Keep screen on when running stopwatch

Bug: 7538100

Added a wakelock to keep the screen on when stopwatch is running, the clock
app in running and it is in the stopwatch view.
Added a callback and a listener to track the current view in the clock app.

Change-Id: Ib2af1dcd510321afc805c54d4155346eeca7fffa
diff --git a/src/com/android/deskclock/DeskClock.java b/src/com/android/deskclock/DeskClock.java
index 159fffe..0cc0d28 100644
--- a/src/com/android/deskclock/DeskClock.java
+++ b/src/com/android/deskclock/DeskClock.java
@@ -20,15 +20,13 @@
 import android.app.ActionBar.Tab;
 import android.app.Activity;
 import android.app.Fragment;
+import android.app.FragmentManager;
 import android.app.FragmentTransaction;
 import android.content.ActivityNotFoundException;
 import android.content.Context;
 import android.content.Intent;
 import android.content.SharedPreferences;
-import android.graphics.drawable.TransitionDrawable;
 import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
 import android.preference.PreferenceManager;
 import android.support.v13.app.FragmentPagerAdapter;
 import android.support.v4.view.ViewPager;
@@ -38,10 +36,6 @@
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.View.OnTouchListener;
-import android.view.animation.Animation;
-import android.view.animation.Animation.AnimationListener;
-import android.view.animation.AnimationUtils;
-import android.view.animation.TranslateAnimation;
 import android.widget.PopupMenu;
 import android.widget.TextView;
 
@@ -54,6 +48,7 @@
 import com.android.deskclock.worldclock.CitiesActivity;
 
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.TimeZone;
 
 /**
@@ -134,6 +129,7 @@
             mStopwatchTab.setContentDescription(R.string.menu_stopwatch);
             mTabsAdapter.addTab(mStopwatchTab, StopwatchFragment.class,STOPWATCH_TAB_INDEX);
             mActionBar.setSelectedNavigationItem(selectedIndex);
+            mTabsAdapter.notifySelectedPage(selectedIndex);
         }
     }
 
@@ -268,10 +264,19 @@
         Log.v(LOG_TAG, "Setting home time zone to " + homeTimeZone);
     }
 
-    public boolean isClockTab() {
-        return mViewPager.getCurrentItem() == CLOCK_TAB_INDEX;
+    public void registerPageChangedListener(DeskClockFragment frag) {
+        if (mTabsAdapter != null) {
+            mTabsAdapter.registerPageChangedListener(frag);
+        }
     }
 
+    public void unregisterPageChangedListener(DeskClockFragment frag) {
+        if (mTabsAdapter != null) {
+            mTabsAdapter.unregisterPageChangedListener(frag);
+        }
+    }
+
+
     /***
      * Adapter for wrapping together the ActionBar's tab with the ViewPager
      */
@@ -300,6 +305,8 @@
         ActionBar mMainActionBar;
         Context mContext;
         ViewPager mPager;
+        // Used for doing callbacks to fragments.
+        HashSet<String> mFragmentTags = new HashSet<String>();
 
         public TabsAdapter(Activity activity, ViewPager pager) {
             super(activity.getFragmentManager());
@@ -340,6 +347,7 @@
         @Override
         public void onPageSelected(int position) {
             mMainActionBar.setSelectedNavigationItem(position);
+            notifyPageChanged(position);
         }
 
         @Override
@@ -363,14 +371,44 @@
             // Do nothing
 
         }
+
+        public void notifySelectedPage(int page) {
+            notifyPageChanged(page);
+        }
+
+        private void notifyPageChanged(int newPage) {
+            for (String tag : mFragmentTags) {
+                final FragmentManager fm = getFragmentManager();
+                DeskClockFragment f = (DeskClockFragment) fm.findFragmentByTag(tag);
+                if (f != null) {
+                    f.onPageChanged(newPage);
+                }
+            }
+        }
+
+        public void registerPageChangedListener(DeskClockFragment frag) {
+            String tag = frag.getTag();
+            if (mFragmentTags.contains(tag)) {
+                Log.wtf(LOG_TAG, "Trying to add an existing fragment " + tag);
+            } else {
+                mFragmentTags.add(frag.getTag());
+            }
+            // Since registering a listener by the fragment is done sometimes after the page
+            // was already changed, make sure the fragment gets the current page
+            frag.onPageChanged(mMainActionBar.getSelectedNavigationIndex());
+        }
+
+        public void unregisterPageChangedListener(DeskClockFragment frag) {
+            mFragmentTags.remove(frag.getTag());
+        }
     }
 
     public static abstract class OnTapListener implements OnTouchListener {
         private float mLastTouchX;
         private float mLastTouchY;
         private long mLastTouchTime;
-        private TextView mMakePressedTextView;
-        private int mPressedColor, mGrayColor;
+        private final TextView mMakePressedTextView;
+        private final int mPressedColor, mGrayColor;
         private final float MAX_MOVEMENT_ALLOWED = 20;
         private final long MAX_TIME_ALLOWED = 500;
 
diff --git a/src/com/android/deskclock/DeskClockFragment.java b/src/com/android/deskclock/DeskClockFragment.java
index 4df2fcc..dcf7f7c 100644
--- a/src/com/android/deskclock/DeskClockFragment.java
+++ b/src/com/android/deskclock/DeskClockFragment.java
@@ -17,19 +17,10 @@
 package com.android.deskclock;
 
 import android.app.Fragment;
-import android.content.Context;
 
 public class DeskClockFragment extends Fragment {
-    protected Context mContext;
-    private boolean mButtonClicked = false;
 
-    protected void buttonClicked(boolean state) {
-        mButtonClicked = state;
-    }
-
-    public boolean isButtonClicked() {
-        boolean res = mButtonClicked;
-        mButtonClicked = false;
-        return res;
+    public void onPageChanged(int page) {
+        // Do nothing here , only in derived classes
     }
 }
diff --git a/src/com/android/deskclock/stopwatch/StopwatchFragment.java b/src/com/android/deskclock/stopwatch/StopwatchFragment.java
index b751cc0..fd71f4c 100644
--- a/src/com/android/deskclock/stopwatch/StopwatchFragment.java
+++ b/src/com/android/deskclock/stopwatch/StopwatchFragment.java
@@ -9,6 +9,8 @@
 import android.content.pm.ResolveInfo;
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
+import android.os.PowerManager;
+import android.os.PowerManager.WakeLock;
 import android.preference.PreferenceManager;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -17,7 +19,6 @@
 import android.widget.AdapterView.OnItemClickListener;
 import android.widget.ArrayAdapter;
 import android.widget.BaseAdapter;
-import android.widget.Button;
 import android.widget.ImageButton;
 import android.widget.ImageView;
 import android.widget.ListPopupWindow;
@@ -28,7 +29,6 @@
 import com.android.deskclock.CircleButtonsLinearLayout;
 import com.android.deskclock.CircleTimerView;
 import com.android.deskclock.DeskClock;
-import com.android.deskclock.DeskClock.OnTapListener;
 import com.android.deskclock.DeskClockFragment;
 import com.android.deskclock.Log;
 import com.android.deskclock.R;
@@ -38,10 +38,10 @@
 import java.util.ArrayList;
 import java.util.List;
 
-/**
- * TODO: Insert description here. (generated by isaackatz)
- */
-public class StopwatchFragment extends DeskClockFragment implements OnSharedPreferenceChangeListener{
+public class StopwatchFragment extends DeskClockFragment
+        implements OnSharedPreferenceChangeListener {
+
+    private static final String TAG = "StopwatchFragment";
     int mState = Stopwatches.STOPWATCH_RESET;
 
     // Stopwatch views that are accessed by the activity
@@ -52,6 +52,7 @@
     private ListView mLapsList;
     private ImageButton mShareButton;
     private ListPopupWindow mSharePopup;
+    private WakeLock mWakeLock;
 
     // Used for calculating the time from the start taking into account the pause times
     long mStartTime = 0;
@@ -185,7 +186,6 @@
         Intent intent = new Intent(context, StopwatchService.class);
         intent.putExtra(Stopwatches.MESSAGE_TIME, time);
         intent.putExtra(Stopwatches.SHOW_NOTIF, false);
-        buttonClicked(true);
         switch (mState) {
             case Stopwatches.STOPWATCH_RUNNING:
                 // do stop
@@ -194,6 +194,7 @@
                 doStop();
                 intent.setAction(Stopwatches.STOP_STOPWATCH);
                 context.startService(intent);
+                releaseWakeLock();
                 break;
             case Stopwatches.STOPWATCH_RESET:
             case Stopwatches.STOPWATCH_STOPPED:
@@ -201,6 +202,7 @@
                 doStart(time);
                 intent.setAction(Stopwatches.START_STOPWATCH);
                 context.startService(intent);
+                acquireWakeLock();
                 break;
             default:
                 Log.wtf("Illegal state " + mState
@@ -224,7 +226,6 @@
                 Intent intent = new Intent(context, StopwatchService.class);
                 intent.putExtra(Stopwatches.MESSAGE_TIME, time);
                 intent.putExtra(Stopwatches.SHOW_NOTIF, false);
-                buttonClicked(true);
                 switch (mState) {
                     case Stopwatches.STOPWATCH_RUNNING:
                         // Save lap time
@@ -238,6 +239,7 @@
                         doReset();
                         intent.setAction(Stopwatches.RESET_STOPWATCH);
                         context.startService(intent);
+                        releaseWakeLock();
                         break;
                     default:
                         Log.wtf("Illegal state " + mState
@@ -300,12 +302,13 @@
         setButtons(mState);
         mTimeText.setTime(mAccumulatedTime, true, true);
         if (mState == Stopwatches.STOPWATCH_RUNNING) {
+            acquireWakeLock();
             startUpdateThread();
         } else if (mState == Stopwatches.STOPWATCH_STOPPED && mAccumulatedTime != 0) {
             mTimeText.blinkTimeStr(true);
         }
         showLaps();
-
+        ((DeskClock)getActivity()).registerPageChangedListener(this);
         super.onResume();
     }
 
@@ -325,10 +328,20 @@
             mSharePopup.dismiss();
             mSharePopup = null;
         }
-
+        ((DeskClock)getActivity()).unregisterPageChangedListener(this);
+        releaseWakeLock();
         super.onPause();
     }
 
+    @Override
+    public void onPageChanged(int page) {
+        if (page == DeskClock.STOPWATCH_TAB_INDEX && mState == Stopwatches.STOPWATCH_RUNNING) {
+            acquireWakeLock();
+        } else {
+            releaseWakeLock();
+        }
+    }
+
     private void doStop() {
         stopUpdateThread();
         mTime.pauseIntervalAnimation();
@@ -743,4 +756,24 @@
             }
         }
     }
+
+    // Used to keeps screen on when stopwatch is running.
+
+    private void acquireWakeLock() {
+        if (mWakeLock == null) {
+            final PowerManager pm =
+                    (PowerManager) getActivity().getSystemService(Context.POWER_SERVICE);
+            mWakeLock = pm.newWakeLock(
+                    PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, TAG);
+            mWakeLock.setReferenceCounted(false);
+        }
+        mWakeLock.acquire();
+    }
+
+    private void releaseWakeLock() {
+        if (mWakeLock != null && mWakeLock.isHeld()) {
+            mWakeLock.release();
+        }
+    }
+
 }