15e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal/* 25e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal * Copyright (C) 2012 Google Inc. 35e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal * Licensed to The Android Open Source Project. 45e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal * 55e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal * Licensed under the Apache License, Version 2.0 (the "License"); 65e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal * you may not use this file except in compliance with the License. 75e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal * You may obtain a copy of the License at 85e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal * 95e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal * http://www.apache.org/licenses/LICENSE-2.0 105e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal * 115e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal * Unless required by applicable law or agreed to in writing, software 125e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal * distributed under the License is distributed on an "AS IS" BASIS, 135e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 145e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal * See the License for the specific language governing permissions and 155e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal * limitations under the License. 165e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal */ 175e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal 181ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwalpackage com.android.mail.ui; 195e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal 205e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwalimport android.app.Activity; 215e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwalimport android.app.FragmentTransaction; 225e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwalimport android.os.Handler; 235e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal 24b334c9035e9b7a38766bb66c29da2208525d1e11Paul Westbrookimport com.android.mail.utils.LogTag; 2530e2c24b056542f3b1b438aeb798305d1226d0c8Andy Huangimport com.android.mail.utils.LogUtils; 265e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal 275e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwalimport java.util.concurrent.atomic.AtomicInteger; 285e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal 295e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal/** 305e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal * A thin wrapper of {@link Handler} to run a callback in UI thread. Any callback posted to this 315e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal * handler is guarantee to run inside {@link Activity} life cycle. However, it can be dropped if the 325e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal * {@link Activity} has been stopped. This handler is safe to use with {@link FragmentTransaction}. 335e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal * 345e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal * @author phamm 355e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal */ 365e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwalpublic class UiHandler { 375e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal private final Handler mHandler = new Handler(); 385e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal private boolean mEnabled = true; 39b334c9035e9b7a38766bb66c29da2208525d1e11Paul Westbrook private final static String LOG_TAG = LogTag.getLogTag(); 405e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal 415e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal /** Number of {@link Runnable} in the queue. */ 425e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal private AtomicInteger mCount = new AtomicInteger(0); 435e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal 445e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal public void post(final Runnable r) { 455e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal if (mEnabled) { 465e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal mCount.incrementAndGet(); 475e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal mHandler.post(new Runnable() { 485e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal @Override 495e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal public void run() { 505e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal mCount.decrementAndGet(); 515e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal r.run(); 525e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal } 535e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal }); 545e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal } else { 555e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal LogUtils.d(LOG_TAG, "UiHandler is disabled in post(). Dropping Runnable."); 565e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal } 575e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal } 585e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal 595e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal public void postDelayed(final Runnable r, long delayMillis) { 605e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal if (mEnabled) { 615e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal mCount.incrementAndGet(); 625e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal mHandler.postDelayed(new Runnable() { 635e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal @Override 645e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal public void run() { 655e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal mCount.decrementAndGet(); 665e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal r.run(); 675e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal } 685e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal }, delayMillis); 695e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal } else { 705e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal LogUtils.d(LOG_TAG, "UiHandler is disabled in postDelayed(). Dropping Runnable."); 715e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal } 725e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal } 735e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal 745e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal public void removeCallbacks(Runnable r) { 755e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal mHandler.removeCallbacks(r); 765e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal } 775e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal 785e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal public void setEnabled(boolean enabled) { 795e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal mEnabled = enabled; 805e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal if (!mEnabled) { 815e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal int count = mCount.getAndSet(0); 825e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal if (count > 0) { 835e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal LogUtils.e(LOG_TAG, "Disable UiHandler. Dropping %d Runnables.", count); 845e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal } 855e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal mHandler.removeCallbacksAndMessages(null); 865e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal } 875e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal } 885e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal 895e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal /** 905e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal * @return whether the {@link UiHandler} is enabled. It's safe to edit UI if the 915e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal * {@link UiHandler} is enabled. 925e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal */ 935e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal public boolean isEnabled() { 945e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal return mEnabled; 955e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal } 965e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal}