Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 486c2ee1 authored by Evan Millar's avatar Evan Millar
Browse files

Get rid of "flashies" in the action bar.

-Filter out short spinner events. All spinner events that last <1sec are
now ignored. We also enforce a minimum delay time of 2 sec.
-Mark the share and delete menu items as visible="false" by default to
get rid of the quick display/removal of them under scenarios where they
are ultimately removed.

bug:5398336
Change-Id: I0620532f3ab59d9fde46123620eb781a87445b54
parent ae70ae47
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -24,10 +24,12 @@
            android:title="@string/share"
            android:enabled="true"
            android:actionProviderClass="android.widget.ShareActionProvider"
            android:visible="false"
            android:showAsAction="ifRoom" />
    <item android:id="@+id/action_delete"
            android:icon="@drawable/ic_menu_trash_holo_light"
            android:title="@string/delete"
            android:visible="false"
            android:showAsAction="ifRoom">
        <menu>
            <item android:id="@+id/action_confirm_delete"
+1 −5
Original line number Diff line number Diff line
@@ -271,11 +271,7 @@ public class GalleryUtils {

    public static void setSpinnerVisibility(final Activity activity,
            final boolean visible) {
        activity.runOnUiThread(new Runnable() {
            public void run() {
                activity.setProgressBarIndeterminateVisibility(visible);
            }
        });
        SpinnerVisibilitySetter.getInstance(activity).setSpinnerVisibility(visible);
    }

    public static int determineTypeBits(Context context, Intent intent) {
+133 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.gallery3d.util;

import android.app.Activity;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;

import java.util.HashMap;
import java.util.Map;

/**
 * This class manages the visibility of the progress spinner in the action bar for an
 * Activity. It filters out short-lived appearances of the progress spinner by only
 * showing the spinner if it hasn't been hidden again before the end of a specified
 * delay period. It also enforces a minimum display time once the spinner is made visible.
 * This meant to cut down on the frequent "flashes" of the progress spinner.
 */
public class SpinnerVisibilitySetter {

    private static final int SHOW_SPINNER_REQUESTED = 0;
    private static final int HIDE_SPINNER_REQUESTED = 1;
    private static final int SHOW_SPINNER_DELAY_REACHED = 2;
    private static final int HIDE_SPINNER_DELAY_REACHED = 3;

    // Amount of time after a show request that the progress spinner is actually made visible.
    // This means that any show/hide requests that happen subsequently within this period
    // of time will be ignored.
    private static final long SPINNER_DISPLAY_DELAY = 1000;

    // The minimum amount of time the progress spinner must be visible before it can be hidden.
    private static final long MIN_SPINNER_DISPLAY_TIME = 2000;

    private boolean mPendingVisibilityRequest = false;
    private boolean mActiveVisibilityRequest = false;
    private long mSpinnerVisibilityStartTime;

    Handler mHandler = new Handler() {

        @Override
        public void handleMessage(Message msg) {
            switch(msg.what) {
                case SHOW_SPINNER_REQUESTED:
                    mPendingVisibilityRequest = true;
                    sendEmptyMessageDelayed(SHOW_SPINNER_DELAY_REACHED, SPINNER_DISPLAY_DELAY);
                    break;
                case HIDE_SPINNER_REQUESTED:
                    mPendingVisibilityRequest = false;
                    if (!mActiveVisibilityRequest) {
                        // We haven't requested to show the spinner so no need to decide
                        // when to hide it.
                        break;
                    }

                    long currTime = SystemClock.uptimeMillis();
                    if (currTime - mSpinnerVisibilityStartTime > MIN_SPINNER_DISPLAY_TIME) {
                        // The spinner has already been visible longer than the requisite min
                        // display time. Send the hide message immediately.
                        sendEmptyMessage(HIDE_SPINNER_DELAY_REACHED);
                    } else {
                        // The spinner is visible but hasn't been visible for long enough yet.
                        // Send a delayed hide message.
                        sendEmptyMessageAtTime(HIDE_SPINNER_DELAY_REACHED,
                                mSpinnerVisibilityStartTime + MIN_SPINNER_DISPLAY_TIME);
                    }
                    break;
                case SHOW_SPINNER_DELAY_REACHED:
                    if (mPendingVisibilityRequest) {
                        mPendingVisibilityRequest = false;
                        mActiveVisibilityRequest = true;

                        // Even though the spinner isn't visible quite yet, lets set this
                        // here to avoid possible cross-thread synchronization issues.
                        mSpinnerVisibilityStartTime = SystemClock.uptimeMillis();
                        mActivity.runOnUiThread(new SetProgressVisibilityRunnable(true));
                    }
                    break;
                case HIDE_SPINNER_DELAY_REACHED:
                    mActiveVisibilityRequest = false;
                    mActivity.runOnUiThread(new SetProgressVisibilityRunnable(false));
                    break;
            }
        }
    };
    static final Map<Activity, SpinnerVisibilitySetter> sInstanceMap =
            new HashMap<Activity, SpinnerVisibilitySetter>();
    private Activity mActivity;

    private SpinnerVisibilitySetter(Activity activity) {
        mActivity = activity;
    }

    public static SpinnerVisibilitySetter getInstance(Activity activity) {
        synchronized(sInstanceMap) {
            if (sInstanceMap.get(activity) == null) {
                sInstanceMap.put(activity, new SpinnerVisibilitySetter(activity));
            }
            return sInstanceMap.get(activity);
        }
    }

    public void setSpinnerVisibility(boolean visible) {
        mHandler.sendEmptyMessage(visible ? SHOW_SPINNER_REQUESTED : HIDE_SPINNER_REQUESTED);
    }

    private class SetProgressVisibilityRunnable implements Runnable {
        boolean mVisible;

        public SetProgressVisibilityRunnable(boolean visible) {
            mVisible = visible;
        }

        @Override
        public void run() {
            mActivity.setProgressBarIndeterminateVisibility(mVisible);
        }
    }
}