13db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen/*
23db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen * Copyright (C) 2010 The Android Open Source Project
33db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen *
43db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen * Licensed under the Apache License, Version 2.0 (the "License");
53db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen * you may not use this file except in compliance with the License.
63db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen * You may obtain a copy of the License at
73db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen *
83db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen *      http://www.apache.org/licenses/LICENSE-2.0
93db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen *
103db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen * Unless required by applicable law or agreed to in writing, software
113db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen * distributed under the License is distributed on an "AS IS" BASIS,
123db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen * See the License for the specific language governing permissions and
143db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen * limitations under the License.
153db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen */
163db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
173db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohenpackage android.widget;
183db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
193db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohenimport android.content.BroadcastReceiver;
203db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohenimport android.content.Context;
213db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohenimport android.content.Intent;
223db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohenimport android.content.IntentFilter;
233db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohenimport android.content.res.TypedArray;
243db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohenimport android.os.Handler;
253db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohenimport android.os.Message;
263db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohenimport android.util.AttributeSet;
273db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohenimport android.util.Log;
282dd2197805edb4d9547b143deef2226413218f4cAdam Cohenimport android.view.RemotableViewMethod;
298a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganovimport android.view.accessibility.AccessibilityEvent;
308a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganovimport android.view.accessibility.AccessibilityNodeInfo;
313db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohenimport android.widget.RemoteViews.RemoteView;
323db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
333db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen/**
343db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen * Simple {@link ViewAnimator} that will animate between two or more views
353db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen * that have been added to it.  Only one child is shown at a time.  If
363db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen * requested, can automatically flip between each child at a regular interval.
373db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen *
383db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen * @attr ref android.R.styleable#AdapterViewFlipper_flipInterval
393db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen * @attr ref android.R.styleable#AdapterViewFlipper_autoStart
403db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen */
413db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen@RemoteView
423db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohenpublic class AdapterViewFlipper extends AdapterViewAnimator {
433db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    private static final String TAG = "ViewFlipper";
443db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    private static final boolean LOGD = false;
453db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
463db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    private static final int DEFAULT_INTERVAL = 10000;
473db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
483db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    private int mFlipInterval = DEFAULT_INTERVAL;
493db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    private boolean mAutoStart = false;
503db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
513db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    private boolean mRunning = false;
523db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    private boolean mStarted = false;
533db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    private boolean mVisible = false;
543db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    private boolean mUserPresent = true;
55a02fdf1ba03fad71cc80a89dfc74b17456d5b4a5Adam Cohen    private boolean mAdvancedByHost = false;
563db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
573db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    public AdapterViewFlipper(Context context) {
583db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        super(context);
593db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
603db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
613db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    public AdapterViewFlipper(Context context, AttributeSet attrs) {
62617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette        this(context, attrs, 0);
63617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette    }
64617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette
65617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette    public AdapterViewFlipper(Context context, AttributeSet attrs, int defStyleAttr) {
66617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette        this(context, attrs, defStyleAttr, 0);
67617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette    }
68617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette
69617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette    public AdapterViewFlipper(
70617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
71617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette        super(context, attrs, defStyleAttr, defStyleRes);
723db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
73617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette        final TypedArray a = context.obtainStyledAttributes(attrs,
74617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette                com.android.internal.R.styleable.AdapterViewFlipper, defStyleAttr, defStyleRes);
753db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        mFlipInterval = a.getInt(
764725660292bcf11c84e9c7da127fd0215fb58e81Adam Cohen                com.android.internal.R.styleable.AdapterViewFlipper_flipInterval, DEFAULT_INTERVAL);
773db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        mAutoStart = a.getBoolean(
784725660292bcf11c84e9c7da127fd0215fb58e81Adam Cohen                com.android.internal.R.styleable.AdapterViewFlipper_autoStart, false);
791b065cd1401253f999caa5d0ac12909407cef00eAdam Cohen
804725660292bcf11c84e9c7da127fd0215fb58e81Adam Cohen        // A view flipper should cycle through the views
814725660292bcf11c84e9c7da127fd0215fb58e81Adam Cohen        mLoopViews = true;
821b065cd1401253f999caa5d0ac12909407cef00eAdam Cohen
833db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        a.recycle();
843db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
853db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
863db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
873db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        @Override
883db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        public void onReceive(Context context, Intent intent) {
893db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            final String action = intent.getAction();
903db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            if (Intent.ACTION_SCREEN_OFF.equals(action)) {
913db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                mUserPresent = false;
923db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                updateRunning();
933db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            } else if (Intent.ACTION_USER_PRESENT.equals(action)) {
943db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                mUserPresent = true;
953db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                updateRunning(false);
963db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            }
973db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        }
983db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    };
993db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
1003db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    @Override
1013db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    protected void onAttachedToWindow() {
1023db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        super.onAttachedToWindow();
1033db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
1043db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        // Listen for broadcasts related to user-presence
1053db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        final IntentFilter filter = new IntentFilter();
1063db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        filter.addAction(Intent.ACTION_SCREEN_OFF);
1073db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        filter.addAction(Intent.ACTION_USER_PRESENT);
108985e566ceca9c11d2f740499053f37dfaeb9033dSvetoslav
109985e566ceca9c11d2f740499053f37dfaeb9033dSvetoslav        // OK, this is gross but needed. This class is supported by the
110985e566ceca9c11d2f740499053f37dfaeb9033dSvetoslav        // remote views machanism and as a part of that the remote views
111985e566ceca9c11d2f740499053f37dfaeb9033dSvetoslav        // can be inflated by a context for another user without the app
112985e566ceca9c11d2f740499053f37dfaeb9033dSvetoslav        // having interact users permission - just for loading resources.
113985e566ceca9c11d2f740499053f37dfaeb9033dSvetoslav        // For exmaple, when adding widgets from a user profile to the
114985e566ceca9c11d2f740499053f37dfaeb9033dSvetoslav        // home screen. Therefore, we register the receiver as the current
115985e566ceca9c11d2f740499053f37dfaeb9033dSvetoslav        // user not the one the context is for.
116985e566ceca9c11d2f740499053f37dfaeb9033dSvetoslav        getContext().registerReceiverAsUser(mReceiver, android.os.Process.myUserHandle(),
117985e566ceca9c11d2f740499053f37dfaeb9033dSvetoslav                filter, null, mHandler);
118985e566ceca9c11d2f740499053f37dfaeb9033dSvetoslav
1193db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
1203db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        if (mAutoStart) {
1213db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            // Automatically start when requested
1223db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            startFlipping();
1233db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        }
1243db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
1253db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
1263db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    @Override
1273db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    protected void onDetachedFromWindow() {
1283db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        super.onDetachedFromWindow();
1293db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        mVisible = false;
1303db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
1313db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        getContext().unregisterReceiver(mReceiver);
1323db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        updateRunning();
1333db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
1343db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
1353db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    @Override
1363db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    protected void onWindowVisibilityChanged(int visibility) {
1373db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        super.onWindowVisibilityChanged(visibility);
1383db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        mVisible = (visibility == VISIBLE);
1393db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        updateRunning(false);
1403db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
1413db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
1423db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    @Override
1433db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    public void setAdapter(Adapter adapter) {
1443db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        super.setAdapter(adapter);
1453db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        updateRunning();
1463db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
1473db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
1483db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    /**
149aac722a9c0d199c79ae8ce2dd3cce113f01c30b7Philip Milne     * Returns the flip interval, in milliseconds.
1503db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     *
151aac722a9c0d199c79ae8ce2dd3cce113f01c30b7Philip Milne     * @return the flip interval in milliseconds
152aac722a9c0d199c79ae8ce2dd3cce113f01c30b7Philip Milne     *
153aac722a9c0d199c79ae8ce2dd3cce113f01c30b7Philip Milne     * @see #setFlipInterval(int)
154aac722a9c0d199c79ae8ce2dd3cce113f01c30b7Philip Milne     *
155aac722a9c0d199c79ae8ce2dd3cce113f01c30b7Philip Milne     * @attr ref android.R.styleable#AdapterViewFlipper_flipInterval
156aac722a9c0d199c79ae8ce2dd3cce113f01c30b7Philip Milne     */
157aac722a9c0d199c79ae8ce2dd3cce113f01c30b7Philip Milne    public int getFlipInterval() {
158aac722a9c0d199c79ae8ce2dd3cce113f01c30b7Philip Milne        return mFlipInterval;
159aac722a9c0d199c79ae8ce2dd3cce113f01c30b7Philip Milne    }
160aac722a9c0d199c79ae8ce2dd3cce113f01c30b7Philip Milne
161aac722a9c0d199c79ae8ce2dd3cce113f01c30b7Philip Milne    /**
162aac722a9c0d199c79ae8ce2dd3cce113f01c30b7Philip Milne     * How long to wait before flipping to the next view.
163aac722a9c0d199c79ae8ce2dd3cce113f01c30b7Philip Milne     *
164aac722a9c0d199c79ae8ce2dd3cce113f01c30b7Philip Milne     * @param flipInterval flip interval in milliseconds
165aac722a9c0d199c79ae8ce2dd3cce113f01c30b7Philip Milne     *
166aac722a9c0d199c79ae8ce2dd3cce113f01c30b7Philip Milne     * @see #getFlipInterval()
167aac722a9c0d199c79ae8ce2dd3cce113f01c30b7Philip Milne     *
168aac722a9c0d199c79ae8ce2dd3cce113f01c30b7Philip Milne     * @attr ref android.R.styleable#AdapterViewFlipper_flipInterval
1693db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     */
170aac722a9c0d199c79ae8ce2dd3cce113f01c30b7Philip Milne    public void setFlipInterval(int flipInterval) {
171aac722a9c0d199c79ae8ce2dd3cce113f01c30b7Philip Milne        mFlipInterval = flipInterval;
1723db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
1733db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
1743db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    /**
1753db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * Start a timer to cycle through child views
1763db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     */
1773db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    public void startFlipping() {
1783db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        mStarted = true;
1793db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        updateRunning();
1803db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
1813db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
1823db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    /**
1833db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * No more flips
1843db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     */
1853db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    public void stopFlipping() {
1863db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        mStarted = false;
1873db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        updateRunning();
1883db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
1893db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
1903db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    /**
191b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen    * {@inheritDoc}
192b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen    */
193b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen   @Override
194b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen   @RemotableViewMethod
195b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen   public void showNext() {
196b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen       // if the flipper is currently flipping automatically, and showNext() is called
197b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen       // we should we should make sure to reset the timer
198b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen       if (mRunning) {
199b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen           mHandler.removeMessages(FLIP_MSG);
200b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen           Message msg = mHandler.obtainMessage(FLIP_MSG);
201b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen           mHandler.sendMessageDelayed(msg, mFlipInterval);
202b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen       }
203b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen       super.showNext();
204b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen   }
205b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen
206b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen   /**
207b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen    * {@inheritDoc}
208b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen    */
209b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen   @Override
210b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen   @RemotableViewMethod
211b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen   public void showPrevious() {
212b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen       // if the flipper is currently flipping automatically, and showPrevious() is called
213b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen       // we should we should make sure to reset the timer
214b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen       if (mRunning) {
215b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen           mHandler.removeMessages(FLIP_MSG);
216b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen           Message msg = mHandler.obtainMessage(FLIP_MSG);
217b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen           mHandler.sendMessageDelayed(msg, mFlipInterval);
218b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen       }
219b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen       super.showPrevious();
220b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen   }
221b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen
222b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen    /**
2233db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * Internal method to start or stop dispatching flip {@link Message} based
2243db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * on {@link #mRunning} and {@link #mVisible} state.
2253db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     */
2263db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    private void updateRunning() {
2273db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        // by default when we update running, we want the
2283db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        // current view to animate in
2293db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        updateRunning(true);
2303db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
2313db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
2323db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    /**
2333db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * Internal method to start or stop dispatching flip {@link Message} based
2343db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * on {@link #mRunning} and {@link #mVisible} state.
2353db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     *
2363db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * @param flipNow Determines whether or not to execute the animation now, in
2373db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     *            addition to queuing future flips. If omitted, defaults to
2383db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     *            true.
2393db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     */
2403db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    private void updateRunning(boolean flipNow) {
241a02fdf1ba03fad71cc80a89dfc74b17456d5b4a5Adam Cohen        boolean running = !mAdvancedByHost && mVisible && mStarted && mUserPresent
242a02fdf1ba03fad71cc80a89dfc74b17456d5b4a5Adam Cohen                && mAdapter != null;
2433db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        if (running != mRunning) {
2443db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            if (running) {
2453db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                showOnly(mWhichChild, flipNow);
2463db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                Message msg = mHandler.obtainMessage(FLIP_MSG);
2473db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                mHandler.sendMessageDelayed(msg, mFlipInterval);
2483db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            } else {
2493db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                mHandler.removeMessages(FLIP_MSG);
2503db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            }
2513db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            mRunning = running;
2523db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        }
2533db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        if (LOGD) {
2543db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            Log.d(TAG, "updateRunning() mVisible=" + mVisible + ", mStarted=" + mStarted
2553db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                    + ", mUserPresent=" + mUserPresent + ", mRunning=" + mRunning);
2563db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        }
2573db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
2583db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
2593db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    /**
2603db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * Returns true if the child views are flipping.
2613db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     */
2623db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    public boolean isFlipping() {
2633db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        return mStarted;
2643db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
2653db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
2663db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    /**
2673db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * Set if this view automatically calls {@link #startFlipping()} when it
2683db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * becomes attached to a window.
2693db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     */
2703db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    public void setAutoStart(boolean autoStart) {
2713db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        mAutoStart = autoStart;
2723db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
2733db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
2743db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    /**
2753db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * Returns true if this view automatically calls {@link #startFlipping()}
2763db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * when it becomes attached to a window.
2773db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     */
2783db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    public boolean isAutoStart() {
2793db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        return mAutoStart;
2803db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
2813db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
2823db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    private final int FLIP_MSG = 1;
2833db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
2843db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    private final Handler mHandler = new Handler() {
2853db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        @Override
2863db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        public void handleMessage(Message msg) {
2873db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            if (msg.what == FLIP_MSG) {
2883db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                if (mRunning) {
2893db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                    showNext();
2903db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                }
2913db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            }
2923db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        }
2933db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    };
294a02fdf1ba03fad71cc80a89dfc74b17456d5b4a5Adam Cohen
2950e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen    /**
2960e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen     * Called by an {@link android.appwidget.AppWidgetHost} to indicate that it will be
2970e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen     * automatically advancing the views of this {@link AdapterViewFlipper} by calling
2980e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen     * {@link AdapterViewFlipper#advance()} at some point in the future. This allows
2990e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen     * {@link AdapterViewFlipper} to prepare by no longer Advancing its children.
3000e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen     */
301a02fdf1ba03fad71cc80a89dfc74b17456d5b4a5Adam Cohen    @Override
3020e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen    public void fyiWillBeAdvancedByHostKThx() {
303a02fdf1ba03fad71cc80a89dfc74b17456d5b4a5Adam Cohen        mAdvancedByHost = true;
304a02fdf1ba03fad71cc80a89dfc74b17456d5b4a5Adam Cohen        updateRunning(false);
305a02fdf1ba03fad71cc80a89dfc74b17456d5b4a5Adam Cohen    }
3068a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov
3078a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov    @Override
3088a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
3098a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov        super.onInitializeAccessibilityEvent(event);
3108a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov        event.setClassName(AdapterViewFlipper.class.getName());
3118a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov    }
3128a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov
3138a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov    @Override
3148a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
3158a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov        super.onInitializeAccessibilityNodeInfo(info);
3168a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov        info.setClassName(AdapterViewFlipper.class.getName());
3178a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov    }
3183db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen}
319