1c4f2a5652dd42fdb43a94e341b7a2034b0211a21Daniel Sandler/*
2c4f2a5652dd42fdb43a94e341b7a2034b0211a21Daniel Sandler * Copyright (C) 2012 The Android Open Source Project
3c4f2a5652dd42fdb43a94e341b7a2034b0211a21Daniel Sandler *
4c4f2a5652dd42fdb43a94e341b7a2034b0211a21Daniel Sandler * Licensed under the Apache License, Version 2.0 (the "License");
5c4f2a5652dd42fdb43a94e341b7a2034b0211a21Daniel Sandler * you may not use this file except in compliance with the License.
6c4f2a5652dd42fdb43a94e341b7a2034b0211a21Daniel Sandler * You may obtain a copy of the License at
7c4f2a5652dd42fdb43a94e341b7a2034b0211a21Daniel Sandler *
8c4f2a5652dd42fdb43a94e341b7a2034b0211a21Daniel Sandler *      http://www.apache.org/licenses/LICENSE-2.0
9c4f2a5652dd42fdb43a94e341b7a2034b0211a21Daniel Sandler *
10c4f2a5652dd42fdb43a94e341b7a2034b0211a21Daniel Sandler * Unless required by applicable law or agreed to in writing, software
11c4f2a5652dd42fdb43a94e341b7a2034b0211a21Daniel Sandler * distributed under the License is distributed on an "AS IS" BASIS,
12c4f2a5652dd42fdb43a94e341b7a2034b0211a21Daniel Sandler * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c4f2a5652dd42fdb43a94e341b7a2034b0211a21Daniel Sandler * See the License for the specific language governing permissions and
14c4f2a5652dd42fdb43a94e341b7a2034b0211a21Daniel Sandler * limitations under the License.
15c4f2a5652dd42fdb43a94e341b7a2034b0211a21Daniel Sandler */
16c4f2a5652dd42fdb43a94e341b7a2034b0211a21Daniel Sandler
17c4f2a5652dd42fdb43a94e341b7a2034b0211a21Daniel Sandlerpackage com.android.systemui.statusbar.phone;
18c4f2a5652dd42fdb43a94e341b7a2034b0211a21Daniel Sandler
19c4f2a5652dd42fdb43a94e341b7a2034b0211a21Daniel Sandlerimport android.content.Context;
20198a0306e5b0ef6b02d61e299a4b4ab4c1c2cdc8Daniel Sandlerimport android.graphics.Canvas;
21198a0306e5b0ef6b02d61e299a4b4ab4c1c2cdc8Daniel Sandlerimport android.graphics.Paint;
22c4f2a5652dd42fdb43a94e341b7a2034b0211a21Daniel Sandlerimport android.util.AttributeSet;
235de6e94e36e2adbdd4ebfb5c1903c23c9ea3c388Chris Wrenimport android.util.Log;
24c4f2a5652dd42fdb43a94e341b7a2034b0211a21Daniel Sandlerimport android.view.KeyEvent;
255de6e94e36e2adbdd4ebfb5c1903c23c9ea3c388Chris Wrenimport android.view.MotionEvent;
26b4e56edde684c2a09cb225c99571fddb39b43b34Daniel Sandlerimport android.view.View;
27b10d885c3bb9d634c1c21178319fdf1c04c16bc3Daniel Sandlerimport android.view.ViewRootImpl;
28c4f2a5652dd42fdb43a94e341b7a2034b0211a21Daniel Sandlerimport android.widget.FrameLayout;
299b2cd15f0fed990f532f35590c2a2896b90dc7fcChris Wrenimport android.widget.ScrollView;
30c4f2a5652dd42fdb43a94e341b7a2034b0211a21Daniel Sandlerimport android.widget.TextSwitcher;
31c4f2a5652dd42fdb43a94e341b7a2034b0211a21Daniel Sandler
325de6e94e36e2adbdd4ebfb5c1903c23c9ea3c388Chris Wrenimport com.android.systemui.ExpandHelper;
335de6e94e36e2adbdd4ebfb5c1903c23c9ea3c388Chris Wrenimport com.android.systemui.R;
34198a0306e5b0ef6b02d61e299a4b4ab4c1c2cdc8Daniel Sandlerimport com.android.systemui.statusbar.BaseStatusBar;
355de6e94e36e2adbdd4ebfb5c1903c23c9ea3c388Chris Wrenimport com.android.systemui.statusbar.policy.NotificationRowLayout;
365de6e94e36e2adbdd4ebfb5c1903c23c9ea3c388Chris Wren
37c4f2a5652dd42fdb43a94e341b7a2034b0211a21Daniel Sandler
38c4f2a5652dd42fdb43a94e341b7a2034b0211a21Daniel Sandlerpublic class StatusBarWindowView extends FrameLayout
39c4f2a5652dd42fdb43a94e341b7a2034b0211a21Daniel Sandler{
40198a0306e5b0ef6b02d61e299a4b4ab4c1c2cdc8Daniel Sandler    public static final String TAG = "StatusBarWindowView";
41198a0306e5b0ef6b02d61e299a4b4ab4c1c2cdc8Daniel Sandler    public static final boolean DEBUG = BaseStatusBar.DEBUG;
425de6e94e36e2adbdd4ebfb5c1903c23c9ea3c388Chris Wren
435de6e94e36e2adbdd4ebfb5c1903c23c9ea3c388Chris Wren    private ExpandHelper mExpandHelper;
445de6e94e36e2adbdd4ebfb5c1903c23c9ea3c388Chris Wren    private NotificationRowLayout latestItems;
45b4e56edde684c2a09cb225c99571fddb39b43b34Daniel Sandler    private NotificationPanelView mNotificationPanel;
46101784e5605338f22e32f587ffcaa09b582d556cDaniel Sandler    private ScrollView mScrollView;
475de6e94e36e2adbdd4ebfb5c1903c23c9ea3c388Chris Wren
48c4f2a5652dd42fdb43a94e341b7a2034b0211a21Daniel Sandler    PhoneStatusBar mService;
49c4f2a5652dd42fdb43a94e341b7a2034b0211a21Daniel Sandler
50c4f2a5652dd42fdb43a94e341b7a2034b0211a21Daniel Sandler    public StatusBarWindowView(Context context, AttributeSet attrs) {
51c4f2a5652dd42fdb43a94e341b7a2034b0211a21Daniel Sandler        super(context, attrs);
525de6e94e36e2adbdd4ebfb5c1903c23c9ea3c388Chris Wren        setMotionEventSplittingEnabled(false);
53198a0306e5b0ef6b02d61e299a4b4ab4c1c2cdc8Daniel Sandler        setWillNotDraw(!DEBUG);
545de6e94e36e2adbdd4ebfb5c1903c23c9ea3c388Chris Wren    }
555de6e94e36e2adbdd4ebfb5c1903c23c9ea3c388Chris Wren
565de6e94e36e2adbdd4ebfb5c1903c23c9ea3c388Chris Wren    @Override
575de6e94e36e2adbdd4ebfb5c1903c23c9ea3c388Chris Wren    protected void onAttachedToWindow () {
585de6e94e36e2adbdd4ebfb5c1903c23c9ea3c388Chris Wren        super.onAttachedToWindow();
595de6e94e36e2adbdd4ebfb5c1903c23c9ea3c388Chris Wren        latestItems = (NotificationRowLayout) findViewById(R.id.latestItems);
60101784e5605338f22e32f587ffcaa09b582d556cDaniel Sandler        mScrollView = (ScrollView) findViewById(R.id.scroll);
61b4e56edde684c2a09cb225c99571fddb39b43b34Daniel Sandler        mNotificationPanel = (NotificationPanelView) findViewById(R.id.notification_panel);
625de6e94e36e2adbdd4ebfb5c1903c23c9ea3c388Chris Wren        int minHeight = getResources().getDimensionPixelSize(R.dimen.notification_row_min_height);
635de6e94e36e2adbdd4ebfb5c1903c23c9ea3c388Chris Wren        int maxHeight = getResources().getDimensionPixelSize(R.dimen.notification_row_max_height);
645de6e94e36e2adbdd4ebfb5c1903c23c9ea3c388Chris Wren        mExpandHelper = new ExpandHelper(mContext, latestItems, minHeight, maxHeight);
655de6e94e36e2adbdd4ebfb5c1903c23c9ea3c388Chris Wren        mExpandHelper.setEventSource(this);
66101784e5605338f22e32f587ffcaa09b582d556cDaniel Sandler        mExpandHelper.setScrollView(mScrollView);
67b10d885c3bb9d634c1c21178319fdf1c04c16bc3Daniel Sandler
68b10d885c3bb9d634c1c21178319fdf1c04c16bc3Daniel Sandler        // We really need to be able to animate while window animations are going on
69b10d885c3bb9d634c1c21178319fdf1c04c16bc3Daniel Sandler        // so that activities may be started asynchronously from panel animations
70b10d885c3bb9d634c1c21178319fdf1c04c16bc3Daniel Sandler        final ViewRootImpl root = getViewRootImpl();
71b10d885c3bb9d634c1c21178319fdf1c04c16bc3Daniel Sandler        if (root != null) {
72b10d885c3bb9d634c1c21178319fdf1c04c16bc3Daniel Sandler            root.setDrawDuringWindowsAnimating(true);
73b10d885c3bb9d634c1c21178319fdf1c04c16bc3Daniel Sandler        }
74c4f2a5652dd42fdb43a94e341b7a2034b0211a21Daniel Sandler    }
75c4f2a5652dd42fdb43a94e341b7a2034b0211a21Daniel Sandler
76c4f2a5652dd42fdb43a94e341b7a2034b0211a21Daniel Sandler    @Override
77c4f2a5652dd42fdb43a94e341b7a2034b0211a21Daniel Sandler    public boolean dispatchKeyEvent(KeyEvent event) {
78c4f2a5652dd42fdb43a94e341b7a2034b0211a21Daniel Sandler        boolean down = event.getAction() == KeyEvent.ACTION_DOWN;
79c4f2a5652dd42fdb43a94e341b7a2034b0211a21Daniel Sandler        switch (event.getKeyCode()) {
80c4f2a5652dd42fdb43a94e341b7a2034b0211a21Daniel Sandler        case KeyEvent.KEYCODE_BACK:
81c4f2a5652dd42fdb43a94e341b7a2034b0211a21Daniel Sandler            if (!down) {
8211cf178100e71d3f9f34ab5865e03a277c5eadaaDaniel Sandler                mService.animateCollapsePanels();
83c4f2a5652dd42fdb43a94e341b7a2034b0211a21Daniel Sandler            }
84c4f2a5652dd42fdb43a94e341b7a2034b0211a21Daniel Sandler            return true;
85c4f2a5652dd42fdb43a94e341b7a2034b0211a21Daniel Sandler        }
86c4f2a5652dd42fdb43a94e341b7a2034b0211a21Daniel Sandler        return super.dispatchKeyEvent(event);
87c4f2a5652dd42fdb43a94e341b7a2034b0211a21Daniel Sandler    }
885de6e94e36e2adbdd4ebfb5c1903c23c9ea3c388Chris Wren
895de6e94e36e2adbdd4ebfb5c1903c23c9ea3c388Chris Wren    @Override
905de6e94e36e2adbdd4ebfb5c1903c23c9ea3c388Chris Wren    public boolean onInterceptTouchEvent(MotionEvent ev) {
91b4e56edde684c2a09cb225c99571fddb39b43b34Daniel Sandler        boolean intercept = false;
92101784e5605338f22e32f587ffcaa09b582d556cDaniel Sandler        if (mNotificationPanel.isFullyExpanded() && mScrollView.getVisibility() == View.VISIBLE) {
93b4e56edde684c2a09cb225c99571fddb39b43b34Daniel Sandler            intercept = mExpandHelper.onInterceptTouchEvent(ev);
94b4e56edde684c2a09cb225c99571fddb39b43b34Daniel Sandler        }
95b4e56edde684c2a09cb225c99571fddb39b43b34Daniel Sandler        if (!intercept) {
96b4e56edde684c2a09cb225c99571fddb39b43b34Daniel Sandler            super.onInterceptTouchEvent(ev);
97b4e56edde684c2a09cb225c99571fddb39b43b34Daniel Sandler        }
985de6e94e36e2adbdd4ebfb5c1903c23c9ea3c388Chris Wren        if (intercept) {
99a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn            MotionEvent cancellation = MotionEvent.obtain(ev);
100a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn            cancellation.setAction(MotionEvent.ACTION_CANCEL);
1015de6e94e36e2adbdd4ebfb5c1903c23c9ea3c388Chris Wren            latestItems.onInterceptTouchEvent(cancellation);
102a4b7f2f75e7803193429ec1179fb5e2eb1c6fbdaDianne Hackborn            cancellation.recycle();
1035de6e94e36e2adbdd4ebfb5c1903c23c9ea3c388Chris Wren        }
1045de6e94e36e2adbdd4ebfb5c1903c23c9ea3c388Chris Wren        return intercept;
1055de6e94e36e2adbdd4ebfb5c1903c23c9ea3c388Chris Wren    }
1065de6e94e36e2adbdd4ebfb5c1903c23c9ea3c388Chris Wren
1075de6e94e36e2adbdd4ebfb5c1903c23c9ea3c388Chris Wren    @Override
1085de6e94e36e2adbdd4ebfb5c1903c23c9ea3c388Chris Wren    public boolean onTouchEvent(MotionEvent ev) {
109b4e56edde684c2a09cb225c99571fddb39b43b34Daniel Sandler        boolean handled = false;
110b4e56edde684c2a09cb225c99571fddb39b43b34Daniel Sandler        if (mNotificationPanel.isFullyExpanded()) {
111b4e56edde684c2a09cb225c99571fddb39b43b34Daniel Sandler            handled = mExpandHelper.onTouchEvent(ev);
112b4e56edde684c2a09cb225c99571fddb39b43b34Daniel Sandler        }
113b4e56edde684c2a09cb225c99571fddb39b43b34Daniel Sandler        if (!handled) {
114b4e56edde684c2a09cb225c99571fddb39b43b34Daniel Sandler            handled = super.onTouchEvent(ev);
115b4e56edde684c2a09cb225c99571fddb39b43b34Daniel Sandler        }
1165de6e94e36e2adbdd4ebfb5c1903c23c9ea3c388Chris Wren        return handled;
1175de6e94e36e2adbdd4ebfb5c1903c23c9ea3c388Chris Wren    }
118198a0306e5b0ef6b02d61e299a4b4ab4c1c2cdc8Daniel Sandler
119198a0306e5b0ef6b02d61e299a4b4ab4c1c2cdc8Daniel Sandler    @Override
120198a0306e5b0ef6b02d61e299a4b4ab4c1c2cdc8Daniel Sandler    public void onDraw(Canvas canvas) {
121198a0306e5b0ef6b02d61e299a4b4ab4c1c2cdc8Daniel Sandler        super.onDraw(canvas);
122198a0306e5b0ef6b02d61e299a4b4ab4c1c2cdc8Daniel Sandler        if (DEBUG) {
123198a0306e5b0ef6b02d61e299a4b4ab4c1c2cdc8Daniel Sandler            Paint pt = new Paint();
124198a0306e5b0ef6b02d61e299a4b4ab4c1c2cdc8Daniel Sandler            pt.setColor(0x80FFFF00);
125198a0306e5b0ef6b02d61e299a4b4ab4c1c2cdc8Daniel Sandler            pt.setStrokeWidth(12.0f);
126198a0306e5b0ef6b02d61e299a4b4ab4c1c2cdc8Daniel Sandler            pt.setStyle(Paint.Style.STROKE);
127198a0306e5b0ef6b02d61e299a4b4ab4c1c2cdc8Daniel Sandler            canvas.drawRect(0, 0, canvas.getWidth(), canvas.getHeight(), pt);
128198a0306e5b0ef6b02d61e299a4b4ab4c1c2cdc8Daniel Sandler        }
129198a0306e5b0ef6b02d61e299a4b4ab4c1c2cdc8Daniel Sandler    }
130ac47ff70c322614ff2ca9ad82fe41338daf55877Daniel Sandler
131ac47ff70c322614ff2ca9ad82fe41338daf55877Daniel Sandler    public void cancelExpandHelper() {
1321a3bdd5097e83659590895991904bbc6250cd5f2Daniel Sandler        if (mExpandHelper != null) {
1331a3bdd5097e83659590895991904bbc6250cd5f2Daniel Sandler            mExpandHelper.cancel();
1341a3bdd5097e83659590895991904bbc6250cd5f2Daniel Sandler        }
135ac47ff70c322614ff2ca9ad82fe41338daf55877Daniel Sandler    }
136c4f2a5652dd42fdb43a94e341b7a2034b0211a21Daniel Sandler}
137c4f2a5652dd42fdb43a94e341b7a2034b0211a21Daniel Sandler
138