package com.android.ex.photo;

import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Process;
import androidx.annotation.IdRes;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.loader.app.LoaderManager;
import androidx.loader.content.Loader;
import androidx.viewpager.widget.ViewPager.OnPageChangeListener;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewPropertyAnimator;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityManager;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.AnimationSet;
import android.view.animation.ScaleAnimation;
import android.view.animation.TranslateAnimation;
import android.widget.ImageView;

import com.android.ex.photo.ActionBarInterface.OnMenuVisibilityListener;
import com.android.ex.photo.PhotoViewPager.InterceptType;
import com.android.ex.photo.PhotoViewPager.OnInterceptTouchListener;
import com.android.ex.photo.adapters.PhotoPagerAdapter;
import com.android.ex.photo.fragments.PhotoViewFragment;
import com.android.ex.photo.loaders.PhotoBitmapLoader;
import com.android.ex.photo.loaders.PhotoBitmapLoaderInterface.BitmapResult;
import com.android.ex.photo.loaders.PhotoPagerLoader;
import com.android.ex.photo.provider.PhotoContract;
import com.android.ex.photo.util.ImageUtils;
import com.android.ex.photo.util.Util;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * This class implements all the logic of the photo view activity. An activity should use this class
 * calling through from relevant activity methods to the methods of the same name here.
 *
 * To customize the photo viewer activity, you should subclass this and implement your
 * customizations here. Then subclass {@link PhotoViewActivity} and override just
 * {@link PhotoViewActivity#createController createController} to instantiate your controller
 * subclass.
 */
public class PhotoViewController implements
        LoaderManager.LoaderCallbacks<Cursor>, OnPageChangeListener, OnInterceptTouchListener,
        OnMenuVisibilityListener, PhotoViewCallbacks  {

    /**
     * Defines the interface between the Activity and this class.
     *
     * The activity itself must delegate all appropriate method calls into this class, to the
     * methods of the same name.
     */
    public interface ActivityInterface {
        public Context getContext();
        public Context getApplicationContext();
        public Intent getIntent();
        public void setContentView(int resId);
        public <T extends View> T findViewById(int id);
        public Resources getResources();
        public FragmentManager getSupportFragmentManager();
        public LoaderManager getSupportLoaderManager();
        public ActionBarInterface getActionBarInterface();
        public boolean onOptionsItemSelected(MenuItem item);
        public void finish();
        public void overridePendingTransition(int enterAnim, int exitAnim);
        public PhotoViewController getController();
    }

    private final static String TAG = "PhotoViewController";

    private final static String STATE_INITIAL_URI_KEY =
            "com.android.ex.PhotoViewFragment.INITIAL_URI";
    private final static String STATE_CURRENT_URI_KEY =
            "com.android.ex.PhotoViewFragment.CURRENT_URI";
    private final static String STATE_CURRENT_INDEX_KEY =
            "com.android.ex.PhotoViewFragment.CURRENT_INDEX";
    private final static String STATE_FULLSCREEN_KEY =
            "com.android.ex.PhotoViewFragment.FULLSCREEN";
    private final static String STATE_ACTIONBARTITLE_KEY =
            "com.android.ex.PhotoViewFragment.ACTIONBARTITLE";
    private final static String STATE_ACTIONBARSUBTITLE_KEY =
            "com.android.ex.PhotoViewFragment.ACTIONBARSUBTITLE";
    private final static String STATE_ENTERANIMATIONFINISHED_KEY =
            "com.android.ex.PhotoViewFragment.SCALEANIMATIONFINISHED";

    protected final static String ARG_IMAGE_URI = "image_uri";

    public static final int LOADER_PHOTO_LIST = 100;

    /** Count used when the real photo count is unknown [but, may be determined] */
    public static final int ALBUM_COUNT_UNKNOWN = -1;

    public static final int ENTER_ANIMATION_DURATION_MS = 250;
    public static final int EXIT_ANIMATION_DURATION_MS = 250;

    /** Argument key for the dialog message */
    public static final String KEY_MESSAGE = "dialog_message";

    public static int sMemoryClass;
    public static int sMaxPhotoSize; // The maximum size (either width or height)

    private final ActivityInterface mActivity;

    private int mLastFlags;

    private final View.OnSystemUiVisibilityChangeListener mSystemUiVisibilityChangeListener;

    /** The URI of the photos we're viewing; may be {@code null} */
    private String mPhotosUri;
    /** The uri of the initial photo */
    private String mInitialPhotoUri;
    /** The index of the currently viewed photo */
    private int mCurrentPhotoIndex;
    /** The uri of the currently viewed photo */
    private String mCurrentPhotoUri;
    /** The query projection to use; may be {@code null} */
    private String[] mProjection;
    /** The total number of photos; only valid if {@link #mIsEmpty} is {@code false}. */
    protected int mAlbumCount = ALBUM_COUNT_UNKNOWN;
    /** {@code true} if the view is empty. Otherwise, {@code false}. */
    protected boolean mIsEmpty;
    /** the main root view */
    protected View mRootView;
    /** Background image that contains nothing, so it can be alpha faded from
     * transparent to black without affecting any other views. */
    @Nullable
    protected View mBackground;
    /** The main pager; provides left/right swipe between photos */
    protected PhotoViewPager mViewPager;
    /** The temporary image so that we can quickly scale up the fullscreen thumbnail */
    @Nullable
    protected ImageView mTemporaryImage;
    /** Adapter to create pager views */
    protected PhotoPagerAdapter mAdapter;
    /** Whether or not we're in "full screen" mode */
    protected boolean mFullScreen;
    /** The listeners wanting full screen state for each screen position */
    private final Map<Integer, OnScreenListener>
            mScreenListeners = new HashMap<Integer, OnScreenListener>();
    /** The set of listeners wanting full screen state */
    private final Set<CursorChangedListener> mCursorListeners = new HashSet<CursorChangedListener>();
    /** When {@code true}, restart the loader when the activity becomes active */
    private boolean mKickLoader;
    /** Don't attempt operations that may trigger a fragment transaction when the activity is
     * destroyed */
    private boolean mIsDestroyedCompat;
    /** Whether or not this activity is paused */
    protected boolean mIsPaused = true;
    /** The maximum scale factor applied to images when they are initially displayed */
    protected float mMaxInitialScale;
    /** The title in the actionbar */
    protected String mActionBarTitle;
    /** The subtitle in the actionbar */
    protected String mActionBarSubtitle;

    private boolean mEnterAnimationFinished;
    protected boolean mScaleAnimationEnabled;
    protected int mAnimationStartX;
    protected int mAnimationStartY;
    protected int mAnimationStartWidth;
    protected int mAnimationStartHeight;

    /** Whether lights out should invoked based on timer */
    protected boolean mIsTimerLightsOutEnabled;
    protected boolean mActionBarHiddenInitially;
    protected boolean mDisplayThumbsFullScreen;

    private final AccessibilityManager mAccessibilityManager;

    protected BitmapCallback mBitmapCallback;
    protected final Handler mHandler = new Handler();

    // TODO Find a better way to do this. We basically want the activity to display the
    // "loading..." progress until the fragment takes over and shows it's own "loading..."
    // progress [located in photo_header_view.xml]. We could potentially have all status displayed
    // by the activity, but, that gets tricky when it comes to screen rotation. For now, we
    // track the loading by this variable which is fragile and may cause phantom "loading..."
    // text.
    private long mEnterFullScreenDelayTime;

    private int lastAnnouncedTitle = -1;

    public PhotoViewController(ActivityInterface activity) {
        mActivity = activity;

        // View.OnSystemUiVisibilityChangeListener is an API that was introduced in API level 11.
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
            mSystemUiVisibilityChangeListener = null;
        } else {
            mSystemUiVisibilityChangeListener = new View.OnSystemUiVisibilityChangeListener() {
                @Override
                public void onSystemUiVisibilityChange(int visibility) {
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT &&
                            visibility == 0 && mLastFlags == 3846) {
                        setFullScreen(false /* fullscreen */, true /* setDelayedRunnable */);
                    }
                }
            };
        }

        mAccessibilityManager = (AccessibilityManager)
                activity.getContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
    }

    public PhotoPagerAdapter createPhotoPagerAdapter(Context context,
            androidx.fragment.app.FragmentManager fm, Cursor c, float maxScale) {
        return new PhotoPagerAdapter(context, fm, c, maxScale, mDisplayThumbsFullScreen);
    }

    public PhotoViewController.ActivityInterface getActivity() {
        return mActivity;
    }

    public void onCreate(Bundle savedInstanceState) {
        initMaxPhotoSize();
        final ActivityManager mgr = (ActivityManager) mActivity.getApplicationContext().
                getSystemService(Activity.ACTIVITY_SERVICE);
        sMemoryClass = mgr.getMemoryClass();

        final Intent intent = mActivity.getIntent();
        // uri of the photos to view; optional
        if (intent.hasExtra(Intents.EXTRA_PHOTOS_URI)) {
            mPhotosUri = intent.getStringExtra(Intents.EXTRA_PHOTOS_URI);
        }

        mIsTimerLightsOutEnabled = intent.getBooleanExtra(
                Intents.EXTRA_ENABLE_TIMER_LIGHTS_OUT, true);

        if (intent.getBooleanExtra(Intents.EXTRA_SCALE_UP_ANIMATION, false)) {
            mScaleAnimationEnabled = true;
            mAnimationStartX = intent.getIntExtra(Intents.EXTRA_ANIMATION_START_X, 0);
            mAnimationStartY = intent.getIntExtra(Intents.EXTRA_ANIMATION_START_Y, 0);
            mAnimationStartWidth = intent.getIntExtra(Intents.EXTRA_ANIMATION_START_WIDTH, 0);
            mAnimationStartHeight = intent.getIntExtra(Intents.EXTRA_ANIMATION_START_HEIGHT, 0);
        }
        mActionBarHiddenInitially = intent.getBooleanExtra(
                Intents.EXTRA_ACTION_BAR_HIDDEN_INITIALLY, false)
                && !Util.isTouchExplorationEnabled(mAccessibilityManager);
        mDisplayThumbsFullScreen = intent.getBooleanExtra(
                Intents.EXTRA_DISPLAY_THUMBS_FULLSCREEN, false);

        // projection for the query; optional
        // If not set, the default projection is used.
        // This projection must include the columns from the default projection.
        if (intent.hasExtra(Intents.EXTRA_PROJECTION)) {
            mProjection = intent.getStringArrayExtra(Intents.EXTRA_PROJECTION);
        } else {
            mProjection = null;
        }

        // Set the max initial scale, defaulting to 1x
        mMaxInitialScale = intent.getFloatExtra(Intents.EXTRA_MAX_INITIAL_SCALE, 1.0f);
        mCurrentPhotoUri = null;
        mCurrentPhotoIndex = -1;

        // We allow specifying the current photo by either index or uri.
        // This is because some users may have live datasets that can change,
        // adding new items to either the beginning or end of the set. For clients
        // that do not need that capability, ability to specify the current photo
        // by index is offered as a convenience.
        if (intent.hasExtra(Intents.EXTRA_PHOTO_INDEX)) {
            mCurrentPhotoIndex = intent.getIntExtra(Intents.EXTRA_PHOTO_INDEX, -1);
        }
        if (intent.hasExtra(Intents.EXTRA_INITIAL_PHOTO_URI)) {
            mInitialPhotoUri = intent.getStringExtra(Intents.EXTRA_INITIAL_PHOTO_URI);
            mCurrentPhotoUri = mInitialPhotoUri;
        }
        mIsEmpty = true;

        if (savedInstanceState != null) {
            mInitialPhotoUri = savedInstanceState.getString(STATE_INITIAL_URI_KEY);
            mCurrentPhotoUri = savedInstanceState.getString(STATE_CURRENT_URI_KEY);
            mCurrentPhotoIndex = savedInstanceState.getInt(STATE_CURRENT_INDEX_KEY);
            mFullScreen = savedInstanceState.getBoolean(STATE_FULLSCREEN_KEY, false)
                    && !Util.isTouchExplorationEnabled(mAccessibilityManager);
            mActionBarTitle = savedInstanceState.getString(STATE_ACTIONBARTITLE_KEY);
            mActionBarSubtitle = savedInstanceState.getString(STATE_ACTIONBARSUBTITLE_KEY);
            mEnterAnimationFinished = savedInstanceState.getBoolean(
                    STATE_ENTERANIMATIONFINISHED_KEY, false);
        } else {
            mFullScreen = mActionBarHiddenInitially;
        }

        mActivity.setContentView(getContentViewId());

        // Create the adapter and add the view pager
        mAdapter = createPhotoPagerAdapter(mActivity.getContext(),
                        mActivity.getSupportFragmentManager(), null, mMaxInitialScale);
        final Resources resources = mActivity.getResources();
        mRootView = findViewById(getRootViewId());
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            mRootView.setOnSystemUiVisibilityChangeListener(getSystemUiVisibilityChangeListener());
        }
        mBackground = getBackground();
        mTemporaryImage = getTemporaryImage();
        mViewPager = (PhotoViewPager) findViewById(R.id.photo_view_pager);
        mViewPager.setAdapter(mAdapter);
        mViewPager.setOnPageChangeListener(this);
        mViewPager.setOnInterceptTouchListener(this);
        mViewPager.setPageMargin(resources.getDimensionPixelSize(R.dimen.photo_page_margin));

        mBitmapCallback = new BitmapCallback();
        if (!mScaleAnimationEnabled || mEnterAnimationFinished) {
            // We are not running the scale up animation. Just let the fragments
            // display and handle the animation.
            mActivity.getSupportLoaderManager().initLoader(LOADER_PHOTO_LIST, null, this);
            // Make the background opaque immediately so that we don't see the activity
            // behind this one.
            if (hasBackground()) {
                mBackground.setVisibility(View.VISIBLE);
            }
        } else {
            // Attempt to load the initial image thumbnail. Once we have the
            // image, animate it up. Once the animation is complete, we can kick off
            // loading the ViewPager. After the primary fullres image is loaded, we will
            // make our temporary image invisible and display the ViewPager.
            mViewPager.setVisibility(View.GONE);
            Bundle args = new Bundle();
            args.putString(ARG_IMAGE_URI, mInitialPhotoUri);
            mActivity.getSupportLoaderManager().initLoader(
                    BITMAP_LOADER_THUMBNAIL, args, mBitmapCallback);
        }

        mEnterFullScreenDelayTime =
                resources.getInteger(R.integer.reenter_fullscreen_delay_time_in_millis);

        final ActionBarInterface actionBar = mActivity.getActionBarInterface();
        if (actionBar != null) {
            actionBar.setDisplayHomeAsUpEnabled(true);
            actionBar.addOnMenuVisibilityListener(this);
            actionBar.setDisplayOptionsShowTitle();
            // Set the title and subtitle immediately here, rather than waiting
            // for the fragment to be initialized.
            setActionBarTitles(actionBar);
        }

        if (!mScaleAnimationEnabled) {
            setLightsOutMode(mFullScreen);
        } else {
            // Keep lights out mode as false. This is to prevent jank cause by concurrent
            // animations during the enter animation.
            setLightsOutMode(false);
        }
    }

    private void initMaxPhotoSize() {
        if (sMaxPhotoSize == 0) {
            final DisplayMetrics metrics = new DisplayMetrics();
            final WindowManager wm = (WindowManager)
                    mActivity.getContext().getSystemService(Context.WINDOW_SERVICE);
            final ImageUtils.ImageSize imageSize = ImageUtils.sUseImageSize;
            wm.getDefaultDisplay().getMetrics(metrics);
            switch (imageSize) {
                case EXTRA_SMALL:
                    // Use a photo that's 80% of the "small" size
                    sMaxPhotoSize = (Math.min(metrics.heightPixels, metrics.widthPixels) * 800) / 1000;
                    break;
                case SMALL:
                    // Fall through.
                case NORMAL:
                    // Fall through.
                default:
                    sMaxPhotoSize = Math.min(metrics.heightPixels, metrics.widthPixels);
                    break;
            }
        }
    }

    public boolean onCreateOptionsMenu(Menu menu) {
        return true;
    }

    public boolean onPrepareOptionsMenu(Menu menu) {
        return true;
    }

    public void onActivityResult(int requestCode, int resultCode, Intent data) {}

    protected View findViewById(int id) {
        return mActivity.findViewById(id);
    }

    /**
     * Returns the android id of the viewer's root view. Subclasses should override this method if
     * they provide their own layout.
     */
    @IdRes
    protected int getRootViewId() {
      return R.id.photo_activity_root_view;
    }

    /**
     * Returns the android layout id of the root layout that should be inflated for the viewer.
     * Subclasses should override this method if they provide their own layout.
     */
    @IdRes
    protected int getContentViewId() {
        return R.layout.photo_activity_view;
    }

    /**
     * Returns the android view for the viewer's background view, if it has one. Subclasses should
     * override this if they have a different (or no) background view.
     */
    @Nullable
    protected View getBackground() {
        return findViewById(R.id.photo_activity_background);
    }

    /**
     * Returns whether or not the view has a background object. Subclasses should override this if
     * they do not contain a background object.
     */
    protected boolean hasBackground() {
        return mBackground != null;
    }

    /**
     * Returns the android view for the viewer's temporary image, if it has one. Subclasses should
     * override this if they have a different (or no) temporary image view.
     */
    @Nullable
    protected ImageView getTemporaryImage() {
        return (ImageView) findViewById(R.id.photo_activity_temporary_image);
    }

    /**
     * Returns whether or not the view has a temporary image view. Subclasses should override this
     * if they do not use a temporary image.
     */
    protected boolean hasTemporaryImage() {
        return mTemporaryImage != null;
    }

    public void onStart() {}

    public void onResume() {
        setFullScreen(mFullScreen, false);

        mIsPaused = false;
        if (mKickLoader) {
            mKickLoader = false;
            mActivity.getSupportLoaderManager().initLoader(LOADER_PHOTO_LIST, null, this);
        }
    }

    public void onPause() {
        mIsPaused = true;
    }

    public void onStop() {}

    public void onDestroy() {
        mIsDestroyedCompat = true;
    }

    private boolean isDestroyedCompat() {
        return mIsDestroyedCompat;
    }

    public boolean onBackPressed() {
        // If we are in fullscreen mode, and the default is not full screen, then
        // switch back to actionBar display mode.
        if (mFullScreen && !mActionBarHiddenInitially) {
            toggleFullScreen();
        } else {
            if (mScaleAnimationEnabled) {
                runExitAnimation();
            } else {
                return false;
            }
        }
        return true;
    }

    public void onSaveInstanceState(Bundle outState) {
        outState.putString(STATE_INITIAL_URI_KEY, mInitialPhotoUri);
        outState.putString(STATE_CURRENT_URI_KEY, mCurrentPhotoUri);
        outState.putInt(STATE_CURRENT_INDEX_KEY, mCurrentPhotoIndex);
        outState.putBoolean(STATE_FULLSCREEN_KEY, mFullScreen);
        outState.putString(STATE_ACTIONBARTITLE_KEY, mActionBarTitle);
        outState.putString(STATE_ACTIONBARSUBTITLE_KEY, mActionBarSubtitle);
        outState.putBoolean(STATE_ENTERANIMATIONFINISHED_KEY, mEnterAnimationFinished);
    }

    public boolean onOptionsItemSelected(MenuItem item) {
       switch (item.getItemId()) {
          case android.R.id.home:
             mActivity.finish();
             return true;
          default:
             return false;
       }
    }

    @Override
    public void addScreenListener(int position, OnScreenListener listener) {
        mScreenListeners.put(position, listener);
    }

    @Override
    public void removeScreenListener(int position) {
        mScreenListeners.remove(position);
    }

    @Override
    public synchronized void addCursorListener(CursorChangedListener listener) {
        mCursorListeners.add(listener);
    }

    @Override
    public synchronized void removeCursorListener(CursorChangedListener listener) {
        mCursorListeners.remove(listener);
    }

    @Override
    public boolean isFragmentFullScreen(Fragment fragment) {
        if (mViewPager == null || mAdapter == null || mAdapter.getCount() == 0) {
            return mFullScreen;
        }
        return mFullScreen || (mViewPager.getCurrentItem() != mAdapter.getItemPosition(fragment));
    }

    @Override
    public void toggleFullScreen() {
        setFullScreen(!mFullScreen, true);
    }

    public void onPhotoRemoved(long photoId) {
        final Cursor data = mAdapter.getCursor();
        if (data == null) {
            // Huh?! How would this happen?
            return;
        }

        final int dataCount = data.getCount();
        if (dataCount <= 1) {
            mActivity.finish();
            return;
        }

        mActivity.getSupportLoaderManager().restartLoader(LOADER_PHOTO_LIST, null, this);
    }

    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
        if (id == LOADER_PHOTO_LIST) {
            return new PhotoPagerLoader(mActivity.getContext(), Uri.parse(mPhotosUri), mProjection);
        }
        return null;
    }

    @Override
    public Loader<BitmapResult> onCreateBitmapLoader(int id, Bundle args, String uri) {
        switch (id) {
            case BITMAP_LOADER_AVATAR:
            case BITMAP_LOADER_THUMBNAIL:
            case BITMAP_LOADER_PHOTO:
                return new PhotoBitmapLoader(mActivity.getContext(), uri);
            default:
                return null;
        }
    }

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
        final int id = loader.getId();
        if (id == LOADER_PHOTO_LIST) {
            if (data == null || data.getCount() == 0) {
                mIsEmpty = true;
                mAdapter.swapCursor(null);
            } else {
                mAlbumCount = data.getCount();
                if (mCurrentPhotoUri != null) {
                    int index = 0;
                    // Clear query params. Compare only the path.
                    final int uriIndex = data.getColumnIndex(PhotoContract.PhotoViewColumns.URI);
                    final Uri currentPhotoUri;
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
                        currentPhotoUri = Uri.parse(mCurrentPhotoUri).buildUpon()
                                .clearQuery().build();
                    } else {
                        currentPhotoUri = Uri.parse(mCurrentPhotoUri).buildUpon()
                                .query(null).build();
                    }
                    // Rewind data cursor to the start if it has already advanced.
                    data.moveToPosition(-1);
                    while (data.moveToNext()) {
                        final String uriString = data.getString(uriIndex);
                        final Uri uri;
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
                            uri = Uri.parse(uriString).buildUpon().clearQuery().build();
                        } else {
                            uri = Uri.parse(uriString).buildUpon().query(null).build();
                        }
                        if (currentPhotoUri != null && currentPhotoUri.equals(uri)) {
                            mCurrentPhotoIndex = index;
                            break;
                        }
                        index++;
                    }
                }

                // We're paused; don't do anything now, we'll get re-invoked
                // when the activity becomes active again
                if (mIsPaused) {
                    mKickLoader = true;
                    mAdapter.swapCursor(null);
                    return;
                }
                boolean wasEmpty = mIsEmpty;
                mIsEmpty = false;

                mAdapter.swapCursor(data);
                if (mViewPager.getAdapter() == null) {
                    mViewPager.setAdapter(mAdapter);
                }
                notifyCursorListeners(data);

                // Use an index of 0 if the index wasn't specified or couldn't be found
                if (mCurrentPhotoIndex < 0) {
                    mCurrentPhotoIndex = 0;
                }

                mViewPager.setCurrentItem(mCurrentPhotoIndex, false);
                if (wasEmpty) {
                    setViewActivated(mCurrentPhotoIndex);
                }
            }
            // Update the any action items
            updateActionItems();
        }
    }

    @Override
    public void onLoaderReset(androidx.loader.content.Loader<Cursor> loader) {
        // If the loader is reset, remove the reference in the adapter to this cursor
        if (!isDestroyedCompat()) {
            // This will cause a fragment transaction which can't happen if we're destroyed,
            // but we don't care in that case because we're destroyed anyways.
            mAdapter.swapCursor(null);
        }
    }

    public void updateActionItems() {
        // Do nothing, but allow extending classes to do work
    }

    private synchronized void notifyCursorListeners(Cursor data) {
        // tell all of the objects listening for cursor changes
        // that the cursor has changed
        for (CursorChangedListener listener : mCursorListeners) {
            listener.onCursorChanged(data);
        }
    }

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        if (positionOffset < 0.0001) {
            OnScreenListener before = mScreenListeners.get(position - 1);
            if (before != null) {
                before.onViewUpNext();
            }
            OnScreenListener after = mScreenListeners.get(position + 1);
            if (after != null) {
                after.onViewUpNext();
            }
        }
    }

    @Override
    public void onPageSelected(int position) {
        mCurrentPhotoIndex = position;
        setViewActivated(position);
    }

    @Override
    public void onPageScrollStateChanged(int state) {
    }

    @Override
    public boolean isFragmentActive(Fragment fragment) {
        if (mViewPager == null || mAdapter == null) {
            return false;
        }
        return mViewPager.getCurrentItem() == mAdapter.getItemPosition(fragment);
    }

    @Override
    public void onFragmentVisible(PhotoViewFragment fragment) {
        // Do nothing, we handle this in setViewActivated
    }

    @Override
    public InterceptType onTouchIntercept(float origX, float origY) {
        boolean interceptLeft = false;
        boolean interceptRight = false;

        for (OnScreenListener listener : mScreenListeners.values()) {
            if (!interceptLeft) {
                interceptLeft = listener.onInterceptMoveLeft(origX, origY);
            }
            if (!interceptRight) {
                interceptRight = listener.onInterceptMoveRight(origX, origY);
            }
        }

        if (interceptLeft) {
            if (interceptRight) {
                return InterceptType.BOTH;
            }
            return InterceptType.LEFT;
        } else if (interceptRight) {
            return InterceptType.RIGHT;
        }
        return InterceptType.NONE;
    }

    /**
     * Updates the title bar according to the value of {@link #mFullScreen}.
     */
    protected void setFullScreen(boolean fullScreen, boolean setDelayedRunnable) {
        if (Util.isTouchExplorationEnabled(mAccessibilityManager)) {
            // Disallow full screen mode when accessibility is enabled so that the action bar
            // stays accessible.
            fullScreen = false;
            setDelayedRunnable = false;
        }

        final boolean fullScreenChanged = (fullScreen != mFullScreen);
        mFullScreen = fullScreen;

        if (mFullScreen) {
            setLightsOutMode(true);
            cancelEnterFullScreenRunnable();
        } else {
            setLightsOutMode(false);
            if (setDelayedRunnable) {
                postEnterFullScreenRunnableWithDelay();
            }
        }

        if (fullScreenChanged) {
            for (OnScreenListener listener : mScreenListeners.values()) {
                listener.onFullScreenChanged(mFullScreen);
            }
        }
    }

    /**
     * Posts a runnable to enter full screen after mEnterFullScreenDelayTime. This method is a
     * no-op if mIsTimerLightsOutEnabled is set to false.
     */
    private void postEnterFullScreenRunnableWithDelay() {
        if (mIsTimerLightsOutEnabled) {
            mHandler.postDelayed(mEnterFullScreenRunnable, mEnterFullScreenDelayTime);
        }
    }

    private void cancelEnterFullScreenRunnable() {
        mHandler.removeCallbacks(mEnterFullScreenRunnable);
    }

    protected void setLightsOutMode(boolean enabled) {
        setImmersiveMode(enabled);
    }

    private final Runnable mEnterFullScreenRunnable = new Runnable() {
        @Override
        public void run() {
            setFullScreen(true, true);
        }
    };

    @Override
    public void setViewActivated(int position) {
        OnScreenListener listener = mScreenListeners.get(position);
        if (listener != null) {
            listener.onViewActivated();
        }
        final Cursor cursor = getCursorAtProperPosition();
        mCurrentPhotoIndex = position;
        // FLAG: get the column indexes once in onLoadFinished().
        // That would make this more efficient, instead of looking these up
        // repeatedly whenever we want them.
        int uriIndex = cursor.getColumnIndex(PhotoContract.PhotoViewColumns.URI);
        mCurrentPhotoUri = cursor.getString(uriIndex);
        updateActionBar();
        if (mAccessibilityManager.isEnabled() && lastAnnouncedTitle != position) {
            String announcement = getPhotoAccessibilityAnnouncement(position);
            if (announcement != null) {
                Util.announceForAccessibility(mRootView, mAccessibilityManager, announcement);
                lastAnnouncedTitle = position;
            }
        }

        // Restart the timer to return to fullscreen.
        cancelEnterFullScreenRunnable();
        postEnterFullScreenRunnableWithDelay();
    }

    /**
     * Adjusts the activity title and subtitle to reflect the photo name and count.
     */
    public void updateActionBar() {
        final int position = mViewPager.getCurrentItem() + 1;
        final boolean hasAlbumCount = mAlbumCount >= 0;

        final Cursor cursor = getCursorAtProperPosition();
        if (cursor != null) {
            // FLAG: We should grab the indexes when we first get the cursor
            // and store them so we don't need to do it each time.
            final int photoNameIndex = cursor.getColumnIndex(PhotoContract.PhotoViewColumns.NAME);
            mActionBarTitle = cursor.getString(photoNameIndex);
        } else {
            mActionBarTitle = null;
        }

        if (mIsEmpty || !hasAlbumCount || position <= 0) {
            mActionBarSubtitle = null;
        } else {
            mActionBarSubtitle = mActivity.getResources().getString(
                    R.string.photo_view_count, position, mAlbumCount);
        }

        setActionBarTitles(mActivity.getActionBarInterface());
    }

    /**
     * Returns a string used as an announcement for accessibility after the user moves to a new
     * photo. It will be called after {@link #updateActionBar} has been called.
     * @param position the index in the album of the currently active photo
     * @return announcement for accessibility
     */
    protected String getPhotoAccessibilityAnnouncement(int position) {
        String announcement = mActionBarTitle;
        if (mActionBarSubtitle != null) {
            announcement = mActivity.getContext().getResources().getString(
                    R.string.titles, mActionBarTitle, mActionBarSubtitle);
        }
        return announcement;
    }

    /**
     * Sets the Action Bar title to {@link #mActionBarTitle} and the subtitle to
     * {@link #mActionBarSubtitle}
     */
    protected final void setActionBarTitles(ActionBarInterface actionBar) {
        if (actionBar == null) {
            return;
        }
        actionBar.setTitle(getInputOrEmpty(mActionBarTitle));
        actionBar.setSubtitle(getInputOrEmpty(mActionBarSubtitle));
    }

    /**
     * If the input string is non-null, it is returned, otherwise an empty string is returned;
     * @param in
     * @return
     */
    private static final String getInputOrEmpty(String in) {
        if (in == null) {
            return "";
        }
        return in;
    }

    /**
     * Utility method that will return the cursor that contains the data
     * at the current position so that it refers to the current image on screen.
     * @return the cursor at the current position or
     * null if no cursor exists or if the {@link PhotoViewPager} is null.
     */
    public Cursor getCursorAtProperPosition() {
        if (mViewPager == null) {
            return null;
        }

        final int position = mViewPager.getCurrentItem();
        final Cursor cursor = mAdapter.getCursor();

        if (cursor == null) {
            return null;
        }

        cursor.moveToPosition(position);

        return cursor;
    }

    public Cursor getCursor() {
        return (mAdapter == null) ? null : mAdapter.getCursor();
    }

    @Override
    public void onMenuVisibilityChanged(boolean isVisible) {
        if (isVisible) {
            cancelEnterFullScreenRunnable();
        } else {
            postEnterFullScreenRunnableWithDelay();
        }
    }

    @Override
    public void onNewPhotoLoaded(int position) {
        // do nothing
    }

    protected void setPhotoIndex(int index) {
        mCurrentPhotoIndex = index;
    }

    @Override
    public void onFragmentPhotoLoadComplete(PhotoViewFragment fragment, boolean success) {
        if (hasTemporaryImage() && mTemporaryImage.getVisibility() != View.GONE &&
                TextUtils.equals(fragment.getPhotoUri(), mCurrentPhotoUri)) {
            if (success) {
                // The fragment for the current image is now ready for display.
                if (hasTemporaryImage()) {
                    mTemporaryImage.setVisibility(View.GONE);
                }
                mViewPager.setVisibility(View.VISIBLE);
            } else {
                // This means that we are unable to load the fragment's photo.
                // I'm not sure what the best thing to do here is, but at least if
                // we display the viewPager, the fragment itself can decide how to
                // display the failure of its own image.
                Log.w(TAG, "Failed to load fragment image");
                if (hasTemporaryImage()) {
                    mTemporaryImage.setVisibility(View.GONE);
                }
                mViewPager.setVisibility(View.VISIBLE);
            }
            mActivity.getSupportLoaderManager().destroyLoader(
                    PhotoViewCallbacks.BITMAP_LOADER_THUMBNAIL);
        }
    }

    protected boolean isFullScreen() {
        return mFullScreen;
    }

    @Override
    public void onCursorChanged(PhotoViewFragment fragment, Cursor cursor) {
        // do nothing
    }

    @Override
    public PhotoPagerAdapter getAdapter() {
        return mAdapter;
    }

    public void onEnterAnimationComplete() {
        mEnterAnimationFinished = true;
        mViewPager.setVisibility(View.VISIBLE);
        setLightsOutMode(mFullScreen);
    }

    private void onExitAnimationComplete() {
        mActivity.finish();
        mActivity.overridePendingTransition(0, 0);
    }

    private void runEnterAnimation() {
        final int totalWidth = mRootView.getMeasuredWidth();
        final int totalHeight = mRootView.getMeasuredHeight();

        // FLAG: Need to handle the aspect ratio of the bitmap.  If it's a portrait
        // bitmap, then we need to position the view higher so that the middle
        // pixels line up.
        if (hasTemporaryImage()) {
            mTemporaryImage.setVisibility(View.VISIBLE);
        }
        // We need to take a full screen image, and scale/translate it so that
        // it appears at exactly the same location onscreen as it is in the
        // prior activity.
        // The final image will take either the full screen width or height (or both).

        final float scaleW = (float) mAnimationStartWidth / totalWidth;
        final float scaleY = (float) mAnimationStartHeight / totalHeight;
        final float scale = Math.max(scaleW, scaleY);

        final int translateX = calculateTranslate(mAnimationStartX, mAnimationStartWidth,
                totalWidth, scale);
        final int translateY = calculateTranslate(mAnimationStartY, mAnimationStartHeight,
                totalHeight, scale);

        final int version = android.os.Build.VERSION.SDK_INT;
        if (version >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
            if (hasBackground()) {
                mBackground.setAlpha(0f);
                mBackground.animate().alpha(1f).setDuration(ENTER_ANIMATION_DURATION_MS).start();
                mBackground.setVisibility(View.VISIBLE);
            }

            if (hasTemporaryImage()) {
                mTemporaryImage.setScaleX(scale);
                mTemporaryImage.setScaleY(scale);
                mTemporaryImage.setTranslationX(translateX);
                mTemporaryImage.setTranslationY(translateY);

                Runnable endRunnable = new Runnable() {
                    @Override
                    public void run() {
                        PhotoViewController.this.onEnterAnimationComplete();
                    }
                };
                ViewPropertyAnimator animator = mTemporaryImage.animate().scaleX(1f).scaleY(1f)
                    .translationX(0).translationY(0).setDuration(ENTER_ANIMATION_DURATION_MS);
                if (version >= Build.VERSION_CODES.JELLY_BEAN) {
                    animator.withEndAction(endRunnable);
                } else {
                    mHandler.postDelayed(endRunnable, ENTER_ANIMATION_DURATION_MS);
                }
                animator.start();
            }
        } else {
            if (hasBackground()) {
                final Animation alphaAnimation = new AlphaAnimation(0f, 1f);
                alphaAnimation.setDuration(ENTER_ANIMATION_DURATION_MS);
                mBackground.startAnimation(alphaAnimation);
                mBackground.setVisibility(View.VISIBLE);
            }

            if (hasTemporaryImage()) {
                final Animation translateAnimation = new TranslateAnimation(translateX,
                        translateY, 0, 0);
                translateAnimation.setDuration(ENTER_ANIMATION_DURATION_MS);
                Animation scaleAnimation = new ScaleAnimation(scale, scale, 0, 0);
                scaleAnimation.setDuration(ENTER_ANIMATION_DURATION_MS);

                AnimationSet animationSet = new AnimationSet(true);
                animationSet.addAnimation(translateAnimation);
                animationSet.addAnimation(scaleAnimation);
                AnimationListener listener = new AnimationListener() {
                    @Override
                    public void onAnimationEnd(Animation arg0) {
                        PhotoViewController.this.onEnterAnimationComplete();
                    }

                    @Override
                    public void onAnimationRepeat(Animation arg0) {
                    }

                    @Override
                    public void onAnimationStart(Animation arg0) {
                    }
                };
                animationSet.setAnimationListener(listener);
                mTemporaryImage.startAnimation(animationSet);
            }
        }
    }

    private void runExitAnimation() {
        Intent intent = mActivity.getIntent();
        // FLAG: should just fall back to a standard animation if either:
        // 1. images have been added or removed since we've been here, or
        // 2. we are currently looking at some image other than the one we
        // started on.

        final int totalWidth = mRootView.getMeasuredWidth();
        final int totalHeight = mRootView.getMeasuredHeight();

        // We need to take a full screen image, and scale/translate it so that
        // it appears at exactly the same location onscreen as it is in the
        // prior activity.
        // The final image will take either the full screen width or height (or both).
        final float scaleW = (float) mAnimationStartWidth / totalWidth;
        final float scaleY = (float) mAnimationStartHeight / totalHeight;
        final float scale = Math.max(scaleW, scaleY);

        final int translateX = calculateTranslate(mAnimationStartX, mAnimationStartWidth,
                totalWidth, scale);
        final int translateY = calculateTranslate(mAnimationStartY, mAnimationStartHeight,
                totalHeight, scale);
        final int version = android.os.Build.VERSION.SDK_INT;
        if (version >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
            if (hasBackground()) {
                mBackground.animate().alpha(0f).setDuration(EXIT_ANIMATION_DURATION_MS).start();
                mBackground.setVisibility(View.VISIBLE);
            }

            Runnable endRunnable = new Runnable() {
                @Override
                public void run() {
                    PhotoViewController.this.onExitAnimationComplete();
                }
            };
            // If the temporary image is still visible it means that we have
            // not yet loaded the fullres image, so we need to animate
            // the temporary image out.
            ViewPropertyAnimator animator = null;
            if (hasTemporaryImage() && mTemporaryImage.getVisibility() == View.VISIBLE) {
                animator = mTemporaryImage.animate().scaleX(scale).scaleY(scale)
                    .translationX(translateX).translationY(translateY)
                    .setDuration(EXIT_ANIMATION_DURATION_MS);
            } else {
                animator = mViewPager.animate().scaleX(scale).scaleY(scale)
                    .translationX(translateX).translationY(translateY)
                    .setDuration(EXIT_ANIMATION_DURATION_MS);
            }
            // If the user has swiped to a different photo, fade out the current photo
            // along with the scale animation.
            if (!mInitialPhotoUri.equals(mCurrentPhotoUri)) {
                animator.alpha(0f);
            }
            if (version >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
                animator.withEndAction(endRunnable);
            } else {
                mHandler.postDelayed(endRunnable, EXIT_ANIMATION_DURATION_MS);
            }
            animator.start();
        } else {
            if (hasBackground()) {
                final Animation alphaAnimation = new AlphaAnimation(1f, 0f);
                alphaAnimation.setDuration(EXIT_ANIMATION_DURATION_MS);
                mBackground.startAnimation(alphaAnimation);
                mBackground.setVisibility(View.VISIBLE);
            }

            final Animation scaleAnimation = new ScaleAnimation(1f, 1f, scale, scale);
            scaleAnimation.setDuration(EXIT_ANIMATION_DURATION_MS);
            AnimationListener listener = new AnimationListener() {
                @Override
                public void onAnimationEnd(Animation arg0) {
                    PhotoViewController.this.onExitAnimationComplete();
                }

                @Override
                public void onAnimationRepeat(Animation arg0) {
                }

                @Override
                public void onAnimationStart(Animation arg0) {
                }
            };
            scaleAnimation.setAnimationListener(listener);
            // If the temporary image is still visible it means that we have
            // not yet loaded the fullres image, so we need to animate
            // the temporary image out.
            if (hasTemporaryImage() && mTemporaryImage.getVisibility() == View.VISIBLE) {
                mTemporaryImage.startAnimation(scaleAnimation);
            } else {
                mViewPager.startAnimation(scaleAnimation);
            }
        }
    }

    private int calculateTranslate(int start, int startSize, int totalSize, float scale) {
        // Translation takes precedence over scale.  What this means is that if
        // we want an view's upper left corner to be a particular spot on screen,
        // but that view is scaled to something other than 1, we need to take into
        // account the pixels lost to scaling.
        // So if we have a view that is 200x300, and we want it's upper left corner
        // to be at 50x50, but it's scaled by 50%, we can't just translate it to 50x50.
        // If we were to do that, the view's *visible* upper left corner would be at
        // 100x200.  We need to take into account the difference between the outside
        // size of the view (i.e. the size prior to scaling) and the scaled size.
        // scaleFromEdge is the difference between the visible left edge and the
        // actual left edge, due to scaling.
        // scaleFromTop is the difference between the visible top edge, and the
        // actual top edge, due to scaling.
        int scaleFromEdge = Math.round((totalSize - totalSize * scale) / 2);

        // The imageView is fullscreen, regardless of the aspect ratio of the actual image.
        // This means that some portion of the imageView will be blank.  We need to
        // take into account the size of the blank area so that the actual image
        // lines up with the starting image.
        int blankSize = Math.round((totalSize * scale - startSize) / 2);

        return start - scaleFromEdge - blankSize;
    }

    private void initTemporaryImage(Drawable drawable) {
        if (mEnterAnimationFinished) {
            // Forget this, we've already run the animation.
            return;
        }
        if (hasTemporaryImage()) {
            mTemporaryImage.setImageDrawable(drawable);
        }
        if (drawable != null) {
            // We have not yet run the enter animation. Start it now.
            int totalWidth = mRootView.getMeasuredWidth();
            if (totalWidth == 0) {
                // the measure pass has not yet finished.  We can't properly
                // run out animation until that is done. Listen for the layout
                // to occur, then fire the animation.
                final View base = mRootView;
                base.getViewTreeObserver().addOnGlobalLayoutListener(
                        new OnGlobalLayoutListener() {
                    @Override
                    public void onGlobalLayout() {
                        int version = android.os.Build.VERSION.SDK_INT;
                        if (version >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
                            base.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                        } else {
                            base.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                        }
                        runEnterAnimation();
                    }
                });
            } else {
                // initiate the animation
                runEnterAnimation();
            }
        }
        // Kick off the photo list loader
        mActivity.getSupportLoaderManager().initLoader(LOADER_PHOTO_LIST, null, this);
    }

    public void showActionBar() {
        mActivity.getActionBarInterface().show();
    }

    public void hideActionBar() {
        mActivity.getActionBarInterface().hide();
    }

    public boolean isScaleAnimationEnabled() {
        return mScaleAnimationEnabled;
    }

    public boolean isEnterAnimationFinished() {
        return mEnterAnimationFinished;
    }

    public View getRootView() {
        return mRootView;
    }

    private class BitmapCallback implements LoaderManager.LoaderCallbacks<BitmapResult> {

        @Override
        public Loader<BitmapResult> onCreateLoader(int id, Bundle args) {
            String uri = args.getString(ARG_IMAGE_URI);
            switch (id) {
                case PhotoViewCallbacks.BITMAP_LOADER_THUMBNAIL:
                    return onCreateBitmapLoader(PhotoViewCallbacks.BITMAP_LOADER_THUMBNAIL,
                            args, uri);
                case PhotoViewCallbacks.BITMAP_LOADER_AVATAR:
                    return onCreateBitmapLoader(PhotoViewCallbacks.BITMAP_LOADER_AVATAR,
                            args, uri);
            }
            return null;
        }

        @Override
        public void onLoadFinished(Loader<BitmapResult> loader, BitmapResult result) {
            Drawable drawable = result.getDrawable(mActivity.getResources());
            final ActionBarInterface actionBar = mActivity.getActionBarInterface();
            switch (loader.getId()) {
                case PhotoViewCallbacks.BITMAP_LOADER_THUMBNAIL:
                    // We just loaded the initial thumbnail that we can display
                    // while waiting for the full viewPager to get initialized.
                    initTemporaryImage(drawable);
                    break;
                case PhotoViewCallbacks.BITMAP_LOADER_AVATAR:
                    if (drawable == null) {
                        actionBar.setLogo(null);
                    } else {
                        actionBar.setLogo(drawable);
                    }
                    break;
            }
        }

        @Override
        public void onLoaderReset(Loader<BitmapResult> loader) {
            // Do nothing
        }
    }

    public void setImmersiveMode(boolean enabled) {
        int flags = 0;
        final int version = Build.VERSION.SDK_INT;
        final boolean manuallyUpdateActionBar = version < Build.VERSION_CODES.JELLY_BEAN;
        if (enabled &&
                (!isScaleAnimationEnabled() || isEnterAnimationFinished())) {
            // Turning on immersive mode causes an animation. If the scale animation is enabled and
            // the enter animation isn't yet complete, then an immersive mode animation should not
            // occur, since two concurrent animations are very janky.

            // Disable immersive mode for seconary users to prevent b/12015090 (freezing crash)
            // This is fixed in KK_MR2 but there is no way to differentiate between  KK and KK_MR2.
            if (version > Build.VERSION_CODES.KITKAT ||
                    version == Build.VERSION_CODES.KITKAT && !kitkatIsSecondaryUser()) {
                flags = View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                        | View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                        | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                        | View.SYSTEM_UI_FLAG_FULLSCREEN
                        | View.SYSTEM_UI_FLAG_IMMERSIVE;
            } else if (version >= Build.VERSION_CODES.JELLY_BEAN) {
                // Clients that use the scale animation should set the following system UI flags to
                // prevent janky animations on exit when the status bar is hidden:
                //     View.SYSTEM_UI_FLAG_VISIBLE | View.SYSTEM_UI_FLAG_STABLE
                // As well, client should ensure `android:fitsSystemWindows` is set on the root
                // content view.
                flags = View.SYSTEM_UI_FLAG_LOW_PROFILE
                        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                        | View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                        | View.SYSTEM_UI_FLAG_FULLSCREEN;
            } else if (version >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
                flags = View.SYSTEM_UI_FLAG_LOW_PROFILE;
            } else if (version >= Build.VERSION_CODES.HONEYCOMB) {
                flags = View.STATUS_BAR_HIDDEN;
            }

            if (manuallyUpdateActionBar) {
                hideActionBar();
            }
        } else {
            if (version >= Build.VERSION_CODES.KITKAT) {
                flags = View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                        | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
            } else if (version >= Build.VERSION_CODES.JELLY_BEAN) {
                flags = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                        | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
            } else if (version >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
                flags = View.SYSTEM_UI_FLAG_VISIBLE;
            } else if (version >= Build.VERSION_CODES.HONEYCOMB) {
                flags = View.STATUS_BAR_VISIBLE;
            }

            if (manuallyUpdateActionBar) {
                showActionBar();
            }
        }

        if (version >= Build.VERSION_CODES.HONEYCOMB) {
            mLastFlags = flags;
            getRootView().setSystemUiVisibility(flags);
        }
    }

    /**
     * Return true iff the app is being run as a secondary user on kitkat.
     *
     * This is a hack which we only know to work on kitkat.
     */
    private boolean kitkatIsSecondaryUser() {
        if (Build.VERSION.SDK_INT != Build.VERSION_CODES.KITKAT) {
            throw new IllegalStateException("kitkatIsSecondary user is only callable on KitKat");
        }
        return Process.myUid() > 100000;
    }

    /**
     * Note: This should only be called when API level is 11 or above.
     */
    public View.OnSystemUiVisibilityChangeListener getSystemUiVisibilityChangeListener() {
        return mSystemUiVisibilityChangeListener;
    }
}
