PanelBar.java revision 50a531337e7d6d49b40a1c96636962507ccf6c61
150a531337e7d6d49b40a1c96636962507ccf6c61Daniel Sandler/*
250a531337e7d6d49b40a1c96636962507ccf6c61Daniel Sandler * Copyright (C) 2012 The Android Open Source Project
350a531337e7d6d49b40a1c96636962507ccf6c61Daniel Sandler *
450a531337e7d6d49b40a1c96636962507ccf6c61Daniel Sandler * Licensed under the Apache License, Version 2.0 (the "License");
550a531337e7d6d49b40a1c96636962507ccf6c61Daniel Sandler * you may not use this file except in compliance with the License.
650a531337e7d6d49b40a1c96636962507ccf6c61Daniel Sandler * You may obtain a copy of the License at
750a531337e7d6d49b40a1c96636962507ccf6c61Daniel Sandler *
850a531337e7d6d49b40a1c96636962507ccf6c61Daniel Sandler *      http://www.apache.org/licenses/LICENSE-2.0
950a531337e7d6d49b40a1c96636962507ccf6c61Daniel Sandler *
1050a531337e7d6d49b40a1c96636962507ccf6c61Daniel Sandler * Unless required by applicable law or agreed to in writing, software
1150a531337e7d6d49b40a1c96636962507ccf6c61Daniel Sandler * distributed under the License is distributed on an "AS IS" BASIS,
1250a531337e7d6d49b40a1c96636962507ccf6c61Daniel Sandler * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1350a531337e7d6d49b40a1c96636962507ccf6c61Daniel Sandler * See the License for the specific language governing permissions and
1450a531337e7d6d49b40a1c96636962507ccf6c61Daniel Sandler * limitations under the License.
1550a531337e7d6d49b40a1c96636962507ccf6c61Daniel Sandler */
1650a531337e7d6d49b40a1c96636962507ccf6c61Daniel Sandler
1708d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandlerpackage com.android.systemui.statusbar.phone;
1808d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler
1908d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandlerimport java.util.ArrayList;
2008d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler
2108d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandlerimport android.content.Context;
2208d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandlerimport android.util.AttributeSet;
2308d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandlerimport android.util.Slog;
2408d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandlerimport android.view.MotionEvent;
25173bae2c674b2bc25cf376cbb4e150bd86703049Daniel Sandlerimport android.view.View;
2608d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandlerimport android.widget.FrameLayout;
2708d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler
2808d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandlerpublic class PanelBar extends FrameLayout {
29bf4aa9d5bc34df144afcab45e8045d34a0ac090aDaniel Sandler    public static final boolean DEBUG = false;
30198a0306e5b0ef6b02d61e299a4b4ab4c1c2cdc8Daniel Sandler    public static final String TAG = PanelBar.class.getSimpleName();
3108d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler    public static final void LOG(String fmt, Object... args) {
3208d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler        if (!DEBUG) return;
3308d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler        Slog.v(TAG, String.format(fmt, args));
3408d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler    }
3508d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler
36198a0306e5b0ef6b02d61e299a4b4ab4c1c2cdc8Daniel Sandler    public static final int STATE_CLOSED = 0;
37198a0306e5b0ef6b02d61e299a4b4ab4c1c2cdc8Daniel Sandler    public static final int STATE_OPENING = 1;
38198a0306e5b0ef6b02d61e299a4b4ab4c1c2cdc8Daniel Sandler    public static final int STATE_OPEN = 2;
39198a0306e5b0ef6b02d61e299a4b4ab4c1c2cdc8Daniel Sandler
4067eab79051eea2d4f8fda4a2a698900ffacfb557Daniel Sandler    PanelHolder mPanelHolder;
4167eab79051eea2d4f8fda4a2a698900ffacfb557Daniel Sandler    ArrayList<PanelView> mPanels = new ArrayList<PanelView>();
4267eab79051eea2d4f8fda4a2a698900ffacfb557Daniel Sandler    PanelView mTouchingPanel;
43978f853d189c1857190b4a2e200c7a283e31ca14Daniel Sandler    private int mState = STATE_CLOSED;
44978f853d189c1857190b4a2e200c7a283e31ca14Daniel Sandler    private boolean mTracking;
45978f853d189c1857190b4a2e200c7a283e31ca14Daniel Sandler
4667eab79051eea2d4f8fda4a2a698900ffacfb557Daniel Sandler    float mPanelExpandedFractionSum;
4767eab79051eea2d4f8fda4a2a698900ffacfb557Daniel Sandler
48198a0306e5b0ef6b02d61e299a4b4ab4c1c2cdc8Daniel Sandler    public void go(int state) {
4967eab79051eea2d4f8fda4a2a698900ffacfb557Daniel Sandler        if (DEBUG) LOG("go state: %d -> %d", mState, state);
50978f853d189c1857190b4a2e200c7a283e31ca14Daniel Sandler        mState = state;
51978f853d189c1857190b4a2e200c7a283e31ca14Daniel Sandler    }
5208d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler
5308d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler    public PanelBar(Context context, AttributeSet attrs) {
5408d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler        super(context, attrs);
5508d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler    }
5608d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler
5708d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler    @Override
5808d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler    protected void onFinishInflate() {
5908d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler        super.onFinishInflate();
6008d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler    }
6108d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler
6208d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler    public void addPanel(PanelView pv) {
6308d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler        mPanels.add(pv);
6408d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler        pv.setBar(this);
6508d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler    }
6608d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler
6708d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler    public void setPanelHolder(PanelHolder ph) {
6808d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler        if (ph == null) {
6908d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler            Slog.e(TAG, "setPanelHolder: null PanelHolder", new Throwable());
7008d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler            return;
7108d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler        }
7208d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler        ph.setBar(this);
7308d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler        mPanelHolder = ph;
7408d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler        final int N = ph.getChildCount();
7508d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler        for (int i=0; i<N; i++) {
76e111ad300d614a0f94e30f96ae664a1de578c48aDaniel Sandler            final View v = ph.getChildAt(i);
77e111ad300d614a0f94e30f96ae664a1de578c48aDaniel Sandler            if (v != null && v instanceof PanelView) {
78e111ad300d614a0f94e30f96ae664a1de578c48aDaniel Sandler                addPanel((PanelView) v);
7908d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler            }
8008d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler        }
8108d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler    }
8208d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler
8308d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler    public float getBarHeight() {
8408d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler        return getMeasuredHeight();
8508d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler    }
8608d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler
87efb0faf1c043777762eecfef87ec575632c365e1Daniel Sandler    public PanelView selectPanelForTouch(MotionEvent touch) {
88cf591db04914d8ceadd982451b325bd8c4817086Daniel Sandler        final int N = mPanels.size();
89efb0faf1c043777762eecfef87ec575632c365e1Daniel Sandler        return mPanels.get((int)(N * touch.getX() / getMeasuredWidth()));
90cf591db04914d8ceadd982451b325bd8c4817086Daniel Sandler    }
91cf591db04914d8ceadd982451b325bd8c4817086Daniel Sandler
925050813f15a1d39d49cb8eca5a3aa6df43c4d450Daniel Sandler    public boolean panelsEnabled() {
931e8feef1faca7d2f14bf459691dbe724c8cf5c88Daniel Sandler        return true;
941e8feef1faca7d2f14bf459691dbe724c8cf5c88Daniel Sandler    }
951e8feef1faca7d2f14bf459691dbe724c8cf5c88Daniel Sandler
9608d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler    @Override
9708d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler    public boolean onTouchEvent(MotionEvent event) {
981e8feef1faca7d2f14bf459691dbe724c8cf5c88Daniel Sandler        // Allow subclasses to implement enable/disable semantics
995050813f15a1d39d49cb8eca5a3aa6df43c4d450Daniel Sandler        if (!panelsEnabled()) return false;
1001e8feef1faca7d2f14bf459691dbe724c8cf5c88Daniel Sandler
10108d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler        // figure out which panel needs to be talked to here
10208d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler        if (event.getAction() == MotionEvent.ACTION_DOWN) {
103efb0faf1c043777762eecfef87ec575632c365e1Daniel Sandler            final PanelView panel = selectPanelForTouch(event);
104efb0faf1c043777762eecfef87ec575632c365e1Daniel Sandler            if (panel == null) {
105efb0faf1c043777762eecfef87ec575632c365e1Daniel Sandler                // panel is not there, so we'll eat the gesture
106efb0faf1c043777762eecfef87ec575632c365e1Daniel Sandler                if (DEBUG) LOG("PanelBar.onTouch: no panel for x=%d, bailing", event.getX());
107efb0faf1c043777762eecfef87ec575632c365e1Daniel Sandler                mTouchingPanel = null;
108efb0faf1c043777762eecfef87ec575632c365e1Daniel Sandler                return true;
109efb0faf1c043777762eecfef87ec575632c365e1Daniel Sandler            }
110919adac28bd6a9888c3bbd53a1736f260bc76bbfJohn Spurlock            boolean enabled = panel.isEnabled();
11167eab79051eea2d4f8fda4a2a698900ffacfb557Daniel Sandler            if (DEBUG) LOG("PanelBar.onTouch: state=%d ACTION_DOWN: panel %s %s", mState, panel,
112919adac28bd6a9888c3bbd53a1736f260bc76bbfJohn Spurlock                    (enabled ? "" : " (disabled)"));
113efb0faf1c043777762eecfef87ec575632c365e1Daniel Sandler            if (!enabled) {
114efb0faf1c043777762eecfef87ec575632c365e1Daniel Sandler                // panel is disabled, so we'll eat the gesture
115efb0faf1c043777762eecfef87ec575632c365e1Daniel Sandler                mTouchingPanel = null;
116efb0faf1c043777762eecfef87ec575632c365e1Daniel Sandler                return true;
117efb0faf1c043777762eecfef87ec575632c365e1Daniel Sandler            }
118198a0306e5b0ef6b02d61e299a4b4ab4c1c2cdc8Daniel Sandler            startOpeningPanel(panel);
11908d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler        }
120efb0faf1c043777762eecfef87ec575632c365e1Daniel Sandler        final boolean result = mTouchingPanel != null
121040c2e4ace25a45bc701821da4fa786e6dd75eadDaniel Sandler                ? mTouchingPanel.onTouchEvent(event)
122efb0faf1c043777762eecfef87ec575632c365e1Daniel Sandler                : true;
12308d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler        return result;
12408d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler    }
12508d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler
126198a0306e5b0ef6b02d61e299a4b4ab4c1c2cdc8Daniel Sandler    // called from PanelView when self-expanding, too
127198a0306e5b0ef6b02d61e299a4b4ab4c1c2cdc8Daniel Sandler    public void startOpeningPanel(PanelView panel) {
12867eab79051eea2d4f8fda4a2a698900ffacfb557Daniel Sandler        if (DEBUG) LOG("startOpeningPanel: " + panel);
129198a0306e5b0ef6b02d61e299a4b4ab4c1c2cdc8Daniel Sandler        mTouchingPanel = panel;
130198a0306e5b0ef6b02d61e299a4b4ab4c1c2cdc8Daniel Sandler        mPanelHolder.setSelectedPanel(mTouchingPanel);
13167eab79051eea2d4f8fda4a2a698900ffacfb557Daniel Sandler        for (PanelView pv : mPanels) {
13267eab79051eea2d4f8fda4a2a698900ffacfb557Daniel Sandler            if (pv != panel) {
13367eab79051eea2d4f8fda4a2a698900ffacfb557Daniel Sandler                pv.collapse();
13467eab79051eea2d4f8fda4a2a698900ffacfb557Daniel Sandler            }
13567eab79051eea2d4f8fda4a2a698900ffacfb557Daniel Sandler        }
136198a0306e5b0ef6b02d61e299a4b4ab4c1c2cdc8Daniel Sandler    }
137198a0306e5b0ef6b02d61e299a4b4ab4c1c2cdc8Daniel Sandler
13808d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler    public void panelExpansionChanged(PanelView panel, float frac) {
13908d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler        boolean fullyClosed = true;
1408e72c9e19cfb0b6c1463fa841f1dd02be8f3b4e1Daniel Sandler        PanelView fullyOpenedPanel = null;
14167eab79051eea2d4f8fda4a2a698900ffacfb557Daniel Sandler        if (DEBUG) LOG("panelExpansionChanged: start state=%d panel=%s", mState, panel.getName());
14267eab79051eea2d4f8fda4a2a698900ffacfb557Daniel Sandler        mPanelExpandedFractionSum = 0f;
14308d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler        for (PanelView pv : mPanels) {
144173bae2c674b2bc25cf376cbb4e150bd86703049Daniel Sandler            final boolean visible = pv.getVisibility() == View.VISIBLE;
145978f853d189c1857190b4a2e200c7a283e31ca14Daniel Sandler            // adjust any other panels that may be partially visible
14608d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler            if (pv.getExpandedHeight() > 0f) {
147198a0306e5b0ef6b02d61e299a4b4ab4c1c2cdc8Daniel Sandler                if (mState == STATE_CLOSED) {
148198a0306e5b0ef6b02d61e299a4b4ab4c1c2cdc8Daniel Sandler                    go(STATE_OPENING);
149198a0306e5b0ef6b02d61e299a4b4ab4c1c2cdc8Daniel Sandler                    onPanelPeeked();
150198a0306e5b0ef6b02d61e299a4b4ab4c1c2cdc8Daniel Sandler                }
15108d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler                fullyClosed = false;
15208d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler                final float thisFrac = pv.getExpandedFraction();
15367eab79051eea2d4f8fda4a2a698900ffacfb557Daniel Sandler                mPanelExpandedFractionSum += (visible ? thisFrac : 0);
15467eab79051eea2d4f8fda4a2a698900ffacfb557Daniel Sandler                if (DEBUG) LOG("panelExpansionChanged:  -> %s: f=%.1f", pv.getName(), thisFrac);
15508d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler                if (panel == pv) {
1568e72c9e19cfb0b6c1463fa841f1dd02be8f3b4e1Daniel Sandler                    if (thisFrac == 1f) fullyOpenedPanel = panel;
15708d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler                }
15808d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler            }
159173bae2c674b2bc25cf376cbb4e150bd86703049Daniel Sandler            if (pv.getExpandedHeight() > 0f) {
160173bae2c674b2bc25cf376cbb4e150bd86703049Daniel Sandler                if (!visible) pv.setVisibility(View.VISIBLE);
161173bae2c674b2bc25cf376cbb4e150bd86703049Daniel Sandler            } else {
162173bae2c674b2bc25cf376cbb4e150bd86703049Daniel Sandler                if (visible) pv.setVisibility(View.GONE);
163173bae2c674b2bc25cf376cbb4e150bd86703049Daniel Sandler            }
16408d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler        }
16567eab79051eea2d4f8fda4a2a698900ffacfb557Daniel Sandler        mPanelExpandedFractionSum /= mPanels.size();
166978f853d189c1857190b4a2e200c7a283e31ca14Daniel Sandler        if (fullyOpenedPanel != null && !mTracking) {
167978f853d189c1857190b4a2e200c7a283e31ca14Daniel Sandler            go(STATE_OPEN);
168978f853d189c1857190b4a2e200c7a283e31ca14Daniel Sandler            onPanelFullyOpened(fullyOpenedPanel);
169198a0306e5b0ef6b02d61e299a4b4ab4c1c2cdc8Daniel Sandler        } else if (fullyClosed && !mTracking && mState != STATE_CLOSED) {
170978f853d189c1857190b4a2e200c7a283e31ca14Daniel Sandler            go(STATE_CLOSED);
171978f853d189c1857190b4a2e200c7a283e31ca14Daniel Sandler            onAllPanelsCollapsed();
172978f853d189c1857190b4a2e200c7a283e31ca14Daniel Sandler        }
17308d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler
17467eab79051eea2d4f8fda4a2a698900ffacfb557Daniel Sandler        if (DEBUG) LOG("panelExpansionChanged: end state=%d [%s%s ]", mState,
1758e72c9e19cfb0b6c1463fa841f1dd02be8f3b4e1Daniel Sandler                (fullyOpenedPanel!=null)?" fullyOpened":"", fullyClosed?" fullyClosed":"");
17608d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler    }
17708d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler
17808d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler    public void collapseAllPanels(boolean animate) {
179198a0306e5b0ef6b02d61e299a4b4ab4c1c2cdc8Daniel Sandler        boolean waiting = false;
18008d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler        for (PanelView pv : mPanels) {
181198a0306e5b0ef6b02d61e299a4b4ab4c1c2cdc8Daniel Sandler            if (animate && !pv.isFullyCollapsed()) {
182198a0306e5b0ef6b02d61e299a4b4ab4c1c2cdc8Daniel Sandler                pv.collapse();
183198a0306e5b0ef6b02d61e299a4b4ab4c1c2cdc8Daniel Sandler                waiting = true;
18408d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler            } else {
18508d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler                pv.setExpandedFraction(0); // just in case
18667eab79051eea2d4f8fda4a2a698900ffacfb557Daniel Sandler                pv.setVisibility(View.GONE);
18708d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler            }
18808d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler        }
18967eab79051eea2d4f8fda4a2a698900ffacfb557Daniel Sandler        if (DEBUG) LOG("collapseAllPanels: animate=%s waiting=%s", animate, waiting);
190c38bbc391ae4ec5945d5fa408da3994552f775ebDaniel Sandler        if (!waiting && mState != STATE_CLOSED) {
191198a0306e5b0ef6b02d61e299a4b4ab4c1c2cdc8Daniel Sandler            // it's possible that nothing animated, so we replicate the termination
192198a0306e5b0ef6b02d61e299a4b4ab4c1c2cdc8Daniel Sandler            // conditions of panelExpansionChanged here
193198a0306e5b0ef6b02d61e299a4b4ab4c1c2cdc8Daniel Sandler            go(STATE_CLOSED);
194198a0306e5b0ef6b02d61e299a4b4ab4c1c2cdc8Daniel Sandler            onAllPanelsCollapsed();
195198a0306e5b0ef6b02d61e299a4b4ab4c1c2cdc8Daniel Sandler        }
19608d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler    }
19708d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler
19808d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler    public void onPanelPeeked() {
19967eab79051eea2d4f8fda4a2a698900ffacfb557Daniel Sandler        if (DEBUG) LOG("onPanelPeeked");
20008d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler    }
20108d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler
20208d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler    public void onAllPanelsCollapsed() {
20367eab79051eea2d4f8fda4a2a698900ffacfb557Daniel Sandler        if (DEBUG) LOG("onAllPanelsCollapsed");
20408d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler    }
20508d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler
2068e72c9e19cfb0b6c1463fa841f1dd02be8f3b4e1Daniel Sandler    public void onPanelFullyOpened(PanelView openPanel) {
20767eab79051eea2d4f8fda4a2a698900ffacfb557Daniel Sandler        if (DEBUG) LOG("onPanelFullyOpened");
20808d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler    }
209978f853d189c1857190b4a2e200c7a283e31ca14Daniel Sandler
210978f853d189c1857190b4a2e200c7a283e31ca14Daniel Sandler    public void onTrackingStarted(PanelView panel) {
211978f853d189c1857190b4a2e200c7a283e31ca14Daniel Sandler        mTracking = true;
21267eab79051eea2d4f8fda4a2a698900ffacfb557Daniel Sandler        if (DEBUG && panel != mTouchingPanel) {
213978f853d189c1857190b4a2e200c7a283e31ca14Daniel Sandler            LOG("shouldn't happen: onTrackingStarted(%s) != mTouchingPanel(%s)",
214978f853d189c1857190b4a2e200c7a283e31ca14Daniel Sandler                    panel, mTouchingPanel);
215978f853d189c1857190b4a2e200c7a283e31ca14Daniel Sandler        }
216978f853d189c1857190b4a2e200c7a283e31ca14Daniel Sandler    }
217978f853d189c1857190b4a2e200c7a283e31ca14Daniel Sandler
218978f853d189c1857190b4a2e200c7a283e31ca14Daniel Sandler    public void onTrackingStopped(PanelView panel) {
219978f853d189c1857190b4a2e200c7a283e31ca14Daniel Sandler        mTracking = false;
220978f853d189c1857190b4a2e200c7a283e31ca14Daniel Sandler        panelExpansionChanged(panel, panel.getExpandedFraction());
221978f853d189c1857190b4a2e200c7a283e31ca14Daniel Sandler    }
22208d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler}
223