1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.systemui.statusbar.tablet; 18 19import com.android.systemui.R; 20import com.android.systemui.statusbar.BaseStatusBar; 21import com.android.systemui.statusbar.DelegateViewHelper; 22 23import android.content.Context; 24import android.os.Handler; 25import android.util.AttributeSet; 26import android.util.Slog; 27import android.view.View; 28import android.view.MotionEvent; 29import android.widget.FrameLayout; 30 31public class TabletStatusBarView extends FrameLayout { 32 private Handler mHandler; 33 34 private final int MAX_PANELS = 5; 35 private final View[] mIgnoreChildren = new View[MAX_PANELS]; 36 private final View[] mPanels = new View[MAX_PANELS]; 37 private final int[] mPos = new int[2]; 38 private DelegateViewHelper mDelegateHelper; 39 40 public TabletStatusBarView(Context context) { 41 this(context, null); 42 } 43 44 public TabletStatusBarView(Context context, AttributeSet attrs) { 45 super(context, attrs); 46 mDelegateHelper = new DelegateViewHelper(this); 47 } 48 49 public void setDelegateView(View view) { 50 mDelegateHelper.setDelegateView(view); 51 } 52 53 public void setBar(BaseStatusBar phoneStatusBar) { 54 mDelegateHelper.setBar(phoneStatusBar); 55 } 56 57 @Override 58 public boolean onTouchEvent(MotionEvent event) { 59 if (mDelegateHelper != null) { 60 mDelegateHelper.onInterceptTouchEvent(event); 61 } 62 return true; 63 } 64 65 @Override 66 protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 67 super.onLayout(changed, left, top, right, bottom); 68 // Find the view we wish to grab events from in order to detect search gesture. 69 // Depending on the device, this will be one of the id's listed below. 70 // If we don't find one, we'll use the view provided in the constructor above (this view). 71 View view = findViewById(R.id.navigationArea); 72 if (view == null) { 73 view = findViewById(R.id.nav_buttons); 74 } 75 mDelegateHelper.setSourceView(view); 76 mDelegateHelper.setInitialTouchRegion(view); 77 } 78 79 @Override 80 public boolean onInterceptTouchEvent(MotionEvent ev) { 81 if (ev.getAction() == MotionEvent.ACTION_DOWN) { 82 if (TabletStatusBar.DEBUG) { 83 Slog.d(TabletStatusBar.TAG, "TabletStatusBarView intercepting touch event: " + ev); 84 } 85 // do not close the recents panel here- the intended behavior is that recents is dismissed 86 // on touch up when clicking on status bar buttons 87 // TODO: should we be closing the notification panel and input methods panel? 88 mHandler.removeMessages(TabletStatusBar.MSG_CLOSE_NOTIFICATION_PANEL); 89 mHandler.sendEmptyMessage(TabletStatusBar.MSG_CLOSE_NOTIFICATION_PANEL); 90 mHandler.removeMessages(TabletStatusBar.MSG_CLOSE_INPUT_METHODS_PANEL); 91 mHandler.sendEmptyMessage(TabletStatusBar.MSG_CLOSE_INPUT_METHODS_PANEL); 92 mHandler.removeMessages(TabletStatusBar.MSG_STOP_TICKER); 93 mHandler.sendEmptyMessage(TabletStatusBar.MSG_STOP_TICKER); 94 95 for (int i=0; i < mPanels.length; i++) { 96 if (mPanels[i] != null && mPanels[i].getVisibility() == View.VISIBLE) { 97 if (eventInside(mIgnoreChildren[i], ev)) { 98 if (TabletStatusBar.DEBUG) { 99 Slog.d(TabletStatusBar.TAG, 100 "TabletStatusBarView eating event for view: " 101 + mIgnoreChildren[i]); 102 } 103 return true; 104 } 105 } 106 } 107 } 108 if (TabletStatusBar.DEBUG) { 109 Slog.d(TabletStatusBar.TAG, "TabletStatusBarView not intercepting event"); 110 } 111 if (mDelegateHelper != null && mDelegateHelper.onInterceptTouchEvent(ev)) { 112 return true; 113 } 114 return super.onInterceptTouchEvent(ev); 115 } 116 117 private boolean eventInside(View v, MotionEvent ev) { 118 // assume that x and y are window coords because we are. 119 final int x = (int)ev.getX(); 120 final int y = (int)ev.getY(); 121 122 final int[] p = mPos; 123 v.getLocationInWindow(p); 124 125 final int l = p[0]; 126 final int t = p[1]; 127 final int r = p[0] + v.getWidth(); 128 final int b = p[1] + v.getHeight(); 129 130 return x >= l && x < r && y >= t && y < b; 131 } 132 133 public void setHandler(Handler h) { 134 mHandler = h; 135 } 136 137 /** 138 * Let the status bar know that if you tap on ignore while panel is showing, don't do anything. 139 * 140 * Debounces taps on, say, a popup's trigger when the popup is already showing. 141 */ 142 public void setIgnoreChildren(int index, View ignore, View panel) { 143 mIgnoreChildren[index] = ignore; 144 mPanels[index] = panel; 145 } 146} 147