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