108d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler/* 208d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler * Copyright (C) 2012 The Android Open Source Project 308d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler * 408d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler * Licensed under the Apache License, Version 2.0 (the "License"); 508d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler * you may not use this file except in compliance with the License. 608d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler * You may obtain a copy of the License at 708d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler * 808d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler * http://www.apache.org/licenses/LICENSE-2.0 908d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler * 1008d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler * Unless required by applicable law or agreed to in writing, software 1108d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler * distributed under the License is distributed on an "AS IS" BASIS, 1208d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1308d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler * See the License for the specific language governing permissions and 1408d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler * limitations under the License. 1508d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler */ 1608d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler 1708d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandlerpackage com.android.systemui.statusbar.phone; 1808d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler 1908d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandlerimport android.content.Context; 204d179dc6ccf3eb118767e94b803484abe9552537Chet Haaseimport android.content.res.Resources; 214d179dc6ccf3eb118767e94b803484abe9552537Chet Haaseimport android.graphics.Canvas; 224d179dc6ccf3eb118767e94b803484abe9552537Chet Haaseimport android.graphics.drawable.Drawable; 2308d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandlerimport android.util.AttributeSet; 2464161ccb2f3341ebe1675e38a999250c7967d0adChris Wrenimport android.util.EventLog; 25040c2e4ace25a45bc701821da4fa786e6dd75eadDaniel Sandlerimport android.view.MotionEvent; 2613522a2e40730a0703fd7f185b7fb9be8ae37ab6Daniel Sandlerimport android.view.View; 2723b0a4e90554cc47f5ec1cef6b15ce0e32bb1ff2Casey Burkhardtimport android.view.accessibility.AccessibilityEvent; 2813522a2e40730a0703fd7f185b7fb9be8ae37ab6Daniel Sandler 2964161ccb2f3341ebe1675e38a999250c7967d0adChris Wrenimport com.android.systemui.EventLogTags; 304d179dc6ccf3eb118767e94b803484abe9552537Chet Haaseimport com.android.systemui.R; 31151f00d8f06e207038125f227b42f06a25d5e0a0Daniel Sandlerimport com.android.systemui.statusbar.GestureRecorder; 3208d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler 3308d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandlerpublic class NotificationPanelView extends PanelView { 3464161ccb2f3341ebe1675e38a999250c7967d0adChris Wren public static final boolean DEBUG_GESTURES = true; 354d179dc6ccf3eb118767e94b803484abe9552537Chet Haase 364d179dc6ccf3eb118767e94b803484abe9552537Chet Haase Drawable mHandleBar; 37076324ae191469737afa5bbec577a718f3a31886Daniel Sandler int mHandleBarHeight; 3813522a2e40730a0703fd7f185b7fb9be8ae37ab6Daniel Sandler View mHandleView; 39040c2e4ace25a45bc701821da4fa786e6dd75eadDaniel Sandler int mFingers; 40040c2e4ace25a45bc701821da4fa786e6dd75eadDaniel Sandler PhoneStatusBar mStatusBar; 412017a056624e747ac91f8203728960a27da0b95aDaniel Sandler boolean mOkToFlip; 424d179dc6ccf3eb118767e94b803484abe9552537Chet Haase 4308d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler public NotificationPanelView(Context context, AttributeSet attrs) { 4408d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler super(context, attrs); 4513522a2e40730a0703fd7f185b7fb9be8ae37ab6Daniel Sandler } 4613522a2e40730a0703fd7f185b7fb9be8ae37ab6Daniel Sandler 47040c2e4ace25a45bc701821da4fa786e6dd75eadDaniel Sandler public void setStatusBar(PhoneStatusBar bar) { 48040c2e4ace25a45bc701821da4fa786e6dd75eadDaniel Sandler mStatusBar = bar; 49040c2e4ace25a45bc701821da4fa786e6dd75eadDaniel Sandler } 50040c2e4ace25a45bc701821da4fa786e6dd75eadDaniel Sandler 5113522a2e40730a0703fd7f185b7fb9be8ae37ab6Daniel Sandler @Override 5213522a2e40730a0703fd7f185b7fb9be8ae37ab6Daniel Sandler protected void onFinishInflate() { 5313522a2e40730a0703fd7f185b7fb9be8ae37ab6Daniel Sandler super.onFinishInflate(); 544d179dc6ccf3eb118767e94b803484abe9552537Chet Haase 5513522a2e40730a0703fd7f185b7fb9be8ae37ab6Daniel Sandler Resources resources = getContext().getResources(); 564d179dc6ccf3eb118767e94b803484abe9552537Chet Haase mHandleBar = resources.getDrawable(R.drawable.status_bar_close); 57076324ae191469737afa5bbec577a718f3a31886Daniel Sandler mHandleBarHeight = resources.getDimensionPixelSize(R.dimen.close_handle_height); 5813522a2e40730a0703fd7f185b7fb9be8ae37ab6Daniel Sandler mHandleView = findViewById(R.id.handle); 5908d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler } 6008d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler 6108d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler @Override 6208d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler public void fling(float vel, boolean always) { 63151f00d8f06e207038125f227b42f06a25d5e0a0Daniel Sandler GestureRecorder gr = ((PhoneStatusBarView) mBar).mBar.getGestureRecorder(); 64151f00d8f06e207038125f227b42f06a25d5e0a0Daniel Sandler if (gr != null) { 65151f00d8f06e207038125f227b42f06a25d5e0a0Daniel Sandler gr.tag( 66151f00d8f06e207038125f227b42f06a25d5e0a0Daniel Sandler "fling " + ((vel > 0) ? "open" : "closed"), 67151f00d8f06e207038125f227b42f06a25d5e0a0Daniel Sandler "notifications,v=" + vel); 68151f00d8f06e207038125f227b42f06a25d5e0a0Daniel Sandler } 6908d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler super.fling(vel, always); 7008d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler } 714d179dc6ccf3eb118767e94b803484abe9552537Chet Haase 7223b0a4e90554cc47f5ec1cef6b15ce0e32bb1ff2Casey Burkhardt @Override 7323b0a4e90554cc47f5ec1cef6b15ce0e32bb1ff2Casey Burkhardt public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { 7423b0a4e90554cc47f5ec1cef6b15ce0e32bb1ff2Casey Burkhardt if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) { 7523b0a4e90554cc47f5ec1cef6b15ce0e32bb1ff2Casey Burkhardt event.getText() 7623b0a4e90554cc47f5ec1cef6b15ce0e32bb1ff2Casey Burkhardt .add(getContext().getString(R.string.accessibility_desc_notification_shade)); 7723b0a4e90554cc47f5ec1cef6b15ce0e32bb1ff2Casey Burkhardt return true; 7823b0a4e90554cc47f5ec1cef6b15ce0e32bb1ff2Casey Burkhardt } 7923b0a4e90554cc47f5ec1cef6b15ce0e32bb1ff2Casey Burkhardt 8023b0a4e90554cc47f5ec1cef6b15ce0e32bb1ff2Casey Burkhardt return super.dispatchPopulateAccessibilityEvent(event); 8123b0a4e90554cc47f5ec1cef6b15ce0e32bb1ff2Casey Burkhardt } 8223b0a4e90554cc47f5ec1cef6b15ce0e32bb1ff2Casey Burkhardt 8313522a2e40730a0703fd7f185b7fb9be8ae37ab6Daniel Sandler // We draw the handle ourselves so that it's always glued to the bottom of the window. 844d179dc6ccf3eb118767e94b803484abe9552537Chet Haase @Override 854d179dc6ccf3eb118767e94b803484abe9552537Chet Haase protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 864d179dc6ccf3eb118767e94b803484abe9552537Chet Haase super.onLayout(changed, left, top, right, bottom); 874d179dc6ccf3eb118767e94b803484abe9552537Chet Haase if (changed) { 8813522a2e40730a0703fd7f185b7fb9be8ae37ab6Daniel Sandler final int pl = getPaddingLeft(); 8913522a2e40730a0703fd7f185b7fb9be8ae37ab6Daniel Sandler final int pr = getPaddingRight(); 9013522a2e40730a0703fd7f185b7fb9be8ae37ab6Daniel Sandler mHandleBar.setBounds(pl, 0, getWidth() - pr, (int) mHandleBarHeight); 914d179dc6ccf3eb118767e94b803484abe9552537Chet Haase } 924d179dc6ccf3eb118767e94b803484abe9552537Chet Haase } 934d179dc6ccf3eb118767e94b803484abe9552537Chet Haase 944d179dc6ccf3eb118767e94b803484abe9552537Chet Haase @Override 954d179dc6ccf3eb118767e94b803484abe9552537Chet Haase public void draw(Canvas canvas) { 964d179dc6ccf3eb118767e94b803484abe9552537Chet Haase super.draw(canvas); 9713522a2e40730a0703fd7f185b7fb9be8ae37ab6Daniel Sandler final int off = (int) (getHeight() - mHandleBarHeight - getPaddingBottom()); 9813522a2e40730a0703fd7f185b7fb9be8ae37ab6Daniel Sandler canvas.translate(0, off); 9913522a2e40730a0703fd7f185b7fb9be8ae37ab6Daniel Sandler mHandleBar.setState(mHandleView.getDrawableState()); 1004d179dc6ccf3eb118767e94b803484abe9552537Chet Haase mHandleBar.draw(canvas); 10113522a2e40730a0703fd7f185b7fb9be8ae37ab6Daniel Sandler canvas.translate(0, -off); 1024d179dc6ccf3eb118767e94b803484abe9552537Chet Haase } 103040c2e4ace25a45bc701821da4fa786e6dd75eadDaniel Sandler 104040c2e4ace25a45bc701821da4fa786e6dd75eadDaniel Sandler @Override 105040c2e4ace25a45bc701821da4fa786e6dd75eadDaniel Sandler public boolean onTouchEvent(MotionEvent event) { 10664161ccb2f3341ebe1675e38a999250c7967d0adChris Wren if (DEBUG_GESTURES) { 10764161ccb2f3341ebe1675e38a999250c7967d0adChris Wren if (event.getActionMasked() != MotionEvent.ACTION_MOVE) { 10864161ccb2f3341ebe1675e38a999250c7967d0adChris Wren EventLog.writeEvent(EventLogTags.SYSUI_NOTIFICATIONPANEL_TOUCH, 10964161ccb2f3341ebe1675e38a999250c7967d0adChris Wren event.getActionMasked(), (int) event.getX(), (int) event.getY()); 11064161ccb2f3341ebe1675e38a999250c7967d0adChris Wren } 11164161ccb2f3341ebe1675e38a999250c7967d0adChris Wren } 112040c2e4ace25a45bc701821da4fa786e6dd75eadDaniel Sandler if (PhoneStatusBar.SETTINGS_DRAG_SHORTCUT && mStatusBar.mHasFlipSettings) { 113040c2e4ace25a45bc701821da4fa786e6dd75eadDaniel Sandler switch (event.getActionMasked()) { 114040c2e4ace25a45bc701821da4fa786e6dd75eadDaniel Sandler case MotionEvent.ACTION_DOWN: 1152017a056624e747ac91f8203728960a27da0b95aDaniel Sandler mOkToFlip = getExpandedHeight() == 0; 116040c2e4ace25a45bc701821da4fa786e6dd75eadDaniel Sandler break; 117040c2e4ace25a45bc701821da4fa786e6dd75eadDaniel Sandler case MotionEvent.ACTION_POINTER_DOWN: 1182017a056624e747ac91f8203728960a27da0b95aDaniel Sandler if (mOkToFlip) { 119040c2e4ace25a45bc701821da4fa786e6dd75eadDaniel Sandler float miny = event.getY(0); 120040c2e4ace25a45bc701821da4fa786e6dd75eadDaniel Sandler float maxy = miny; 121040c2e4ace25a45bc701821da4fa786e6dd75eadDaniel Sandler for (int i=1; i<event.getPointerCount(); i++) { 122040c2e4ace25a45bc701821da4fa786e6dd75eadDaniel Sandler final float y = event.getY(i); 123040c2e4ace25a45bc701821da4fa786e6dd75eadDaniel Sandler if (y < miny) miny = y; 124040c2e4ace25a45bc701821da4fa786e6dd75eadDaniel Sandler if (y > maxy) maxy = y; 125040c2e4ace25a45bc701821da4fa786e6dd75eadDaniel Sandler } 126040c2e4ace25a45bc701821da4fa786e6dd75eadDaniel Sandler if (maxy - miny < mHandleBarHeight) { 127040c2e4ace25a45bc701821da4fa786e6dd75eadDaniel Sandler if (getMeasuredHeight() < mHandleBarHeight) { 128040c2e4ace25a45bc701821da4fa786e6dd75eadDaniel Sandler mStatusBar.switchToSettings(); 129040c2e4ace25a45bc701821da4fa786e6dd75eadDaniel Sandler } else { 130040c2e4ace25a45bc701821da4fa786e6dd75eadDaniel Sandler mStatusBar.flipToSettings(); 131040c2e4ace25a45bc701821da4fa786e6dd75eadDaniel Sandler } 1322017a056624e747ac91f8203728960a27da0b95aDaniel Sandler mOkToFlip = false; 133040c2e4ace25a45bc701821da4fa786e6dd75eadDaniel Sandler } 134040c2e4ace25a45bc701821da4fa786e6dd75eadDaniel Sandler } 135040c2e4ace25a45bc701821da4fa786e6dd75eadDaniel Sandler break; 136040c2e4ace25a45bc701821da4fa786e6dd75eadDaniel Sandler } 137040c2e4ace25a45bc701821da4fa786e6dd75eadDaniel Sandler } 138040c2e4ace25a45bc701821da4fa786e6dd75eadDaniel Sandler return mHandleView.dispatchTouchEvent(event); 139040c2e4ace25a45bc701821da4fa786e6dd75eadDaniel Sandler } 14008d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler} 141