There was a really dumb bug that was causing us to not always apply the new configuration. As a result of fixing this, there were new glithes in the transition between car and regular mode, so further work here to fix that. And since I was actually working during the night and seeing night mode, I noticed how obnoxiously bright the status bar is compared to the car home at night, so it now nicely dims itself when we switch to the night config. Oh and in doing that I also found and fixed a bug in dispatching config changes to a window (where they wouldn't get dispatched if the window didn't resize). FINALLY... tweak the wallpaper enter/exit animations a bit to make them a little smoother. Change-Id: I4e062093cbcfbc919307799a794846db2920216f
193 lines
5.9 KiB
Java
193 lines
5.9 KiB
Java
/*
|
|
* Copyright (C) 2008 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package com.android.server.status;
|
|
|
|
import android.content.Context;
|
|
import android.content.res.Configuration;
|
|
import android.graphics.Canvas;
|
|
import android.os.SystemClock;
|
|
import android.util.AttributeSet;
|
|
import android.view.MotionEvent;
|
|
import android.view.View;
|
|
import android.view.ViewGroup;
|
|
import android.view.ViewParent;
|
|
import android.widget.FrameLayout;
|
|
|
|
import com.android.internal.R;
|
|
|
|
public class StatusBarView extends FrameLayout {
|
|
private static final String TAG = "StatusBarView";
|
|
|
|
static final int DIM_ANIM_TIME = 400;
|
|
|
|
StatusBarService mService;
|
|
boolean mTracking;
|
|
int mStartX, mStartY;
|
|
ViewGroup mNotificationIcons;
|
|
ViewGroup mStatusIcons;
|
|
View mDate;
|
|
FixedSizeDrawable mBackground;
|
|
|
|
boolean mNightMode = false;
|
|
int mStartAlpha = 0, mEndAlpha = 0;
|
|
long mEndTime = 0;
|
|
|
|
public StatusBarView(Context context, AttributeSet attrs) {
|
|
super(context, attrs);
|
|
}
|
|
|
|
@Override
|
|
protected void onFinishInflate() {
|
|
super.onFinishInflate();
|
|
mNotificationIcons = (ViewGroup)findViewById(R.id.notificationIcons);
|
|
mStatusIcons = (ViewGroup)findViewById(R.id.statusIcons);
|
|
mDate = findViewById(R.id.date);
|
|
|
|
mBackground = new FixedSizeDrawable(mDate.getBackground());
|
|
mBackground.setFixedBounds(0, 0, 0, 0);
|
|
mDate.setBackgroundDrawable(mBackground);
|
|
}
|
|
|
|
@Override
|
|
protected void onAttachedToWindow() {
|
|
super.onAttachedToWindow();
|
|
mService.onBarViewAttached();
|
|
}
|
|
|
|
@Override
|
|
protected void onConfigurationChanged(Configuration newConfig) {
|
|
super.onConfigurationChanged(newConfig);
|
|
boolean nightMode = (newConfig.uiMode & Configuration.UI_MODE_NIGHT_MASK)
|
|
== Configuration.UI_MODE_NIGHT_YES;
|
|
if (mNightMode != nightMode) {
|
|
mNightMode = nightMode;
|
|
mStartAlpha = getCurAlpha();
|
|
mEndAlpha = mNightMode ? 0x80 : 0x00;
|
|
mEndTime = SystemClock.uptimeMillis() + DIM_ANIM_TIME;
|
|
invalidate();
|
|
}
|
|
}
|
|
|
|
int getCurAlpha() {
|
|
long time = SystemClock.uptimeMillis();
|
|
if (time > mEndTime) {
|
|
return mEndAlpha;
|
|
}
|
|
return mEndAlpha
|
|
- (int)(((mEndAlpha-mStartAlpha) * (mEndTime-time) / DIM_ANIM_TIME));
|
|
}
|
|
|
|
@Override
|
|
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
|
|
super.onSizeChanged(w, h, oldw, oldh);
|
|
mService.updateExpandedViewPos(StatusBarService.EXPANDED_LEAVE_ALONE);
|
|
}
|
|
|
|
@Override
|
|
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
|
super.onLayout(changed, l, t, r, b);
|
|
|
|
// put the date date view quantized to the icons
|
|
int oldDateRight = mDate.getRight();
|
|
int newDateRight;
|
|
|
|
newDateRight = getDateSize(mNotificationIcons, oldDateRight,
|
|
getViewOffset(mNotificationIcons));
|
|
if (newDateRight < 0) {
|
|
int offset = getViewOffset(mStatusIcons);
|
|
if (oldDateRight < offset) {
|
|
newDateRight = oldDateRight;
|
|
} else {
|
|
newDateRight = getDateSize(mStatusIcons, oldDateRight, offset);
|
|
if (newDateRight < 0) {
|
|
newDateRight = r;
|
|
}
|
|
}
|
|
}
|
|
int max = r - getPaddingRight();
|
|
if (newDateRight > max) {
|
|
newDateRight = max;
|
|
}
|
|
|
|
mDate.layout(mDate.getLeft(), mDate.getTop(), newDateRight, mDate.getBottom());
|
|
mBackground.setFixedBounds(-mDate.getLeft(), -mDate.getTop(), (r-l), (b-t));
|
|
}
|
|
|
|
@Override
|
|
protected void dispatchDraw(Canvas canvas) {
|
|
super.dispatchDraw(canvas);
|
|
int alpha = getCurAlpha();
|
|
if (alpha != 0) {
|
|
canvas.drawARGB(alpha, 0, 0, 0);
|
|
}
|
|
if (alpha != mEndAlpha) {
|
|
invalidate();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gets the left position of v in this view. Throws if v is not
|
|
* a child of this.
|
|
*/
|
|
private int getViewOffset(View v) {
|
|
int offset = 0;
|
|
while (v != this) {
|
|
offset += v.getLeft();
|
|
ViewParent p = v.getParent();
|
|
if (v instanceof View) {
|
|
v = (View)p;
|
|
} else {
|
|
throw new RuntimeException(v + " is not a child of " + this);
|
|
}
|
|
}
|
|
return offset;
|
|
}
|
|
|
|
private int getDateSize(ViewGroup g, int w, int offset) {
|
|
final int N = g.getChildCount();
|
|
for (int i=0; i<N; i++) {
|
|
View v = g.getChildAt(i);
|
|
int l = v.getLeft() + offset;
|
|
int r = v.getRight() + offset;
|
|
if (w >= l && w <= r) {
|
|
return r;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
/**
|
|
* Ensure that, if there is no target under us to receive the touch,
|
|
* that we process it ourself. This makes sure that onInterceptTouchEvent()
|
|
* is always called for the entire gesture.
|
|
*/
|
|
@Override
|
|
public boolean onTouchEvent(MotionEvent event) {
|
|
if (event.getAction() != MotionEvent.ACTION_DOWN) {
|
|
mService.interceptTouchEvent(event);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public boolean onInterceptTouchEvent(MotionEvent event) {
|
|
return mService.interceptTouchEvent(event)
|
|
? true : super.onInterceptTouchEvent(event);
|
|
}
|
|
}
|
|
|