PhoneStatusBarView.java revision a4b7f2f75e7803193429ec1179fb5e2eb1c6fbda
1/* 2 * Copyright (C) 2008 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.phone; 18 19import android.content.Context; 20import android.content.res.Configuration; 21import android.graphics.Canvas; 22import android.graphics.Rect; 23import android.os.SystemClock; 24import android.util.AttributeSet; 25import android.util.Log; 26import android.view.KeyEvent; 27import android.view.MotionEvent; 28import android.view.View; 29import android.view.ViewGroup; 30import android.view.ViewParent; 31import android.view.accessibility.AccessibilityEvent; 32import android.widget.FrameLayout; 33 34import com.android.systemui.R; 35import com.android.systemui.statusbar.BaseStatusBar; 36import com.android.systemui.statusbar.policy.FixedSizeDrawable; 37 38public class PhoneStatusBarView extends FrameLayout { 39 private static final String TAG = "PhoneStatusBarView"; 40 41 static final int DIM_ANIM_TIME = 400; 42 43 PhoneStatusBar mService; 44 boolean mTracking; 45 int mStartX, mStartY; 46 ViewGroup mNotificationIcons; 47 ViewGroup mStatusIcons; 48 49 boolean mNightMode = false; 50 int mStartAlpha = 0, mEndAlpha = 0; 51 long mEndTime = 0; 52 53 Rect mButtonBounds = new Rect(); 54 boolean mCapturingEvents = true; 55 56 public PhoneStatusBarView(Context context, AttributeSet attrs) { 57 super(context, attrs); 58 } 59 60 @Override 61 protected void onFinishInflate() { 62 super.onFinishInflate(); 63 mNotificationIcons = (ViewGroup)findViewById(R.id.notificationIcons); 64 mStatusIcons = (ViewGroup)findViewById(R.id.statusIcons); 65 } 66 67 @Override 68 protected void onAttachedToWindow() { 69 super.onAttachedToWindow(); 70 //mService.onBarViewAttached(); 71 } 72 73 @Override 74 protected void onConfigurationChanged(Configuration newConfig) { 75 super.onConfigurationChanged(newConfig); 76 mService.updateDisplaySize(); 77 boolean nightMode = (newConfig.uiMode & Configuration.UI_MODE_NIGHT_MASK) 78 == Configuration.UI_MODE_NIGHT_YES; 79 if (mNightMode != nightMode) { 80 mNightMode = nightMode; 81 mStartAlpha = getCurAlpha(); 82 mEndAlpha = mNightMode ? 0x80 : 0x00; 83 mEndTime = SystemClock.uptimeMillis() + DIM_ANIM_TIME; 84 invalidate(); 85 } 86 } 87 88 int getCurAlpha() { 89 long time = SystemClock.uptimeMillis(); 90 if (time > mEndTime) { 91 return mEndAlpha; 92 } 93 return mEndAlpha 94 - (int)(((mEndAlpha-mStartAlpha) * (mEndTime-time) / DIM_ANIM_TIME)); 95 } 96 97 @Override 98 protected void onSizeChanged(int w, int h, int oldw, int oldh) { 99 super.onSizeChanged(w, h, oldw, oldh); 100 mService.updateExpandedViewPos(BaseStatusBar.EXPANDED_LEAVE_ALONE); 101 } 102 103 @Override 104 protected void onLayout(boolean changed, int l, int t, int r, int b) { 105 super.onLayout(changed, l, t, r, b); 106 } 107 108 @Override 109 protected void dispatchDraw(Canvas canvas) { 110 super.dispatchDraw(canvas); 111 int alpha = getCurAlpha(); 112 if (alpha != 0) { 113 canvas.drawARGB(alpha, 0, 0, 0); 114 } 115 if (alpha != mEndAlpha) { 116 invalidate(); 117 } 118 } 119 120 /** 121 * Gets the left position of v in this view. Throws if v is not 122 * a child of this. 123 */ 124 private int getViewOffset(View v) { 125 int offset = 0; 126 while (v != this) { 127 offset += v.getLeft(); 128 ViewParent p = v.getParent(); 129 if (v instanceof View) { 130 v = (View)p; 131 } else { 132 throw new RuntimeException(v + " is not a child of " + this); 133 } 134 } 135 return offset; 136 } 137 138 /** 139 * Ensure that, if there is no target under us to receive the touch, 140 * that we process it ourself. This makes sure that onInterceptTouchEvent() 141 * is always called for the entire gesture. 142 */ 143 @Override 144 public boolean onTouchEvent(MotionEvent event) { 145 if (!mCapturingEvents) { 146 return false; 147 } 148 if (event.getAction() != MotionEvent.ACTION_DOWN) { 149 mService.interceptTouchEvent(event); 150 } 151 return true; 152 } 153 154 @Override 155 public boolean onInterceptTouchEvent(MotionEvent event) { 156 if (event.getAction() == MotionEvent.ACTION_DOWN) { 157 if (mButtonBounds.contains((int)event.getX(), (int)event.getY())) { 158 mCapturingEvents = false; 159 return false; 160 } 161 } 162 mCapturingEvents = true; 163 return mService.interceptTouchEvent(event) 164 ? true : super.onInterceptTouchEvent(event); 165 } 166 167 @Override 168 public boolean onRequestSendAccessibilityEvent(View child, AccessibilityEvent event) { 169 if (super.onRequestSendAccessibilityEvent(child, event)) { 170 // The status bar is very small so augment the view that the user is touching 171 // with the content of the status bar a whole. This way an accessibility service 172 // may announce the current item as well as the entire content if appropriate. 173 AccessibilityEvent record = AccessibilityEvent.obtain(); 174 onInitializeAccessibilityEvent(record); 175 dispatchPopulateAccessibilityEvent(record); 176 event.appendRecord(record); 177 return true; 178 } 179 return false; 180 } 181} 182