diff --git a/Android.mk b/Android.mk index c71be23e8d6ac..54ce115ea1cd5 100644 --- a/Android.mk +++ b/Android.mk @@ -86,8 +86,6 @@ LOCAL_SRC_FILES += \ core/java/android/app/ISearchManager.aidl \ core/java/android/app/ISearchManagerCallback.aidl \ core/java/android/app/IServiceConnection.aidl \ - core/java/android/app/IStatusBar.aidl \ - core/java/android/app/IStatusBarService.aidl \ core/java/android/app/IThumbnailReceiver.aidl \ core/java/android/app/ITransientNotification.aidl \ core/java/android/app/IUiModeManager.aidl \ @@ -156,6 +154,8 @@ LOCAL_SRC_FILES += \ core/java/com/android/internal/backup/IBackupTransport.aidl \ core/java/com/android/internal/os/IDropBoxManagerService.aidl \ core/java/com/android/internal/os/IResultReceiver.aidl \ + core/java/com/android/internal/statusbar/IStatusBar.aidl \ + core/java/com/android/internal/statusbar/IStatusBarService.aidl \ core/java/com/android/internal/view/IInputContext.aidl \ core/java/com/android/internal/view/IInputContextCallback.aidl \ core/java/com/android/internal/view/IInputMethod.aidl \ diff --git a/CleanSpec.mk b/CleanSpec.mk index 6455103a91632..26d8a1b11d021 100644 --- a/CleanSpec.mk +++ b/CleanSpec.mk @@ -53,6 +53,7 @@ $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framew $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/FrameworkTest_intermediates/) $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/android.policy*) $(call add-clean-step, rm -rf $(TARGET_OUT_JAVA_LIBRARIES)/android.policy.jar) +$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates) # ************************************************ diff --git a/core/java/android/app/StatusBarManager.java b/core/java/android/app/StatusBarManager.java index 746b2d50a676c..8905268a8f91f 100644 --- a/core/java/android/app/StatusBarManager.java +++ b/core/java/android/app/StatusBarManager.java @@ -23,6 +23,8 @@ import android.os.RemoteException; import android.os.IBinder; import android.os.ServiceManager; +import com.android.internal.statusbar.IStatusBarService; + /** * Allows an app to control the status bar. * @@ -116,27 +118,18 @@ public class StatusBarManager { } } - public IBinder addIcon(String slot, int iconId, int iconLevel) { + public void setIcon(String slot, int iconId, int iconLevel) { try { - return mService.addIcon(slot, mContext.getPackageName(), iconId, iconLevel); + mService.setIcon(slot, mContext.getPackageName(), iconId, iconLevel); } catch (RemoteException ex) { // system process is dead anyway. throw new RuntimeException(ex); } } - public void updateIcon(IBinder key, String slot, int iconId, int iconLevel) { + public void removeIcon(String slot) { try { - mService.updateIcon(key, slot, mContext.getPackageName(), iconId, iconLevel); - } catch (RemoteException ex) { - // system process is dead anyway. - throw new RuntimeException(ex); - } - } - - public void removeIcon(IBinder key) { - try { - mService.removeIcon(key); + mService.removeIcon(slot); } catch (RemoteException ex) { // system process is dead anyway. throw new RuntimeException(ex); diff --git a/core/java/android/app/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl similarity index 75% rename from core/java/android/app/IStatusBar.aidl rename to core/java/com/android/internal/statusbar/IStatusBar.aidl index 8d571efde7634..2a5ae1565df5a 100644 --- a/core/java/android/app/IStatusBar.aidl +++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl @@ -14,10 +14,14 @@ * limitations under the License. */ -package android.app; +package com.android.internal.statusbar; + +import com.android.internal.statusbar.StatusBarIcon; /** @hide */ -interface IStatusBar +oneway interface IStatusBar { + void setIcon(int index, in StatusBarIcon icon); + void removeIcon(int index); } diff --git a/core/java/android/app/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl similarity index 66% rename from core/java/android/app/IStatusBarService.aidl rename to core/java/com/android/internal/statusbar/IStatusBarService.aidl index ccde41a502a31..0a9c8da5a6692 100644 --- a/core/java/android/app/IStatusBarService.aidl +++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl @@ -14,9 +14,11 @@ * limitations under the License. */ -package android.app; +package com.android.internal.statusbar; -import android.app.IStatusBar; +import com.android.internal.statusbar.IStatusBar; +import com.android.internal.statusbar.StatusBarIcon; +import com.android.internal.statusbar.StatusBarIconList; /** @hide */ interface IStatusBarService @@ -25,10 +27,10 @@ interface IStatusBarService void deactivate(); void toggle(); void disable(int what, IBinder token, String pkg); - IBinder addIcon(String slot, String iconPackage, int iconId, int iconLevel); - void updateIcon(IBinder key, String slot, String iconPackage, int iconId, int iconLevel); - void removeIcon(IBinder key); + void setIcon(String slot, String iconPackage, int iconId, int iconLevel); + void setIconVisibility(String slot, boolean visible); + void removeIcon(String slot); // ---- Methods below are for use by the status bar policy services ---- - void registerStatusBar(IStatusBar callbacks); + void registerStatusBar(IStatusBar callbacks, out StatusBarIconList state); } diff --git a/core/java/com/android/internal/statusbar/StatusBarIcon.aidl b/core/java/com/android/internal/statusbar/StatusBarIcon.aidl new file mode 100644 index 0000000000000..311a0770ad366 --- /dev/null +++ b/core/java/com/android/internal/statusbar/StatusBarIcon.aidl @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2010, 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.internal.statusbar; + +parcelable StatusBarIcon; + diff --git a/core/java/com/android/internal/statusbar/StatusBarIcon.java b/core/java/com/android/internal/statusbar/StatusBarIcon.java new file mode 100644 index 0000000000000..330b40737f455 --- /dev/null +++ b/core/java/com/android/internal/statusbar/StatusBarIcon.java @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2010 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.internal.statusbar; + +import android.os.Parcel; +import android.os.Parcelable; + +/** + * @hide + */ +public class StatusBarIcon implements Parcelable { + public String iconPackage; + public int iconId; + public int iconLevel; + + private StatusBarIcon() { + } + + public StatusBarIcon(String iconPackage, int iconId, int iconLevel) { + this.iconPackage = iconPackage; + this.iconId = iconId; + this.iconLevel = iconLevel; + } + + public StatusBarIcon clone() { + return new StatusBarIcon(this.iconPackage, this.iconId, this.iconLevel); + } + + /** + * Unflatten the StatusBarIcon from a parcel. + */ + public StatusBarIcon(Parcel in) { + readFromParcel(in); + } + + public void readFromParcel(Parcel in) { + this.iconPackage = in.readString(); + this.iconId = in.readInt(); + this.iconLevel = in.readInt(); + } + + public void writeToParcel(Parcel out, int flags) { + out.writeString(this.iconPackage); + out.writeInt(this.iconId); + out.writeInt(this.iconLevel); + } + + public int describeContents() { + return 0; + } + + /** + * Parcelable.Creator that instantiates StatusBarIcon objects + */ + public static final Parcelable.Creator CREATOR + = new Parcelable.Creator() + { + public StatusBarIcon createFromParcel(Parcel parcel) + { + return new StatusBarIcon(parcel); + } + + public StatusBarIcon[] newArray(int size) + { + return new StatusBarIcon[size]; + } + }; +} + diff --git a/core/java/com/android/internal/statusbar/StatusBarIconList.aidl b/core/java/com/android/internal/statusbar/StatusBarIconList.aidl new file mode 100644 index 0000000000000..c745120500922 --- /dev/null +++ b/core/java/com/android/internal/statusbar/StatusBarIconList.aidl @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2010, 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.internal.statusbar; + +parcelable StatusBarIconList; + diff --git a/core/java/com/android/internal/statusbar/StatusBarIconList.java b/core/java/com/android/internal/statusbar/StatusBarIconList.java new file mode 100644 index 0000000000000..61002d5703fed --- /dev/null +++ b/core/java/com/android/internal/statusbar/StatusBarIconList.java @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2007 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.internal.statusbar; + +import android.os.Parcel; +import android.os.Parcelable; + +import java.io.PrintWriter; + +public class StatusBarIconList implements Parcelable { + private String[] mSlots; + private StatusBarIcon[] mIcons; + + public StatusBarIconList() { + } + + public StatusBarIconList(Parcel in) { + readFromParcel(in); + } + + public void readFromParcel(Parcel in) { + this.mSlots = in.readStringArray(); + final int N = in.readInt(); + if (N < 0) { + mIcons = null; + } else { + mIcons = new StatusBarIcon[N]; + for (int i=0; i CREATOR + = new Parcelable.Creator() + { + public StatusBarIconList createFromParcel(Parcel parcel) + { + return new StatusBarIconList(parcel); + } + + public StatusBarIconList[] newArray(int size) + { + return new StatusBarIconList[size]; + } + }; + + public void defineSlots(String[] slots) { + final int N = slots.length; + String[] s = mSlots = new String[N]; + for (int i=0; i - - - - - - diff --git a/core/res/res/layout/status_bar_expanded.xml b/core/res/res/layout/status_bar_expanded.xml deleted file mode 100644 index 68eb9222bb4b4..0000000000000 --- a/core/res/res/layout/status_bar_expanded.xml +++ /dev/null @@ -1,144 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/core/res/res/layout/status_bar_tracking.xml b/core/res/res/layout/status_bar_tracking.xml deleted file mode 100644 index c0a7a977545f9..0000000000000 --- a/core/res/res/layout/status_bar_tracking.xml +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - - - - - - - diff --git a/packages/StatusBarPhone/res/drawable-hdpi/ic_notification_overlay.9.png b/packages/StatusBarPhone/res/drawable-hdpi/ic_notification_overlay.9.png new file mode 100644 index 0000000000000..744178f1abeb2 Binary files /dev/null and b/packages/StatusBarPhone/res/drawable-hdpi/ic_notification_overlay.9.png differ diff --git a/packages/StatusBarPhone/res/drawable-mdpi/ic_notification_overlay.9.png b/packages/StatusBarPhone/res/drawable-mdpi/ic_notification_overlay.9.png new file mode 100644 index 0000000000000..1a3063c4b3fdd Binary files /dev/null and b/packages/StatusBarPhone/res/drawable-mdpi/ic_notification_overlay.9.png differ diff --git a/packages/StatusBarPhone/res/layout/status_bar.xml b/packages/StatusBarPhone/res/layout/status_bar.xml index 2237ee43b7163..418d383c98bea 100644 --- a/packages/StatusBarPhone/res/layout/status_bar.xml +++ b/packages/StatusBarPhone/res/layout/status_bar.xml @@ -19,7 +19,7 @@ --> - - - - - - + - - + diff --git a/packages/StatusBarPhone/res/layout/status_bar_expanded.xml b/packages/StatusBarPhone/res/layout/status_bar_expanded.xml index 30138a742c74d..26d7a07aa83cc 100644 --- a/packages/StatusBarPhone/res/layout/status_bar_expanded.xml +++ b/packages/StatusBarPhone/res/layout/status_bar_expanded.xml @@ -18,7 +18,7 @@ */ --> - - - + - + diff --git a/core/res/res/layout/status_bar_icon.xml b/packages/StatusBarPhone/res/layout/status_bar_icon.xml similarity index 95% rename from core/res/res/layout/status_bar_icon.xml rename to packages/StatusBarPhone/res/layout/status_bar_icon.xml index 05367923c3975..cba5de7533e95 100644 --- a/core/res/res/layout/status_bar_icon.xml +++ b/packages/StatusBarPhone/res/layout/status_bar_icon.xml @@ -25,7 +25,7 @@ android:layout_height="25dp" > - diff --git a/packages/StatusBarPhone/res/layout/status_bar_tracking.xml b/packages/StatusBarPhone/res/layout/status_bar_tracking.xml index c0a7a977545f9..3866a313e9ea6 100644 --- a/packages/StatusBarPhone/res/layout/status_bar_tracking.xml +++ b/packages/StatusBarPhone/res/layout/status_bar_tracking.xml @@ -15,7 +15,8 @@ limitations under the License. --> - - - - + - + diff --git a/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/CommandQueue.java b/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/CommandQueue.java new file mode 100644 index 0000000000000..b21f65dde9f4e --- /dev/null +++ b/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/CommandQueue.java @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2010 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.policy.statusbar.phone; + +import android.os.Handler; +import android.os.Message; + +import com.android.internal.statusbar.IStatusBar; +import com.android.internal.statusbar.StatusBarIcon; +import com.android.internal.statusbar.StatusBarIconList; + +class CommandQueue extends IStatusBar.Stub { + + private static final int MSG_MASK = 0xffff0000; + private static final int INDEX_MASK = 0x0000ffff; + + private static final int MSG_ICON = 0x00010000; + private static final int OP_SET_ICON = 1; + private static final int OP_REMOVE_ICON = 2; + + private StatusBarIconList mList; + private Callbacks mCallbacks; + private Handler mHandler = new H(); + + /** + * These methods are called back on the main thread. + */ + public interface Callbacks { + public void addIcon(String slot, int index, int viewIndex, StatusBarIcon icon); + public void updateIcon(String slot, int index, int viewIndex, + StatusBarIcon old, StatusBarIcon icon); + public void removeIcon(String slot, int index, int viewIndex); + } + + public CommandQueue(Callbacks callbacks, StatusBarIconList list) { + mCallbacks = callbacks; + mList = list; + } + + public void setIcon(int index, StatusBarIcon icon) { + synchronized (mList) { + int what = MSG_ICON | index; + mHandler.removeMessages(what); + mHandler.obtainMessage(what, OP_SET_ICON, 0, icon.clone()).sendToTarget(); + } + } + + public void removeIcon(int index) { + synchronized (mList) { + int what = MSG_ICON | index; + mHandler.removeMessages(what); + mHandler.obtainMessage(what, OP_REMOVE_ICON, 0, null).sendToTarget(); + } + } + + private final class H extends Handler { + public void handleMessage(Message msg) { + int what = msg.what & MSG_MASK; + switch (msg.what) { + case MSG_ICON: { + int index = msg.what & INDEX_MASK; + int viewIndex = mList.getViewIndex(index); + switch (msg.arg1) { + case OP_SET_ICON: { + StatusBarIcon icon = (StatusBarIcon)msg.obj; + StatusBarIcon old = mList.getIcon(index); + if (old == null) { + mList.setIcon(index, icon); + mCallbacks.addIcon(mList.getSlot(index), index, viewIndex, icon); + } else { + mList.setIcon(index, icon); + mCallbacks.updateIcon(mList.getSlot(index), index, viewIndex, + old, icon); + } + break; + } + case OP_REMOVE_ICON: + mList.removeIcon(index); + mCallbacks.removeIcon(mList.getSlot(index), index, viewIndex); + break; + } + break; + } + } + } + } +} + + diff --git a/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/IconMerger.java b/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/IconMerger.java index 8fcd36fe04d1c..d426be24e2376 100644 --- a/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/IconMerger.java +++ b/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/IconMerger.java @@ -24,7 +24,7 @@ import android.widget.LinearLayout; public class IconMerger extends LinearLayout { PhoneStatusBarService service; - StatusBarIcon moreIcon; + StatusBarIconData moreIcon; public IconMerger(Context context, AttributeSet attrs) { super(context, attrs); @@ -33,6 +33,9 @@ public class IconMerger extends LinearLayout { @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(changed, l, t, r, b); + if (true) { + return; + } final int maxWidth = r - l; final int N = getChildCount(); @@ -90,7 +93,7 @@ public class IconMerger extends LinearLayout { if (childLeft < breakingPoint) { // hide this one child.layout(0, child.getTop(), 0, child.getBottom()); - int n = this.service.getIconNumberForView(child); + int n = 0; // XXX this.service.getIconNumberForView(child); if (n == 0) { number += 1; } else if (n > 0) { diff --git a/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/PhoneStatusBarService.java b/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/PhoneStatusBarService.java index daed2eff42698..5614203b8fa1b 100644 --- a/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/PhoneStatusBarService.java +++ b/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/PhoneStatusBarService.java @@ -17,11 +17,12 @@ package com.android.policy.statusbar.phone; import com.android.internal.util.CharSequences; +import com.android.internal.statusbar.IStatusBar; +import com.android.internal.statusbar.IStatusBarService; +import com.android.internal.statusbar.StatusBarIcon; import android.app.ActivityManagerNative; import android.app.Dialog; -import android.app.IStatusBar; -import android.app.IStatusBarService; import android.app.PendingIntent; import android.app.Service; import android.app.StatusBarManager; @@ -82,22 +83,6 @@ public class PhoneStatusBarService extends StatusBarService { private static final int MSG_ANIMATE = 1000; private static final int MSG_ANIMATE_REVEAL = 1001; - private static final int OP_ADD_ICON = 1; - private static final int OP_UPDATE_ICON = 2; - private static final int OP_REMOVE_ICON = 3; - private static final int OP_SET_VISIBLE = 4; - private static final int OP_EXPAND = 5; - private static final int OP_TOGGLE = 6; - private static final int OP_DISABLE = 7; - private class PendingOp { - IBinder key; - int code; - IconData iconData; - NotificationData notificationData; - boolean visible; - int integer; - } - private class DisableRecord implements IBinder.DeathRecipient { String pkg; int what; @@ -136,12 +121,14 @@ public class PhoneStatusBarService extends StatusBarService { } } - final Display mDisplay; + int mHeight; + int mIconWidth; + + Display mDisplay; StatusBarView mStatusBarView; int mPixelFormat; H mHandler = new H(); Object mQueueLock = new Object(); - ArrayList mQueue = new ArrayList(); NotificationCallbacks mNotificationCallbacks; // All accesses to mIconMap and mNotificationData are syncronized on those objects, @@ -150,14 +137,13 @@ public class PhoneStatusBarService extends StatusBarService { // reads and require them to not be modified. // icons - HashMap mIconMap = new HashMap(); - ArrayList mIconList = new ArrayList(); + HashMap mIconMap = new HashMap(); + ArrayList mIconList = new ArrayList(); String[] mRightIconSlots; - StatusBarIcon[] mRightIcons; + StatusBarIconData[] mRightIcons; LinearLayout mIcons; IconMerger mNotificationIcons; LinearLayout mStatusIcons; - StatusBarIcon mMoreIcon; private UninstallReceiver mUninstallReceiver; // expanded notifications @@ -219,11 +205,15 @@ public class PhoneStatusBarService extends StatusBarService { /** * Construct the service, add the status bar view to the window manager */ - public PhoneStatusBarService(Context context) { - mDisplay = ((WindowManager)context.getSystemService( - Context.WINDOW_SERVICE)).getDefaultDisplay(); - makeStatusBarView(context); + @Override + public void onCreate() { + // First set up our views and stuff. + mDisplay = ((WindowManager)getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); + makeStatusBarView(this); mUninstallReceiver = new UninstallReceiver(); + + // Next, call super.onCreate(), which will populate our views. + super.onCreate(); } public void setNotificationCallbacks(NotificationCallbacks listener) { @@ -236,10 +226,13 @@ public class PhoneStatusBarService extends StatusBarService { private void makeStatusBarView(Context context) { Resources res = context.getResources(); mRightIconSlots = res.getStringArray(R.array.status_bar_icon_order); - mRightIcons = new StatusBarIcon[mRightIconSlots.length]; + mRightIcons = new StatusBarIconData[mRightIconSlots.length]; + + mHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height); + mIconWidth = mHeight; ExpandedView expanded = (ExpandedView)View.inflate(context, - com.android.internal.R.layout.status_bar_expanded, null); + R.layout.status_bar_expanded, null); expanded.mService = this; StatusBarView sb = (StatusBarView)View.inflate(context, R.layout.status_bar, null); sb.mService = this; @@ -282,21 +275,12 @@ public class PhoneStatusBarService extends StatusBarService { TickerView tickerView = (TickerView)sb.findViewById(R.id.tickerText); tickerView.mTicker = mTicker; - mTrackingView = (TrackingView)View.inflate(context, - com.android.internal.R.layout.status_bar_tracking, null); + mTrackingView = (TrackingView)View.inflate(context, R.layout.status_bar_tracking, null); mTrackingView.mService = this; mCloseView = (CloseDragHandle)mTrackingView.findViewById(R.id.close); mCloseView.mService = this; - mEdgeBorder = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_edge_ignore); - - // add the more icon for the notifications - IconData moreData = IconData.makeIcon(null, context.getPackageName(), - R.drawable.stat_notify_more, 0, 42); - mMoreIcon = new StatusBarIcon(context, moreData, mNotificationIcons); - mMoreIcon.view.setId(R.drawable.stat_notify_more); - mNotificationIcons.moreIcon = mMoreIcon; - mNotificationIcons.addView(mMoreIcon.view); + mEdgeBorder = res.getDimensionPixelSize(R.dimen.status_bar_edge_ignore); // set the inital view visibility setAreThereNotifications(); @@ -319,17 +303,14 @@ public class PhoneStatusBarService extends StatusBarService { @Override protected void addStatusBarView() { - final View view = new View(this); - - // TODO final StatusBarView view = mStatusBarView; + final StatusBarView view = mStatusBarView; WindowManager.LayoutParams lp = new WindowManager.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, - view.getContext().getResources().getDimensionPixelSize( - com.android.internal.R.dimen.status_bar_height), + mHeight, WindowManager.LayoutParams.TYPE_STATUS_BAR, - WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE| - WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING, - PixelFormat.RGB_888); + WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE + | WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING, + PixelFormat.RGBX_8888); lp.gravity = Gravity.TOP | Gravity.FILL_HORIZONTAL; lp.setTitle("StatusBar"); // TODO lp.windowAnimations = R.style.Animation_StatusBar; @@ -338,415 +319,42 @@ public class PhoneStatusBarService extends StatusBarService { } // ================================================================================ - // From IStatusBarService + // Always called from the UI thread. // ================================================================================ - public void activate() { - enforceExpandStatusBar(); - addPendingOp(OP_EXPAND, null, true); + + public void addIcon(String slot, int index, int viewIndex, StatusBarIcon icon) { + Slog.d(TAG, "addIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex + + " icon=" + icon); + StatusBarIconView view = new StatusBarIconView(this, slot); + view.set(icon); + mStatusIcons.addView(view, viewIndex, new LinearLayout.LayoutParams(mIconWidth, mHeight)); } - public void deactivate() { - enforceExpandStatusBar(); - addPendingOp(OP_EXPAND, null, false); + public void updateIcon(String slot, int index, int viewIndex, + StatusBarIcon old, StatusBarIcon icon) { + Slog.d(TAG, "updateIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex + + " old=" + old + " icon=" + icon); + StatusBarIconView view = (StatusBarIconView)mStatusIcons.getChildAt(viewIndex); + view.set(icon); } - public void toggle() { - enforceExpandStatusBar(); - addPendingOp(OP_TOGGLE, null, false); - } - - public void disable(int what, IBinder token, String pkg) { - enforceStatusBar(); - synchronized (mNotificationCallbacks) { - // This is a little gross, but I think it's safe as long as nobody else - // synchronizes on mNotificationCallbacks. It's important that the the callback - // and the pending op get done in the correct order and not interleaved with - // other calls, otherwise they'll get out of sync. - int net; - synchronized (mDisableRecords) { - manageDisableListLocked(what, token, pkg); - net = gatherDisableActionsLocked(); - mNotificationCallbacks.onSetDisabled(net); - } - addPendingOp(OP_DISABLE, net); - } - } - - public IBinder addIcon(String slot, String iconPackage, int iconId, int iconLevel) { - enforceStatusBar(); - return addIcon(IconData.makeIcon(slot, iconPackage, iconId, iconLevel, 0), null); - } - - public void updateIcon(IBinder key, - String slot, String iconPackage, int iconId, int iconLevel) { - enforceStatusBar(); - updateIcon(key, IconData.makeIcon(slot, iconPackage, iconId, iconLevel, 0), null); - } - - public void removeIcon(IBinder key) { - enforceStatusBar(); - addPendingOp(OP_REMOVE_ICON, key, null, null, -1); - } - - private void enforceStatusBar() { - enforceCallingOrSelfPermission( - android.Manifest.permission.STATUS_BAR, - "PhoneStatusBarService"); - } - - private void enforceExpandStatusBar() { - enforceCallingOrSelfPermission( - android.Manifest.permission.EXPAND_STATUS_BAR, - "PhoneStatusBarService"); - } - - public void registerStatusBar(IStatusBar bar) { - Slog.d(TAG, "registerStatusBar bar=" + bar); + public void removeIcon(String slot, int index, int viewIndex) { + Slog.d(TAG, "removeIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex); + mStatusIcons.removeViewAt(viewIndex); } - - // ================================================================================ - // Can be called from any thread - // ================================================================================ - public IBinder addIcon(IconData data, NotificationData n) { - // TODO: Call onto the IStatusBar - int slot; - // assert early-on if they using a slot that doesn't exist. - if (data != null && n == null) { - slot = getRightIconIndex(data.slot); - if (slot < 0) { - throw new SecurityException("invalid status bar icon slot: " - + (data.slot != null ? "'" + data.slot + "'" : "null")); - } - } else { - slot = -1; - } - IBinder key = new Binder(); - addPendingOp(OP_ADD_ICON, key, data, n, -1); - return key; - } - - public void updateIcon(IBinder key, IconData data, NotificationData n) { - addPendingOp(OP_UPDATE_ICON, key, data, n, -1); - } - - public void setIconVisibility(IBinder key, boolean visible) { - addPendingOp(OP_SET_VISIBLE, key, visible); - } - - private void addPendingOp(int code, IBinder key, IconData data, NotificationData n, int i) { - synchronized (mQueueLock) { - PendingOp op = new PendingOp(); - op.key = key; - op.code = code; - op.iconData = data == null ? null : data.clone(); - op.notificationData = n; - op.integer = i; - mQueue.add(op); - if (mQueue.size() == 1) { - mHandler.sendEmptyMessage(2); - } - } - } - - private void addPendingOp(int code, IBinder key, boolean visible) { - synchronized (mQueueLock) { - PendingOp op = new PendingOp(); - op.key = key; - op.code = code; - op.visible = visible; - mQueue.add(op); - if (mQueue.size() == 1) { - mHandler.sendEmptyMessage(1); - } - } - } - - private void addPendingOp(int code, int integer) { - synchronized (mQueueLock) { - PendingOp op = new PendingOp(); - op.code = code; - op.integer = integer; - mQueue.add(op); - if (mQueue.size() == 1) { - mHandler.sendEmptyMessage(1); - } - } - } - - // lock on mDisableRecords - void manageDisableListLocked(int what, IBinder token, String pkg) { - if (SPEW) { - Slog.d(TAG, "manageDisableList what=0x" + Integer.toHexString(what) - + " pkg=" + pkg); - } - // update the list - synchronized (mDisableRecords) { - final int N = mDisableRecords.size(); - DisableRecord tok = null; - int i; - for (i=0; i queue; - synchronized (mQueueLock) { - queue = mQueue; - mQueue = new ArrayList(); - } - - boolean wasExpanded = mExpanded; - - // for each one in the queue, find all of the ones with the same key - // and collapse that down into a final op and/or call to setVisibility, etc - boolean expand = wasExpanded; - boolean doExpand = false; - boolean doDisable = false; - int disableWhat = 0; - int N = queue.size(); - while (N > 0) { - PendingOp op = queue.get(0); - boolean doOp = false; - boolean visible = false; - boolean doVisibility = false; - if (op.code == OP_SET_VISIBLE) { - doVisibility = true; - visible = op.visible; - } - else if (op.code == OP_EXPAND) { - doExpand = true; - expand = op.visible; - } - else if (op.code == OP_TOGGLE) { - doExpand = true; - expand = !expand; - } - else { - doOp = true; - } - - if (alwaysHandle(op.code)) { - // coalesce these - for (int i=1; i keys = mIconMap.keySet(); int i=0; for (IBinder key: keys) { - StatusBarIcon icon = mIconMap.get(key); + StatusBarIconData icon = mIconMap.get(key); pw.println(" [" + i + "] key=" + key); pw.println(" data=" + icon.mData); i++; @@ -1681,6 +1235,10 @@ public class PhoneStatusBarService extends StatusBarService { */ private boolean mPanelSlightlyVisible; void panelSlightlyVisible(boolean visible) { + if (true) { + // XXX + return; + } if (mPanelSlightlyVisible != visible) { mPanelSlightlyVisible = visible; if (visible) { @@ -1727,7 +1285,7 @@ public class PhoneStatusBarService extends StatusBarService { private View.OnClickListener mClearButtonListener = new View.OnClickListener() { public void onClick(View v) { mNotificationCallbacks.onClearAll(); - addPendingOp(OP_EXPAND, null, false); + //addPendingOp(OP_EXPAND, null, false); } }; @@ -1865,7 +1423,7 @@ public class PhoneStatusBarService extends StatusBarService { if (list != null) { final int N = list.size(); for (int i=0; i 0) { nv.setText("" + data.number); diff --git a/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/StatusBarIconView.java b/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/StatusBarIconView.java new file mode 100644 index 0000000000000..96d663c336fc5 --- /dev/null +++ b/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/StatusBarIconView.java @@ -0,0 +1,104 @@ +/* + * 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.policy.statusbar.phone; + +import android.content.Context; +import android.content.pm.PackageManager; +import android.content.res.Resources; +import android.graphics.drawable.Drawable; +import android.graphics.Canvas; +import android.util.Slog; +import android.view.ViewDebug; +import android.widget.FrameLayout; + +import com.android.internal.statusbar.StatusBarIcon; + +public class StatusBarIconView extends AnimatedImageView { + private static final String TAG = "StatusBarIconView"; + + private StatusBarIcon mIcon; + @ViewDebug.ExportedProperty private String mSlot; + + public StatusBarIconView(Context context, String slot) { + super(context); + mSlot = slot; + } + + private static boolean streq(String a, String b) { + if (a == null && b != null) { + return false; + } + if (a != null && b == null) { + return false; + } + return a.equals(b); + } + + public void set(StatusBarIcon icon) { + final boolean iconEquals = mIcon != null + && streq(mIcon.iconPackage, icon.iconPackage) + && mIcon.iconId == icon.iconId; + final boolean levelEquals = iconEquals + && mIcon.iconLevel == icon.iconLevel; + if (!iconEquals) { + setImageDrawable(getIcon(icon)); + } + if (!levelEquals) { + setImageLevel(icon.iconLevel); + } + mIcon = icon.clone(); + } + + /** + * Returns the right icon to use for this item, respecting the iconId and + * iconPackage (if set) + * + * @param context Context to use to get resources if iconPackage is not set + * @return Drawable for this item, or null if the package or item could not + * be found + */ + private Drawable getIcon(StatusBarIcon icon) { + Context context = getContext(); + Resources r = null; + + if (icon.iconPackage != null) { + try { + r = context.getPackageManager().getResourcesForApplication(icon.iconPackage); + } catch (PackageManager.NameNotFoundException ex) { + Slog.e(PhoneStatusBarService.TAG, "Icon package not found: "+icon.iconPackage, ex); + return null; + } + } else { + r = context.getResources(); + } + + if (icon.iconId == 0) { + Slog.w(PhoneStatusBarService.TAG, "No icon ID for slot " + mSlot); + return null; + } + + try { + return r.getDrawable(icon.iconId); + } catch (RuntimeException e) { + Slog.w(PhoneStatusBarService.TAG, "Icon not found in " + + (icon.iconPackage != null ? icon.iconId : "") + + ": " + Integer.toHexString(icon.iconId)); + } + + return null; + } +} diff --git a/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/StatusBarPolicy.java b/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/StatusBarPolicy.java deleted file mode 100644 index 5cc8482aeb7cc..0000000000000 --- a/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/StatusBarPolicy.java +++ /dev/null @@ -1,1386 +0,0 @@ -/* - * 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.policy.statusbar.phone; - -import android.app.AlertDialog; -import android.bluetooth.BluetoothA2dp; -import android.bluetooth.BluetoothAdapter; -import android.bluetooth.BluetoothHeadset; -import android.bluetooth.BluetoothPbap; -import android.content.BroadcastReceiver; -import android.content.ContentResolver; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.res.TypedArray; -import android.graphics.PixelFormat; -import android.graphics.drawable.Drawable; -import android.location.LocationManager; -import android.media.AudioManager; -import android.media.Ringtone; -import android.media.RingtoneManager; -import android.net.NetworkInfo; -import android.net.Uri; -import android.net.wifi.WifiManager; -import android.os.Binder; -import android.os.Handler; -import android.os.IBinder; -import android.os.Message; -import android.os.RemoteException; -import android.os.storage.StorageManager; -import android.provider.Settings; -import android.telephony.PhoneStateListener; -import android.telephony.ServiceState; -import android.telephony.SignalStrength; -import android.telephony.TelephonyManager; -import android.text.format.DateFormat; -import android.text.style.RelativeSizeSpan; -import android.text.Spannable; -import android.text.SpannableStringBuilder; -import android.util.Slog; -import android.view.View; -import android.view.ViewGroup; -import android.view.WindowManager; -import android.view.WindowManagerImpl; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.TextView; - -import com.android.internal.R; -import com.android.internal.app.IBatteryStats; -import com.android.internal.telephony.IccCard; -import com.android.internal.telephony.TelephonyIntents; -import com.android.internal.telephony.cdma.EriInfo; -import com.android.internal.telephony.cdma.TtyIntent; -import com.android.server.am.BatteryStatsService; - -import com.android.server.status.IconData; - -import java.text.SimpleDateFormat; -import java.util.Calendar; -import java.util.TimeZone; - -/** - * This class contains all of the policy about which icons are installed in the status - * bar at boot time. In reality, it should go into the android.policy package, but - * putting it here is the first step from extracting it. - */ -public class StatusBarPolicy { - private static final String TAG = "StatusBarPolicy"; - - private static StatusBarPolicy sInstance; - - // message codes for the handler - private static final int EVENT_BATTERY_CLOSE = 4; - - private final Context mContext; - private final StatusBarService mService; - private final Handler mHandler = new StatusBarHandler(); - private final IBatteryStats mBatteryStats; - - // clock - private Calendar mCalendar; - private String mClockFormatString; - private SimpleDateFormat mClockFormat; - private IBinder mClockIcon; - private IconData mClockData; - - // storage - private StorageManager mStorageManager; - - // battery - private IBinder mBatteryIcon; - private IconData mBatteryData; - private boolean mBatteryFirst = true; - private boolean mBatteryPlugged; - private int mBatteryLevel; - private AlertDialog mLowBatteryDialog; - private TextView mBatteryLevelTextView; - private View mBatteryView; - private int mBatteryViewSequence; - private boolean mBatteryShowLowOnEndCall = false; - private static final boolean SHOW_LOW_BATTERY_WARNING = true; - private static final boolean SHOW_BATTERY_WARNINGS_IN_CALL = true; - - // phone - private TelephonyManager mPhone; - private IBinder mPhoneIcon; - - //***** Signal strength icons - private IconData mPhoneData; - //GSM/UMTS - private static final int[] sSignalImages = new int[] { - com.android.internal.R.drawable.stat_sys_signal_0, - com.android.internal.R.drawable.stat_sys_signal_1, - com.android.internal.R.drawable.stat_sys_signal_2, - com.android.internal.R.drawable.stat_sys_signal_3, - com.android.internal.R.drawable.stat_sys_signal_4 - }; - private static final int[] sSignalImages_r = new int[] { - com.android.internal.R.drawable.stat_sys_r_signal_0, - com.android.internal.R.drawable.stat_sys_r_signal_1, - com.android.internal.R.drawable.stat_sys_r_signal_2, - com.android.internal.R.drawable.stat_sys_r_signal_3, - com.android.internal.R.drawable.stat_sys_r_signal_4 - }; - private static final int[] sRoamingIndicatorImages_cdma = new int[] { - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, //Standard Roaming Indicator - // 1 is Standard Roaming Indicator OFF - // TODO T: image never used, remove and put 0 instead? - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - - // 2 is Standard Roaming Indicator FLASHING - // TODO T: image never used, remove and put 0 instead? - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - - // 3-12 Standard ERI - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, //3 - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - - // 13-63 Reserved for Standard ERI - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, //13 - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - - // 64-127 Reserved for Non Standard (Operator Specific) ERI - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, //64 - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0, - com.android.internal.R.drawable.stat_sys_roaming_cdma_0 //83 - - // 128-255 Reserved - }; - - //***** Data connection icons - private int[] mDataIconList = sDataNetType_g; - //GSM/UMTS - private static final int[] sDataNetType_g = new int[] { - com.android.internal.R.drawable.stat_sys_data_connected_g, - com.android.internal.R.drawable.stat_sys_data_in_g, - com.android.internal.R.drawable.stat_sys_data_out_g, - com.android.internal.R.drawable.stat_sys_data_inandout_g, - }; - private static final int[] sDataNetType_3g = new int[] { - com.android.internal.R.drawable.stat_sys_data_connected_3g, - com.android.internal.R.drawable.stat_sys_data_in_3g, - com.android.internal.R.drawable.stat_sys_data_out_3g, - com.android.internal.R.drawable.stat_sys_data_inandout_3g, - }; - private static final int[] sDataNetType_e = new int[] { - com.android.internal.R.drawable.stat_sys_data_connected_e, - com.android.internal.R.drawable.stat_sys_data_in_e, - com.android.internal.R.drawable.stat_sys_data_out_e, - com.android.internal.R.drawable.stat_sys_data_inandout_e, - }; - //3.5G - private static final int[] sDataNetType_h = new int[] { - com.android.internal.R.drawable.stat_sys_data_connected_h, - com.android.internal.R.drawable.stat_sys_data_in_h, - com.android.internal.R.drawable.stat_sys_data_out_h, - com.android.internal.R.drawable.stat_sys_data_inandout_h, - }; - - //CDMA - // Use 3G icons for EVDO data and 1x icons for 1XRTT data - private static final int[] sDataNetType_1x = new int[] { - com.android.internal.R.drawable.stat_sys_data_connected_1x, - com.android.internal.R.drawable.stat_sys_data_in_1x, - com.android.internal.R.drawable.stat_sys_data_out_1x, - com.android.internal.R.drawable.stat_sys_data_inandout_1x, - }; - - // Assume it's all good unless we hear otherwise. We don't always seem - // to get broadcasts that it *is* there. - IccCard.State mSimState = IccCard.State.READY; - int mPhoneState = TelephonyManager.CALL_STATE_IDLE; - int mDataState = TelephonyManager.DATA_DISCONNECTED; - int mDataActivity = TelephonyManager.DATA_ACTIVITY_NONE; - ServiceState mServiceState; - SignalStrength mSignalStrength; - - // data connection - private IBinder mDataIcon; - private IconData mDataData; - private boolean mDataIconVisible; - private boolean mHspaDataDistinguishable; - - // ringer volume - private IBinder mVolumeIcon; - private IconData mVolumeData; - private boolean mVolumeVisible; - - // bluetooth device status - private IBinder mBluetoothIcon; - private IconData mBluetoothData; - private int mBluetoothHeadsetState; - private boolean mBluetoothA2dpConnected; - private int mBluetoothPbapState; - private boolean mBluetoothEnabled; - - // wifi - private static final int[] sWifiSignalImages = new int[] { - com.android.internal.R.drawable.stat_sys_wifi_signal_1, - com.android.internal.R.drawable.stat_sys_wifi_signal_2, - com.android.internal.R.drawable.stat_sys_wifi_signal_3, - com.android.internal.R.drawable.stat_sys_wifi_signal_4, - }; - private static final int sWifiTemporarilyNotConnectedImage = - com.android.internal.R.drawable.stat_sys_wifi_signal_0; - - private int mLastWifiSignalLevel = -1; - private boolean mIsWifiConnected = false; - private IBinder mWifiIcon; - private IconData mWifiData; - - // gps - private IBinder mGpsIcon; - private IconData mGpsEnabledIconData; - private IconData mGpsFixIconData; - - // alarm clock - // Icon lit when clock is set - private IBinder mAlarmClockIcon; - private IconData mAlarmClockIconData; - - // sync state - // If sync is active the SyncActive icon is displayed. If sync is not active but - // sync is failing the SyncFailing icon is displayed. Otherwise neither are displayed. - private IBinder mSyncActiveIcon; - private IBinder mSyncFailingIcon; - - // TTY mode - // Icon lit when TTY mode is enabled - private IBinder mTTYModeIcon; - private IconData mTTYModeEnableIconData; - - // Cdma Roaming Indicator, ERI - private IBinder mCdmaRoamingIndicatorIcon; - private IconData mCdmaRoamingIndicatorIconData; - - private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - if (action.equals(Intent.ACTION_TIME_TICK)) { - updateClock(); - } - else if (action.equals(Intent.ACTION_TIME_CHANGED)) { - updateClock(); - } - else if (action.equals(Intent.ACTION_BATTERY_CHANGED)) { - updateBattery(intent); - } - else if (action.equals(Intent.ACTION_CONFIGURATION_CHANGED)) { - updateClock(); - } - else if (action.equals(Intent.ACTION_TIMEZONE_CHANGED)) { - String tz = intent.getStringExtra("time-zone"); - mCalendar = Calendar.getInstance(TimeZone.getTimeZone(tz)); - updateClock(); - } - else if (action.equals(Intent.ACTION_ALARM_CHANGED)) { - updateAlarm(intent); - } - else if (action.equals(Intent.ACTION_SYNC_STATE_CHANGED)) { - updateSyncState(intent); - } - else if (action.equals(Intent.ACTION_BATTERY_LOW)) { - onBatteryLow(intent); - } - else if (action.equals(Intent.ACTION_BATTERY_OKAY) - || action.equals(Intent.ACTION_POWER_CONNECTED)) { - onBatteryOkay(intent); - } - else if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED) || - action.equals(BluetoothHeadset.ACTION_STATE_CHANGED) || - action.equals(BluetoothA2dp.ACTION_SINK_STATE_CHANGED) || - action.equals(BluetoothPbap.PBAP_STATE_CHANGED_ACTION)) { - updateBluetooth(intent); - } - else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION) || - action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION) || - action.equals(WifiManager.RSSI_CHANGED_ACTION)) { - updateWifi(intent); - } - else if (action.equals(LocationManager.GPS_ENABLED_CHANGE_ACTION) || - action.equals(LocationManager.GPS_FIX_CHANGE_ACTION)) { - updateGps(intent); - } - else if (action.equals(AudioManager.RINGER_MODE_CHANGED_ACTION) || - action.equals(AudioManager.VIBRATE_SETTING_CHANGED_ACTION)) { - updateVolume(); - } - else if (action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) { - updateSimState(intent); - } - else if (action.equals(TtyIntent.TTY_ENABLED_CHANGE_ACTION)) { - updateTTY(intent); - } - } - }; - - private StatusBarPolicy(Context context, StatusBarService service) { - mContext = context; - mService = service; - mSignalStrength = new SignalStrength(); - mBatteryStats = BatteryStatsService.getService(); - - // clock - mCalendar = Calendar.getInstance(TimeZone.getDefault()); - mClockData = IconData.makeText("clock", ""); - mClockIcon = service.addIcon(mClockData, null); - updateClock(); - - // storage - mStorageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE); - mStorageManager.registerListener( - new com.android.server.status.StorageNotification(context)); - - // battery - mBatteryData = IconData.makeIcon("battery", - null, com.android.internal.R.drawable.stat_sys_battery_unknown, 0, 0); - mBatteryIcon = service.addIcon(mBatteryData, null); - - // phone_signal - mPhone = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE); - mPhoneData = IconData.makeIcon("phone_signal", - null, com.android.internal.R.drawable.stat_sys_signal_null, 0, 0); - mPhoneIcon = service.addIcon(mPhoneData, null); - - // register for phone state notifications. - ((TelephonyManager)mContext.getSystemService(Context.TELEPHONY_SERVICE)) - .listen(mPhoneStateListener, - PhoneStateListener.LISTEN_SERVICE_STATE - | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS - | PhoneStateListener.LISTEN_CALL_STATE - | PhoneStateListener.LISTEN_DATA_CONNECTION_STATE - | PhoneStateListener.LISTEN_DATA_ACTIVITY); - - // data_connection - mDataData = IconData.makeIcon("data_connection", - null, com.android.internal.R.drawable.stat_sys_data_connected_g, 0, 0); - mDataIcon = service.addIcon(mDataData, null); - service.setIconVisibility(mDataIcon, false); - - // wifi - mWifiData = IconData.makeIcon("wifi", null, sWifiSignalImages[0], 0, 0); - mWifiIcon = service.addIcon(mWifiData, null); - service.setIconVisibility(mWifiIcon, false); - // wifi will get updated by the sticky intents - - // TTY status - mTTYModeEnableIconData = IconData.makeIcon("tty", - null, com.android.internal.R.drawable.stat_sys_tty_mode, 0, 0); - mTTYModeIcon = service.addIcon(mTTYModeEnableIconData, null); - service.setIconVisibility(mTTYModeIcon, false); - - // Cdma Roaming Indicator, ERI - mCdmaRoamingIndicatorIconData = IconData.makeIcon("cdma_eri", - null, com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 0, 0); - mCdmaRoamingIndicatorIcon = service.addIcon(mCdmaRoamingIndicatorIconData, null); - service.setIconVisibility(mCdmaRoamingIndicatorIcon, false); - - // bluetooth status - mBluetoothData = IconData.makeIcon("bluetooth", - null, com.android.internal.R.drawable.stat_sys_data_bluetooth, 0, 0); - mBluetoothIcon = service.addIcon(mBluetoothData, null); - BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); - if (adapter != null) { - mBluetoothEnabled = adapter.isEnabled(); - } else { - mBluetoothEnabled = false; - } - mBluetoothA2dpConnected = false; - mBluetoothHeadsetState = BluetoothHeadset.STATE_DISCONNECTED; - mBluetoothPbapState = BluetoothPbap.STATE_DISCONNECTED; - mService.setIconVisibility(mBluetoothIcon, mBluetoothEnabled); - - // Gps status - mGpsEnabledIconData = IconData.makeIcon("gps", - null, com.android.internal.R.drawable.stat_sys_gps_acquiring_anim, 0, 0); - mGpsFixIconData = IconData.makeIcon("gps", - null, com.android.internal.R.drawable.stat_sys_gps_on, 0, 0); - mGpsIcon = service.addIcon(mGpsEnabledIconData, null); - service.setIconVisibility(mGpsIcon, false); - - // Alarm clock - mAlarmClockIconData = IconData.makeIcon( - "alarm_clock", - null, com.android.internal.R.drawable.stat_notify_alarm, 0, 0); - mAlarmClockIcon = service.addIcon(mAlarmClockIconData, null); - service.setIconVisibility(mAlarmClockIcon, false); - - // Sync state - mSyncActiveIcon = service.addIcon(IconData.makeIcon("sync_active", - null, R.drawable.stat_notify_sync_anim0, 0, 0), null); - mSyncFailingIcon = service.addIcon(IconData.makeIcon("sync_failing", - null, R.drawable.stat_notify_sync_error, 0, 0), null); - service.setIconVisibility(mSyncActiveIcon, false); - service.setIconVisibility(mSyncFailingIcon, false); - - // volume - mVolumeData = IconData.makeIcon("volume", - null, com.android.internal.R.drawable.stat_sys_ringer_silent, 0, 0); - mVolumeIcon = service.addIcon(mVolumeData, null); - service.setIconVisibility(mVolumeIcon, false); - updateVolume(); - - IntentFilter filter = new IntentFilter(); - - // Register for Intent broadcasts for... - filter.addAction(Intent.ACTION_TIME_TICK); - filter.addAction(Intent.ACTION_TIME_CHANGED); - filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED); - filter.addAction(Intent.ACTION_BATTERY_CHANGED); - filter.addAction(Intent.ACTION_BATTERY_LOW); - filter.addAction(Intent.ACTION_BATTERY_OKAY); - filter.addAction(Intent.ACTION_POWER_CONNECTED); - filter.addAction(Intent.ACTION_TIMEZONE_CHANGED); - filter.addAction(Intent.ACTION_ALARM_CHANGED); - filter.addAction(Intent.ACTION_SYNC_STATE_CHANGED); - filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION); - filter.addAction(AudioManager.VIBRATE_SETTING_CHANGED_ACTION); - filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED); - filter.addAction(BluetoothHeadset.ACTION_STATE_CHANGED); - filter.addAction(BluetoothA2dp.ACTION_SINK_STATE_CHANGED); - filter.addAction(BluetoothPbap.PBAP_STATE_CHANGED_ACTION); - filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); - filter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION); - filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); - filter.addAction(WifiManager.RSSI_CHANGED_ACTION); - filter.addAction(LocationManager.GPS_ENABLED_CHANGE_ACTION); - filter.addAction(LocationManager.GPS_FIX_CHANGE_ACTION); - filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED); - filter.addAction(TtyIntent.TTY_ENABLED_CHANGE_ACTION); - mContext.registerReceiver(mIntentReceiver, filter, null, mHandler); - - // load config to determine if to distinguish Hspa data icon - try { - mHspaDataDistinguishable = mContext.getResources().getBoolean( - com.android.internal.R.bool.config_hspa_data_distinguishable); - } catch (Exception e) { - mHspaDataDistinguishable = false; - } - } - - public static void installIcons(Context context, StatusBarService service) { - sInstance = new StatusBarPolicy(context, service); - } - - private final CharSequence getSmallTime() { - boolean b24 = DateFormat.is24HourFormat(mContext); - int res; - - if (b24) { - res = R.string.twenty_four_hour_time_format; - } else { - res = R.string.twelve_hour_time_format; - } - - final char MAGIC1 = '\uEF00'; - final char MAGIC2 = '\uEF01'; - - SimpleDateFormat sdf; - String format = mContext.getString(res); - if (!format.equals(mClockFormatString)) { - /* - * Search for an unquoted "a" in the format string, so we can - * add dummy characters around it to let us find it again after - * formatting and change its size. - */ - int a = -1; - boolean quoted = false; - for (int i = 0; i < format.length(); i++) { - char c = format.charAt(i); - - if (c == '\'') { - quoted = !quoted; - } - - if (!quoted && c == 'a') { - a = i; - break; - } - } - - if (a >= 0) { - // Move a back so any whitespace before the AM/PM is also in the alternate size. - final int b = a; - while (a > 0 && Character.isWhitespace(format.charAt(a-1))) { - a--; - } - format = format.substring(0, a) + MAGIC1 + format.substring(a, b) - + "a" + MAGIC2 + format.substring(b + 1); - } - - mClockFormat = sdf = new SimpleDateFormat(format); - mClockFormatString = format; - } else { - sdf = mClockFormat; - } - String result = sdf.format(mCalendar.getTime()); - - int magic1 = result.indexOf(MAGIC1); - int magic2 = result.indexOf(MAGIC2); - - if (magic1 >= 0 && magic2 > magic1) { - SpannableStringBuilder formatted = new SpannableStringBuilder(result); - - formatted.setSpan(new RelativeSizeSpan(0.7f), magic1, magic2, - Spannable.SPAN_EXCLUSIVE_INCLUSIVE); - - formatted.delete(magic2, magic2 + 1); - formatted.delete(magic1, magic1 + 1); - - return formatted; - } else { - return result; - } - } - - private final void updateClock() { - mCalendar.setTimeInMillis(System.currentTimeMillis()); - mClockData.text = getSmallTime(); - mService.updateIcon(mClockIcon, mClockData, null); - } - - private final void updateAlarm(Intent intent) { - boolean alarmSet = intent.getBooleanExtra("alarmSet", false); - mService.setIconVisibility(mAlarmClockIcon, alarmSet); - } - - private final void updateSyncState(Intent intent) { - boolean isActive = intent.getBooleanExtra("active", false); - boolean isFailing = intent.getBooleanExtra("failing", false); - mService.setIconVisibility(mSyncActiveIcon, isActive); - // Don't display sync failing icon: BUG 1297963 Set sync error timeout to "never" - //mService.setIconVisibility(mSyncFailingIcon, isFailing && !isActive); - } - - private final void updateBattery(Intent intent) { - mBatteryData.iconId = intent.getIntExtra("icon-small", 0); - mBatteryData.iconLevel = intent.getIntExtra("level", 0); - mService.updateIcon(mBatteryIcon, mBatteryData, null); - - boolean plugged = intent.getIntExtra("plugged", 0) != 0; - int level = intent.getIntExtra("level", -1); - if (false) { - Slog.d(TAG, "updateBattery level=" + level - + " plugged=" + plugged - + " mBatteryPlugged=" + mBatteryPlugged - + " mBatteryLevel=" + mBatteryLevel - + " mBatteryFirst=" + mBatteryFirst); - } - - boolean oldPlugged = mBatteryPlugged; - - mBatteryPlugged = plugged; - mBatteryLevel = level; - - if (mBatteryFirst) { - mBatteryFirst = false; - } - /* - * No longer showing the battery view because it draws attention away - * from the USB storage notification. We could still show it when - * connected to a brick, but that could lead to the user into thinking - * the device does not charge when plugged into USB (since he/she would - * not see the same battery screen on USB as he sees on brick). - */ - /* else { - if (plugged && !oldPlugged) { - showBatteryView(); - } - } - */ - if (false) { - Slog.d(TAG, "plugged=" + plugged + " oldPlugged=" + oldPlugged + " level=" + level); - } - } - - private void onBatteryLow(Intent intent) { - if (SHOW_LOW_BATTERY_WARNING) { - if (false) { - Slog.d(TAG, "mPhoneState=" + mPhoneState - + " mLowBatteryDialog=" + mLowBatteryDialog - + " mBatteryShowLowOnEndCall=" + mBatteryShowLowOnEndCall); - } - - if (SHOW_BATTERY_WARNINGS_IN_CALL || mPhoneState == TelephonyManager.CALL_STATE_IDLE) { - showLowBatteryWarning(); - } else { - mBatteryShowLowOnEndCall = true; - } - } - } - - private void onBatteryOkay(Intent intent) { - if (mLowBatteryDialog != null - && SHOW_LOW_BATTERY_WARNING) { - mLowBatteryDialog.dismiss(); - mBatteryShowLowOnEndCall = false; - } - } - - private void showBatteryView() { - closeLastBatteryView(); - if (mLowBatteryDialog != null) { - mLowBatteryDialog.dismiss(); - } - - int level = mBatteryLevel; - - View v = View.inflate(mContext, com.android.internal.R.layout.battery_status, null); - mBatteryView = v; - int pixelFormat = PixelFormat.TRANSLUCENT; - Drawable bg = v.getBackground(); - if (bg != null) { - pixelFormat = bg.getOpacity(); - } - - int flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE - | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE - | WindowManager.LayoutParams.FLAG_DIM_BEHIND; - - if (!mContext.getResources().getBoolean( - com.android.internal.R.bool.config_sf_slowBlur)) { - flags |= WindowManager.LayoutParams.FLAG_BLUR_BEHIND; - } - - WindowManager.LayoutParams lp = new WindowManager.LayoutParams( - ViewGroup.LayoutParams.WRAP_CONTENT, - ViewGroup.LayoutParams.WRAP_CONTENT, - WindowManager.LayoutParams.TYPE_TOAST, - flags, pixelFormat); - - // Get the dim amount from the theme - TypedArray a = mContext.obtainStyledAttributes( - com.android.internal.R.styleable.Theme); - lp.dimAmount = a.getFloat(android.R.styleable.Theme_backgroundDimAmount, 0.5f); - a.recycle(); - - lp.setTitle("Battery"); - - TextView levelTextView = (TextView)v.findViewById(com.android.internal.R.id.level_percent); - levelTextView.setText(mContext.getString( - com.android.internal.R.string.battery_status_text_percent_format, level)); - - setBatteryLevel(v, com.android.internal.R.id.spacer, 100-level, 0, 0); - setBatteryLevel(v, com.android.internal.R.id.level, level, - com.android.internal.R.drawable.battery_charge_fill, level); - - WindowManagerImpl.getDefault().addView(v, lp); - - scheduleCloseBatteryView(); - } - - private void setBatteryLevel(View parent, int id, int height, int background, int level) { - ImageView v = (ImageView)parent.findViewById(id); - LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams)v.getLayoutParams(); - lp.weight = height; - if (background != 0) { - v.setBackgroundResource(background); - Drawable bkg = v.getBackground(); - bkg.setLevel(level); - } - } - - private void showLowBatteryWarning() { - closeLastBatteryView(); - - // Show exact battery level. - CharSequence levelText = mContext.getString( - com.android.internal.R.string.battery_low_percent_format, mBatteryLevel); - - if (mBatteryLevelTextView != null) { - mBatteryLevelTextView.setText(levelText); - } else { - View v = View.inflate(mContext, com.android.internal.R.layout.battery_low, null); - mBatteryLevelTextView=(TextView)v.findViewById(com.android.internal.R.id.level_percent); - - mBatteryLevelTextView.setText(levelText); - - AlertDialog.Builder b = new AlertDialog.Builder(mContext); - b.setCancelable(true); - b.setTitle(com.android.internal.R.string.battery_low_title); - b.setView(v); - b.setIcon(android.R.drawable.ic_dialog_alert); - b.setPositiveButton(android.R.string.ok, null); - - final Intent intent = new Intent(Intent.ACTION_POWER_USAGE_SUMMARY); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK - | Intent.FLAG_ACTIVITY_MULTIPLE_TASK - | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS - | Intent.FLAG_ACTIVITY_NO_HISTORY); - if (intent.resolveActivity(mContext.getPackageManager()) != null) { - b.setNegativeButton(com.android.internal.R.string.battery_low_why, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - mContext.startActivity(intent); - if (mLowBatteryDialog != null) { - mLowBatteryDialog.dismiss(); - } - } - }); - } - - AlertDialog d = b.create(); - d.setOnDismissListener(mLowBatteryListener); - d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); - d.show(); - mLowBatteryDialog = d; - } - - final ContentResolver cr = mContext.getContentResolver(); - if (Settings.System.getInt(cr, - Settings.System.POWER_SOUNDS_ENABLED, 1) == 1) - { - final String soundPath = Settings.System.getString(cr, - Settings.System.LOW_BATTERY_SOUND); - if (soundPath != null) { - final Uri soundUri = Uri.parse("file://" + soundPath); - if (soundUri != null) { - final Ringtone sfx = RingtoneManager.getRingtone(mContext, soundUri); - if (sfx != null) { - sfx.setStreamType(AudioManager.STREAM_SYSTEM); - sfx.play(); - } - } - } - } - } - - private final void updateCallState(int state) { - mPhoneState = state; - if (false) { - Slog.d(TAG, "mPhoneState=" + mPhoneState - + " mLowBatteryDialog=" + mLowBatteryDialog - + " mBatteryShowLowOnEndCall=" + mBatteryShowLowOnEndCall); - } - if (mPhoneState == TelephonyManager.CALL_STATE_IDLE) { - if (mBatteryShowLowOnEndCall) { - if (!mBatteryPlugged) { - showLowBatteryWarning(); - } - mBatteryShowLowOnEndCall = false; - } - } else { - if (mLowBatteryDialog != null) { - mLowBatteryDialog.dismiss(); - mBatteryShowLowOnEndCall = true; - } - } - } - - private DialogInterface.OnDismissListener mLowBatteryListener - = new DialogInterface.OnDismissListener() { - public void onDismiss(DialogInterface dialog) { - mLowBatteryDialog = null; - mBatteryLevelTextView = null; - } - }; - - private void scheduleCloseBatteryView() { - Message m = mHandler.obtainMessage(EVENT_BATTERY_CLOSE); - m.arg1 = (++mBatteryViewSequence); - mHandler.sendMessageDelayed(m, 3000); - } - - private void closeLastBatteryView() { - if (mBatteryView != null) { - //mBatteryView.debug(); - WindowManagerImpl.getDefault().removeView(mBatteryView); - mBatteryView = null; - } - } - - private PhoneStateListener mPhoneStateListener = new PhoneStateListener() { - @Override - public void onSignalStrengthsChanged(SignalStrength signalStrength) { - mSignalStrength = signalStrength; - updateSignalStrength(); - } - - @Override - public void onServiceStateChanged(ServiceState state) { - mServiceState = state; - updateSignalStrength(); - updateCdmaRoamingIcon(state); - updateDataIcon(); - } - - @Override - public void onCallStateChanged(int state, String incomingNumber) { - updateCallState(state); - // In cdma, if a voice call is made, RSSI should switch to 1x. - if (isCdma()) { - updateSignalStrength(); - } - } - - @Override - public void onDataConnectionStateChanged(int state, int networkType) { - mDataState = state; - updateDataNetType(networkType); - updateDataIcon(); - } - - @Override - public void onDataActivity(int direction) { - mDataActivity = direction; - updateDataIcon(); - } - }; - - private final void updateSimState(Intent intent) { - String stateExtra = intent.getStringExtra(IccCard.INTENT_KEY_ICC_STATE); - if (IccCard.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) { - mSimState = IccCard.State.ABSENT; - } - else if (IccCard.INTENT_VALUE_ICC_READY.equals(stateExtra)) { - mSimState = IccCard.State.READY; - } - else if (IccCard.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) { - final String lockedReason = intent.getStringExtra(IccCard.INTENT_KEY_LOCKED_REASON); - if (IccCard.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) { - mSimState = IccCard.State.PIN_REQUIRED; - } - else if (IccCard.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) { - mSimState = IccCard.State.PUK_REQUIRED; - } - else { - mSimState = IccCard.State.NETWORK_LOCKED; - } - } else { - mSimState = IccCard.State.UNKNOWN; - } - updateDataIcon(); - } - - private boolean isCdma() { - return (mSignalStrength != null) && !mSignalStrength.isGsm(); - } - - private boolean isEvdo() { - return ( (mServiceState != null) - && ((mServiceState.getRadioTechnology() - == ServiceState.RADIO_TECHNOLOGY_EVDO_0) - || (mServiceState.getRadioTechnology() - == ServiceState.RADIO_TECHNOLOGY_EVDO_A))); - } - - private boolean hasService() { - if (mServiceState != null) { - switch (mServiceState.getState()) { - case ServiceState.STATE_OUT_OF_SERVICE: - case ServiceState.STATE_POWER_OFF: - return false; - default: - return true; - } - } else { - return false; - } - } - - private final void updateSignalStrength() { - int iconLevel = -1; - int[] iconList; - - if (!hasService()) { - //Slog.d(TAG, "updateSignalStrength: no service"); - if (Settings.System.getInt(mContext.getContentResolver(), - Settings.System.AIRPLANE_MODE_ON, 0) == 1) { - mPhoneData.iconId = com.android.internal.R.drawable.stat_sys_signal_flightmode; - } else { - mPhoneData.iconId = com.android.internal.R.drawable.stat_sys_signal_null; - } - mService.updateIcon(mPhoneIcon, mPhoneData, null); - return; - } - - if (!isCdma()) { - int asu = mSignalStrength.getGsmSignalStrength(); - - // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5 - // asu = 0 (-113dB or less) is very weak - // signal, its better to show 0 bars to the user in such cases. - // asu = 99 is a special case, where the signal strength is unknown. - if (asu <= 2 || asu == 99) iconLevel = 0; - else if (asu >= 12) iconLevel = 4; - else if (asu >= 8) iconLevel = 3; - else if (asu >= 5) iconLevel = 2; - else iconLevel = 1; - - // Though mPhone is a Manager, this call is not an IPC - if (mPhone.isNetworkRoaming()) { - iconList = sSignalImages_r; - } else { - iconList = sSignalImages; - } - } else { - iconList = this.sSignalImages; - - // If 3G(EV) and 1x network are available than 3G should be - // displayed, displayed RSSI should be from the EV side. - // If a voice call is made then RSSI should switch to 1x. - if ((mPhoneState == TelephonyManager.CALL_STATE_IDLE) && isEvdo()){ - iconLevel = getEvdoLevel(); - if (false) { - Slog.d(TAG, "use Evdo level=" + iconLevel + " to replace Cdma Level=" + getCdmaLevel()); - } - } else { - iconLevel = getCdmaLevel(); - } - } - mPhoneData.iconId = iconList[iconLevel]; - mService.updateIcon(mPhoneIcon, mPhoneData, null); - } - - private int getCdmaLevel() { - final int cdmaDbm = mSignalStrength.getCdmaDbm(); - final int cdmaEcio = mSignalStrength.getCdmaEcio(); - int levelDbm = 0; - int levelEcio = 0; - - if (cdmaDbm >= -75) levelDbm = 4; - else if (cdmaDbm >= -85) levelDbm = 3; - else if (cdmaDbm >= -95) levelDbm = 2; - else if (cdmaDbm >= -100) levelDbm = 1; - else levelDbm = 0; - - // Ec/Io are in dB*10 - if (cdmaEcio >= -90) levelEcio = 4; - else if (cdmaEcio >= -110) levelEcio = 3; - else if (cdmaEcio >= -130) levelEcio = 2; - else if (cdmaEcio >= -150) levelEcio = 1; - else levelEcio = 0; - - return (levelDbm < levelEcio) ? levelDbm : levelEcio; - } - - private int getEvdoLevel() { - int evdoDbm = mSignalStrength.getEvdoDbm(); - int evdoSnr = mSignalStrength.getEvdoSnr(); - int levelEvdoDbm = 0; - int levelEvdoSnr = 0; - - if (evdoDbm >= -65) levelEvdoDbm = 4; - else if (evdoDbm >= -75) levelEvdoDbm = 3; - else if (evdoDbm >= -90) levelEvdoDbm = 2; - else if (evdoDbm >= -105) levelEvdoDbm = 1; - else levelEvdoDbm = 0; - - if (evdoSnr >= 7) levelEvdoSnr = 4; - else if (evdoSnr >= 5) levelEvdoSnr = 3; - else if (evdoSnr >= 3) levelEvdoSnr = 2; - else if (evdoSnr >= 1) levelEvdoSnr = 1; - else levelEvdoSnr = 0; - - return (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr; - } - - private final void updateDataNetType(int net) { - - switch (net) { - case TelephonyManager.NETWORK_TYPE_EDGE: - mDataIconList = sDataNetType_e; - break; - case TelephonyManager.NETWORK_TYPE_UMTS: - mDataIconList = sDataNetType_3g; - break; - case TelephonyManager.NETWORK_TYPE_HSDPA: - case TelephonyManager.NETWORK_TYPE_HSUPA: - case TelephonyManager.NETWORK_TYPE_HSPA: - if (mHspaDataDistinguishable) { - mDataIconList = sDataNetType_h; - } else { - mDataIconList = sDataNetType_3g; - } - break; - case TelephonyManager.NETWORK_TYPE_CDMA: - // display 1xRTT for IS95A/B - mDataIconList = this.sDataNetType_1x; - break; - case TelephonyManager.NETWORK_TYPE_1xRTT: - mDataIconList = this.sDataNetType_1x; - break; - case TelephonyManager.NETWORK_TYPE_EVDO_0: //fall through - case TelephonyManager.NETWORK_TYPE_EVDO_A: - mDataIconList = sDataNetType_3g; - break; - default: - mDataIconList = sDataNetType_g; - break; - } - } - - private final void updateDataIcon() { - int iconId; - boolean visible = true; - - if (!isCdma()) { - // GSM case, we have to check also the sim state - if (mSimState == IccCard.State.READY || mSimState == IccCard.State.UNKNOWN) { - if (hasService() && mDataState == TelephonyManager.DATA_CONNECTED) { - switch (mDataActivity) { - case TelephonyManager.DATA_ACTIVITY_IN: - iconId = mDataIconList[1]; - break; - case TelephonyManager.DATA_ACTIVITY_OUT: - iconId = mDataIconList[2]; - break; - case TelephonyManager.DATA_ACTIVITY_INOUT: - iconId = mDataIconList[3]; - break; - default: - iconId = mDataIconList[0]; - break; - } - mDataData.iconId = iconId; - mService.updateIcon(mDataIcon, mDataData, null); - } else { - visible = false; - } - } else { - mDataData.iconId = com.android.internal.R.drawable.stat_sys_no_sim; - mService.updateIcon(mDataIcon, mDataData, null); - } - } else { - // CDMA case, mDataActivity can be also DATA_ACTIVITY_DORMANT - if (hasService() && mDataState == TelephonyManager.DATA_CONNECTED) { - switch (mDataActivity) { - case TelephonyManager.DATA_ACTIVITY_IN: - iconId = mDataIconList[1]; - break; - case TelephonyManager.DATA_ACTIVITY_OUT: - iconId = mDataIconList[2]; - break; - case TelephonyManager.DATA_ACTIVITY_INOUT: - iconId = mDataIconList[3]; - break; - case TelephonyManager.DATA_ACTIVITY_DORMANT: - default: - iconId = mDataIconList[0]; - break; - } - mDataData.iconId = iconId; - mService.updateIcon(mDataIcon, mDataData, null); - } else { - visible = false; - } - } - - long ident = Binder.clearCallingIdentity(); - try { - mBatteryStats.notePhoneDataConnectionState(mPhone.getNetworkType(), visible); - } catch (RemoteException e) { - } finally { - Binder.restoreCallingIdentity(ident); - } - - if (mDataIconVisible != visible) { - mService.setIconVisibility(mDataIcon, visible); - mDataIconVisible = visible; - } - } - - private final void updateVolume() { - AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE); - final int ringerMode = audioManager.getRingerMode(); - final boolean visible = ringerMode == AudioManager.RINGER_MODE_SILENT || - ringerMode == AudioManager.RINGER_MODE_VIBRATE; - final int iconId = audioManager.shouldVibrate(AudioManager.VIBRATE_TYPE_RINGER) - ? com.android.internal.R.drawable.stat_sys_ringer_vibrate - : com.android.internal.R.drawable.stat_sys_ringer_silent; - - if (visible) { - mVolumeData.iconId = iconId; - mService.updateIcon(mVolumeIcon, mVolumeData, null); - } - if (visible != mVolumeVisible) { - mService.setIconVisibility(mVolumeIcon, visible); - mVolumeVisible = visible; - } - } - - private final void updateBluetooth(Intent intent) { - int iconId = com.android.internal.R.drawable.stat_sys_data_bluetooth; - String action = intent.getAction(); - if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) { - int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR); - mBluetoothEnabled = state == BluetoothAdapter.STATE_ON; - } else if (action.equals(BluetoothHeadset.ACTION_STATE_CHANGED)) { - mBluetoothHeadsetState = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE, - BluetoothHeadset.STATE_ERROR); - } else if (action.equals(BluetoothA2dp.ACTION_SINK_STATE_CHANGED)) { - BluetoothA2dp a2dp = new BluetoothA2dp(mContext); - if (a2dp.getConnectedSinks().size() != 0) { - mBluetoothA2dpConnected = true; - } else { - mBluetoothA2dpConnected = false; - } - } else if (action.equals(BluetoothPbap.PBAP_STATE_CHANGED_ACTION)) { - mBluetoothPbapState = intent.getIntExtra(BluetoothPbap.PBAP_STATE, - BluetoothPbap.STATE_DISCONNECTED); - } else { - return; - } - - if (mBluetoothHeadsetState == BluetoothHeadset.STATE_CONNECTED || mBluetoothA2dpConnected || - mBluetoothPbapState == BluetoothPbap.STATE_CONNECTED) { - iconId = com.android.internal.R.drawable.stat_sys_data_bluetooth_connected; - } - - mBluetoothData.iconId = iconId; - mService.updateIcon(mBluetoothIcon, mBluetoothData, null); - mService.setIconVisibility(mBluetoothIcon, mBluetoothEnabled); - } - - private final void updateWifi(Intent intent) { - final String action = intent.getAction(); - if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) { - - final boolean enabled = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, - WifiManager.WIFI_STATE_UNKNOWN) == WifiManager.WIFI_STATE_ENABLED; - - if (!enabled) { - // If disabled, hide the icon. (We show icon when connected.) - mService.setIconVisibility(mWifiIcon, false); - } - - } else if (action.equals(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION)) { - final boolean enabled = intent.getBooleanExtra(WifiManager.EXTRA_SUPPLICANT_CONNECTED, - false); - if (!enabled) { - mService.setIconVisibility(mWifiIcon, false); - } - } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) { - - final NetworkInfo networkInfo = (NetworkInfo) - intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO); - - int iconId; - if (networkInfo != null && networkInfo.isConnected()) { - mIsWifiConnected = true; - if (mLastWifiSignalLevel == -1) { - iconId = sWifiSignalImages[0]; - } else { - iconId = sWifiSignalImages[mLastWifiSignalLevel]; - } - - // Show the icon since wi-fi is connected - mService.setIconVisibility(mWifiIcon, true); - - } else { - mLastWifiSignalLevel = -1; - mIsWifiConnected = false; - iconId = sWifiSignalImages[0]; - - // Hide the icon since we're not connected - mService.setIconVisibility(mWifiIcon, false); - } - - mWifiData.iconId = iconId; - mService.updateIcon(mWifiIcon, mWifiData, null); - } else if (action.equals(WifiManager.RSSI_CHANGED_ACTION)) { - final int newRssi = intent.getIntExtra(WifiManager.EXTRA_NEW_RSSI, -200); - int newSignalLevel = WifiManager.calculateSignalLevel(newRssi, - sWifiSignalImages.length); - if (newSignalLevel != mLastWifiSignalLevel) { - mLastWifiSignalLevel = newSignalLevel; - if (mIsWifiConnected) { - mWifiData.iconId = sWifiSignalImages[newSignalLevel]; - } else { - mWifiData.iconId = sWifiTemporarilyNotConnectedImage; - } - mService.updateIcon(mWifiIcon, mWifiData, null); - } - } - } - - private final void updateGps(Intent intent) { - final String action = intent.getAction(); - final boolean enabled = intent.getBooleanExtra(LocationManager.EXTRA_GPS_ENABLED, false); - - if (action.equals(LocationManager.GPS_FIX_CHANGE_ACTION) && enabled) { - // GPS is getting fixes - mService.updateIcon(mGpsIcon, mGpsFixIconData, null); - mService.setIconVisibility(mGpsIcon, true); - } else if (action.equals(LocationManager.GPS_ENABLED_CHANGE_ACTION) && !enabled) { - // GPS is off - mService.setIconVisibility(mGpsIcon, false); - } else { - // GPS is on, but not receiving fixes - mService.updateIcon(mGpsIcon, mGpsEnabledIconData, null); - mService.setIconVisibility(mGpsIcon, true); - } - } - - private final void updateTTY(Intent intent) { - final String action = intent.getAction(); - final boolean enabled = intent.getBooleanExtra(TtyIntent.TTY_ENABLED, false); - - if (false) Slog.v(TAG, "updateTTY: enabled: " + enabled); - - if (enabled) { - // TTY is on - if (false) Slog.v(TAG, "updateTTY: set TTY on"); - mService.updateIcon(mTTYModeIcon, mTTYModeEnableIconData, null); - mService.setIconVisibility(mTTYModeIcon, true); - } else { - // TTY is off - if (false) Slog.v(TAG, "updateTTY: set TTY off"); - mService.setIconVisibility(mTTYModeIcon, false); - } - } - - private final void updateCdmaRoamingIcon(ServiceState state) { - if (!hasService()) { - mService.setIconVisibility(mCdmaRoamingIndicatorIcon, false); - return; - } - - if (!isCdma()) { - mService.setIconVisibility(mCdmaRoamingIndicatorIcon, false); - return; - } - - int[] iconList = sRoamingIndicatorImages_cdma; - int iconIndex = state.getCdmaEriIconIndex(); - int iconMode = state.getCdmaEriIconMode(); - - if (iconIndex == -1) { - Slog.e(TAG, "getCdmaEriIconIndex returned null, skipping ERI icon update"); - return; - } - - if (iconMode == -1) { - Slog.e(TAG, "getCdmeEriIconMode returned null, skipping ERI icon update"); - return; - } - - if (iconIndex == EriInfo.ROAMING_INDICATOR_OFF) { - if (false) Slog.v(TAG, "Cdma ROAMING_INDICATOR_OFF, removing ERI icon"); - mService.setIconVisibility(mCdmaRoamingIndicatorIcon, false); - return; - } - - switch (iconMode) { - case EriInfo.ROAMING_ICON_MODE_NORMAL: - mCdmaRoamingIndicatorIconData.iconId = iconList[iconIndex]; - mService.updateIcon(mCdmaRoamingIndicatorIcon, mCdmaRoamingIndicatorIconData, null); - mService.setIconVisibility(mCdmaRoamingIndicatorIcon, true); - break; - case EriInfo.ROAMING_ICON_MODE_FLASH: - mCdmaRoamingIndicatorIconData.iconId = - com.android.internal.R.drawable.stat_sys_roaming_cdma_flash; - mService.updateIcon(mCdmaRoamingIndicatorIcon, mCdmaRoamingIndicatorIconData, null); - mService.setIconVisibility(mCdmaRoamingIndicatorIcon, true); - break; - - } - mService.updateIcon(mPhoneIcon, mPhoneData, null); - } - - - private class StatusBarHandler extends Handler { - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case EVENT_BATTERY_CLOSE: - if (msg.arg1 == mBatteryViewSequence) { - closeLastBatteryView(); - } - break; - } - } - } -} diff --git a/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/StatusBarService.java b/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/StatusBarService.java index 3fe71d82e5589..c7fe0e6324d7b 100644 --- a/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/StatusBarService.java +++ b/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/StatusBarService.java @@ -17,8 +17,6 @@ package com.android.policy.statusbar.phone; import android.app.Service; -import android.app.IStatusBar; -import android.app.IStatusBarService; import android.content.Context; import android.content.Intent; import android.graphics.PixelFormat; @@ -26,7 +24,7 @@ import android.os.IBinder; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemClock; -import android.util.Log; +import android.util.Slog; import android.view.Gravity; import android.view.View; import android.view.ViewGroup; @@ -34,13 +32,18 @@ import android.view.Window; import android.view.WindowManager; import android.view.WindowManagerImpl; +import com.android.internal.statusbar.IStatusBar; +import com.android.internal.statusbar.IStatusBarService; +import com.android.internal.statusbar.StatusBarIcon; +import com.android.internal.statusbar.StatusBarIconList; + import com.android.server.status.IconData; import com.android.server.status.NotificationData; -public abstract class StatusBarService extends Service { +public abstract class StatusBarService extends Service implements CommandQueue.Callbacks { private static final String TAG = "StatusBarService"; - Bar mBar = new Bar(); + CommandQueue mCommandQueue; IStatusBarService mBarService; /* TODO @@ -52,17 +55,30 @@ public abstract class StatusBarService extends Service { @Override public void onCreate() { - // Put up the view - addStatusBarView(); - // Connect in to the status bar manager service + StatusBarIconList iconList = new StatusBarIconList(); mBarService = IStatusBarService.Stub.asInterface( ServiceManager.getService(Context.STATUS_BAR_SERVICE)); try { - mBarService.registerStatusBar(mBar); + mBarService.registerStatusBar(mCommandQueue, iconList); } catch (RemoteException ex) { // If the system process isn't there we're doomed anyway. } + + // Set up the initial icon state + mCommandQueue = new CommandQueue(this, iconList); + final int N = iconList.size(); + int viewIndex = 0; + for (int i=0; i=0; i--) { - final View child = getChildAt(i); - if (child.getVisibility() != GONE) { - fitRight = child.getRight(); - break; - } - } - - // find the first visible one that isn't the more icon - View moreView = null; - int fitLeft = -1; - int startIndex = -1; - for (i=0; i 0) { - number += n; - } - } else { - // decide how much to shift by - if (shift < 0) { - shift = childLeft - fitLeft; - } - // shift this left by shift - child.layout(childLeft-shift, child.getTop(), - childRight-shift, child.getBottom()); - } - } - } - - // BUG: Updating the text during the layout here doesn't seem to cause - // the view to be redrawn fully. The text view gets resized correctly, but the - // text contents aren't drawn properly. To work around this, we post a message - // and provide the value later. We're the only one changing this value show it - // should be ordered correctly. - if (false) { - this.moreIcon.update(number); - } else { - mBugWorkaroundNumber = number; - mBugWorkaroundHandler.post(mBugWorkaroundRunnable); - } - } - - private int mBugWorkaroundNumber; - private Handler mBugWorkaroundHandler = new Handler(); - private Runnable mBugWorkaroundRunnable = new Runnable() { - public void run() { - IconMerger.this.moreIcon.update(mBugWorkaroundNumber); - IconMerger.this.moreIcon.view.invalidate(); - } - }; -} diff --git a/services/java/com/android/server/status/NotificationLinearLayout.java b/services/java/com/android/server/status/NotificationLinearLayout.java deleted file mode 100644 index 2fdf956fb9014..0000000000000 --- a/services/java/com/android/server/status/NotificationLinearLayout.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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.util.AttributeSet; -import android.widget.LinearLayout; - - -public class NotificationLinearLayout extends LinearLayout { - public NotificationLinearLayout(Context context, AttributeSet attrs) { - super(context, attrs); - } -} - diff --git a/services/java/com/android/server/status/StatusBarIcon.java b/services/java/com/android/server/status/StatusBarIcon.java deleted file mode 100644 index 5849ef9d1b400..0000000000000 --- a/services/java/com/android/server/status/StatusBarIcon.java +++ /dev/null @@ -1,183 +0,0 @@ -/* - * 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.pm.PackageManager; -import android.content.res.Resources; -import android.graphics.Typeface; -import android.graphics.drawable.Drawable; -import android.text.TextUtils; -import android.util.Slog; -import android.view.Gravity; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.TextView; - -public class StatusBarIcon { - // TODO: get this from a resource - private static final int ICON_GAP = 8; - private static final int ICON_WIDTH = 25; - private static final int ICON_HEIGHT = 25; - - public View view; - - IconData mData; - - private TextView mTextView; - private AnimatedImageView mImageView; - private TextView mNumberView; - - public StatusBarIcon(Context context, IconData data, ViewGroup parent) { - mData = data.clone(); - - switch (data.type) { - case IconData.TEXT: { - TextView t; - t = new TextView(context, null, com.android.internal.R.style.TextAppearance_StatusBar_Icon); - mTextView = t; - LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams( - LinearLayout.LayoutParams.WRAP_CONTENT, - LinearLayout.LayoutParams.MATCH_PARENT); - t.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT); - t.setPadding(6, 0, 0, 0); - t.setLayoutParams(layoutParams); - t.setText(data.text); - this.view = t; - break; - } - - case IconData.ICON: { - // container - LayoutInflater inflater = (LayoutInflater)context.getSystemService( - Context.LAYOUT_INFLATER_SERVICE); - View v = inflater.inflate(com.android.internal.R.layout.status_bar_icon, parent, false); - this.view = v; - - // icon - AnimatedImageView im = (AnimatedImageView)v.findViewById(com.android.internal.R.id.image); - im.setImageDrawable(getIcon(context, data)); - im.setImageLevel(data.iconLevel); - mImageView = im; - - // number - TextView nv = (TextView)v.findViewById(com.android.internal.R.id.number); - mNumberView = nv; - if (data.number > 0) { - nv.setText("" + data.number); - nv.setVisibility(View.VISIBLE); - } else { - nv.setVisibility(View.GONE); - } - break; - } - } - } - - public void update(Context context, IconData data) throws StatusBarException { - if (mData.type != data.type) { - throw new StatusBarException("status bar entry type can't change"); - } - switch (data.type) { - case IconData.TEXT: - if (!TextUtils.equals(mData.text, data.text)) { - TextView tv = mTextView; - tv.setText(data.text); - } - break; - case IconData.ICON: - if (((mData.iconPackage != null && data.iconPackage != null) - && !mData.iconPackage.equals(data.iconPackage)) - || mData.iconId != data.iconId - || mData.iconLevel != data.iconLevel) { - ImageView im = mImageView; - im.setImageDrawable(getIcon(context, data)); - im.setImageLevel(data.iconLevel); - } - if (mData.number != data.number) { - TextView nv = mNumberView; - if (data.number > 0) { - nv.setText("" + data.number); - } else { - nv.setText(""); - } - } - break; - } - mData.copyFrom(data); - } - - public void update(int number) { - if (mData.number != number) { - TextView nv = mNumberView; - if (number > 0) { - nv.setText("" + number); - } else { - nv.setText(""); - } - } - mData.number = number; - } - - - /** - * Returns the right icon to use for this item, respecting the iconId and - * iconPackage (if set) - * - * @param context Context to use to get resources if iconPackage is not set - * @return Drawable for this item, or null if the package or item could not - * be found - */ - static Drawable getIcon(Context context, IconData data) { - - Resources r = null; - - if (data.iconPackage != null) { - try { - r = context.getPackageManager().getResourcesForApplication(data.iconPackage); - } catch (PackageManager.NameNotFoundException ex) { - Slog.e(StatusBarManagerService.TAG, "Icon package not found: " + data.iconPackage, ex); - return null; - } - } else { - r = context.getResources(); - } - - if (data.iconId == 0) { - Slog.w(StatusBarManagerService.TAG, "No icon ID for slot " + data.slot); - return null; - } - - try { - return r.getDrawable(data.iconId); - } catch (RuntimeException e) { - Slog.w(StatusBarManagerService.TAG, "Icon not found in " - + (data.iconPackage != null ? data.iconId : "") - + ": " + Integer.toHexString(data.iconId)); - } - - return null; - } - - int getNumber() { - return mData.number; - } -} - diff --git a/services/java/com/android/server/status/StatusBarManagerService.java b/services/java/com/android/server/status/StatusBarManagerService.java index b48a57543cdab..3072fe5c1f3af 100644 --- a/services/java/com/android/server/status/StatusBarManagerService.java +++ b/services/java/com/android/server/status/StatusBarManagerService.java @@ -16,13 +16,6 @@ package com.android.server.status; -import com.android.internal.R; -import com.android.internal.util.CharSequences; - -import android.app.ActivityManagerNative; -import android.app.Dialog; -import android.app.IStatusBar; -import android.app.IStatusBarService; import android.app.PendingIntent; import android.app.StatusBarManager; import android.content.BroadcastReceiver; @@ -31,42 +24,22 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; import android.content.res.Resources; -import android.graphics.PixelFormat; -import android.graphics.Rect; -import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.IBinder; import android.os.RemoteException; import android.os.Binder; -import android.os.Handler; -import android.os.Message; import android.os.SystemClock; -import android.provider.Telephony; import android.util.Slog; -import android.view.Display; -import android.view.Gravity; -import android.view.KeyEvent; -import android.view.LayoutInflater; -import android.view.MotionEvent; -import android.view.VelocityTracker; -import android.view.View; -import android.view.ViewGroup; -import android.view.Window; -import android.view.WindowManager; -import android.view.WindowManagerImpl; -import android.view.animation.Animation; -import android.view.animation.AnimationUtils; -import android.widget.LinearLayout; -import android.widget.RemoteViews; -import android.widget.ScrollView; -import android.widget.TextView; -import android.widget.FrameLayout; + +import com.android.internal.statusbar.IStatusBar; +import com.android.internal.statusbar.IStatusBarService; +import com.android.internal.statusbar.StatusBarIcon; +import com.android.internal.statusbar.StatusBarIconList; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; import java.util.HashMap; -import java.util.Set; /** @@ -133,100 +106,19 @@ public class StatusBarManagerService extends IStatusBarService.Stub void onPanelRevealed(); } - private class ExpandedDialog extends Dialog { - ExpandedDialog(Context context) { - super(context, com.android.internal.R.style.Theme_Light_NoTitleBar); - } - - @Override - public boolean dispatchKeyEvent(KeyEvent event) { - boolean down = event.getAction() == KeyEvent.ACTION_DOWN; - switch (event.getKeyCode()) { - case KeyEvent.KEYCODE_BACK: - if (!down) { - StatusBarManagerService.this.deactivate(); - } - return true; - } - return super.dispatchKeyEvent(event); - } - } - final Context mContext; - final Display mDisplay; - View /*StatusBarView*/ mStatusBarView; - int mPixelFormat; - H mHandler = new H(); Object mQueueLock = new Object(); ArrayList mQueue = new ArrayList(); NotificationCallbacks mNotificationCallbacks; + IStatusBar mBar; - // All accesses to mIconMap and mNotificationData are syncronized on those objects, - // but this is only so dump() can work correctly. Modifying these outside of the UI - // thread will not work, there are places in the code that unlock and reaquire between - // reads and require them to not be modified. - // icons - HashMap mIconMap = new HashMap(); - ArrayList mIconList = new ArrayList(); - String[] mRightIconSlots; - StatusBarIcon[] mRightIcons; - LinearLayout mIcons; - IconMerger mNotificationIcons; - LinearLayout mStatusIcons; - StatusBarIcon mMoreIcon; + StatusBarIconList mIcons = new StatusBarIconList(); private UninstallReceiver mUninstallReceiver; // expanded notifications NotificationViewList mNotificationData = new NotificationViewList(); - Dialog mExpandedDialog; - ExpandedView mExpandedView; - WindowManager.LayoutParams mExpandedParams; - ScrollView mScrollView; - View mNotificationLinearLayout; - TextView mOngoingTitle; - LinearLayout mOngoingItems; - TextView mLatestTitle; - LinearLayout mLatestItems; - TextView mNoNotificationsTitle; - TextView mSpnLabel; - TextView mPlmnLabel; - TextView mClearButton; - View mExpandedContents; - CloseDragHandle mCloseView; - int[] mPositionTmp = new int[2]; - boolean mExpanded; - boolean mExpandedVisible; - // the date view - DateView mDateView; - - // the tracker view - TrackingView mTrackingView; - WindowManager.LayoutParams mTrackingParams; - int mTrackingPosition; // the position of the top of the tracking view. - - // ticker - private boolean mTicking; - - // Tracking finger for opening/closing. - int mEdgeBorder; // corresponds to R.dimen.status_bar_edge_ignore - boolean mTracking; - VelocityTracker mVelocityTracker; - - static final int ANIM_FRAME_DURATION = (1000/60); - - boolean mAnimating; - long mCurAnimationTime; - float mDisplayHeight; - float mAnimY; - float mAnimVel; - float mAnimAccel; - long mAnimLastTime; - boolean mAnimatingReveal = false; - int mViewDelta; - int[] mAbsPos = new int[2]; - // for disabling the status bar ArrayList mDisableRecords = new ArrayList(); int mDisabled = 0; @@ -236,9 +128,10 @@ public class StatusBarManagerService extends IStatusBarService.Stub */ public StatusBarManagerService(Context context) { mContext = context; - mDisplay = ((WindowManager)context.getSystemService( - Context.WINDOW_SERVICE)).getDefaultDisplay(); mUninstallReceiver = new UninstallReceiver(); + + final Resources res = context.getResources(); + mIcons.defineSlots(res.getStringArray(com.android.internal.R.array.status_bar_icon_order)); } public void setNotificationCallbacks(NotificationCallbacks listener) { @@ -263,17 +156,14 @@ public class StatusBarManagerService extends IStatusBarService.Stub // ================================================================================ public void activate() { enforceExpandStatusBar(); - addPendingOp(OP_EXPAND, null, true); } public void deactivate() { enforceExpandStatusBar(); - addPendingOp(OP_EXPAND, null, false); } public void toggle() { enforceExpandStatusBar(); - addPendingOp(OP_TOGGLE, null, false); } public void disable(int what, IBinder token, String pkg) { @@ -293,67 +183,88 @@ public class StatusBarManagerService extends IStatusBarService.Stub } } - public IBinder addIcon(String slot, String iconPackage, int iconId, int iconLevel) { - enforceStatusBar(); - return addIcon(IconData.makeIcon(slot, iconPackage, iconId, iconLevel, 0), null); + public void setIcon(String slot, CharSequence text) { + } - public void updateIcon(IBinder key, - String slot, String iconPackage, int iconId, int iconLevel) { + public void setIcon(String slot, String iconPackage, int iconId, int iconLevel) { enforceStatusBar(); - updateIcon(key, IconData.makeIcon(slot, iconPackage, iconId, iconLevel, 0), null); + + synchronized (mIcons) { + int index = mIcons.getSlotIndex(slot); + if (index < 0) { + throw new SecurityException("invalid status bar icon slot: " + slot); + } + + StatusBarIcon icon = new StatusBarIcon(iconPackage, iconId, iconLevel); + mIcons.setIcon(index, icon); + + // Tell the client. If it fails, it'll restart soon and we'll sync up. + if (mBar != null) { + try { + mBar.setIcon(index, icon); + } catch (RemoteException ex) { + } + } + } } - public void removeIcon(IBinder key) { + public void setIconVisibility(String slot, boolean visible) { enforceStatusBar(); - addPendingOp(OP_REMOVE_ICON, key, null, null, -1); + + } + + public void removeIcon(String slot) { + enforceStatusBar(); + + synchronized (mIcons) { + int index = mIcons.getSlotIndex(slot); + if (index < 0) { + throw new SecurityException("invalid status bar icon slot: " + slot); + } + + mIcons.removeIcon(index); + + // Tell the client. If it fails, it'll restart soon and we'll sync up. + if (mBar != null) { + try { + mBar.removeIcon(index); + } catch (RemoteException ex) { + } + } + } } private void enforceStatusBar() { - mContext.enforceCallingOrSelfPermission( - android.Manifest.permission.STATUS_BAR, + mContext.enforceCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR, "StatusBarManagerService"); } private void enforceExpandStatusBar() { - mContext.enforceCallingOrSelfPermission( - android.Manifest.permission.EXPAND_STATUS_BAR, + mContext.enforceCallingOrSelfPermission(android.Manifest.permission.EXPAND_STATUS_BAR, "StatusBarManagerService"); } - public void registerStatusBar(IStatusBar bar) { - Slog.d(TAG, "registerStatusBar bar=" + bar); + public void registerStatusBar(IStatusBar bar, StatusBarIconList iconList) { + Slog.i(TAG, "registerStatusBar bar=" + bar); + mBar = bar; + iconList.copyFrom(mIcons); } + public IBinder addNotification(IconData iconData, NotificationData notificationData) { + return new Binder(); + } + + public void updateNotification(IBinder key, IconData iconData, + NotificationData notificationData) { + } + + public void removeNotification(IBinder key) { + } // ================================================================================ // Can be called from any thread // ================================================================================ - public IBinder addIcon(IconData data, NotificationData n) { - if (true) { - return new Binder(); - } - // TODO: Call onto the IStatusBar - int slot; - // assert early-on if they using a slot that doesn't exist. - if (data != null && n == null) { - slot = getRightIconIndex(data.slot); - if (slot < 0) { - throw new SecurityException("invalid status bar icon slot: " - + (data.slot != null ? "'" + data.slot + "'" : "null")); - } - } else { - slot = -1; - } - IBinder key = new Binder(); - addPendingOp(OP_ADD_ICON, key, data, n, -1); - return key; - } - - public void updateIcon(IBinder key, IconData data, NotificationData n) { - addPendingOp(OP_UPDATE_ICON, key, data, n, -1); - } - public void setIconVisibility(IBinder key, boolean visible) { addPendingOp(OP_SET_VISIBLE, key, visible); } @@ -368,7 +279,7 @@ public class StatusBarManagerService extends IStatusBarService.Stub op.integer = i; mQueue.add(op); if (mQueue.size() == 1) { - mHandler.sendEmptyMessage(2); + //mHandler.sendEmptyMessage(2); } } } @@ -381,7 +292,7 @@ public class StatusBarManagerService extends IStatusBarService.Stub op.visible = visible; mQueue.add(op); if (mQueue.size() == 1) { - mHandler.sendEmptyMessage(1); + //mHandler.sendEmptyMessage(1); } } } @@ -393,7 +304,7 @@ public class StatusBarManagerService extends IStatusBarService.Stub op.integer = integer; mQueue.add(op); if (mQueue.size() == 1) { - mHandler.sendEmptyMessage(1); + //mHandler.sendEmptyMessage(1); } } } @@ -450,292 +361,9 @@ public class StatusBarManagerService extends IStatusBarService.Stub return net; } - private int getRightIconIndex(String slot) { - final int N = mRightIconSlots.length; - for (int i=0; i queue; - synchronized (mQueueLock) { - queue = mQueue; - mQueue = new ArrayList(); - } - - boolean wasExpanded = mExpanded; - - // for each one in the queue, find all of the ones with the same key - // and collapse that down into a final op and/or call to setVisibility, etc - boolean expand = wasExpanded; - boolean doExpand = false; - boolean doDisable = false; - int disableWhat = 0; - int N = queue.size(); - while (N > 0) { - PendingOp op = queue.get(0); - boolean doOp = false; - boolean visible = false; - boolean doVisibility = false; - if (op.code == OP_SET_VISIBLE) { - doVisibility = true; - visible = op.visible; - } - else if (op.code == OP_EXPAND) { - doExpand = true; - expand = op.visible; - } - else if (op.code == OP_TOGGLE) { - doExpand = true; - expand = !expand; - } - else { - doOp = true; - } - - if (alwaysHandle(op.code)) { - // coalesce these - for (int i=1; i s - final float y = mAnimY; - final float v = mAnimVel; // px/s - final float a = mAnimAccel; // px/s/s - mAnimY = y + (v*t) + (0.5f*a*t*t); // px - mAnimVel = v + (a*t); // px/s - mAnimLastTime = now; // ms - //Slog.d(TAG, "y=" + y + " v=" + v + " a=" + a + " t=" + t + " mAnimY=" + mAnimY - // + " mAnimAccel=" + mAnimAccel); - } - - void doRevealAnimation() { - final int h = mCloseView.getHeight() + mStatusBarView.getHeight(); - if (mAnimatingReveal && mAnimating && mAnimY < h) { - incrementAnim(); - if (mAnimY >= h) { - mAnimY = h; - updateExpandedViewPos((int)mAnimY); - } else { - updateExpandedViewPos((int)mAnimY); - mCurAnimationTime += ANIM_FRAME_DURATION; - mHandler.sendMessageAtTime(mHandler.obtainMessage(MSG_ANIMATE_REVEAL), - mCurAnimationTime); - } - } - } - - void prepareTracking(int y, boolean opening) { - mTracking = true; - mVelocityTracker = VelocityTracker.obtain(); - if (opening) { - mAnimAccel = 2000.0f; - mAnimVel = 200; - mAnimY = mStatusBarView.getHeight(); - updateExpandedViewPos((int)mAnimY); - mAnimating = true; - mAnimatingReveal = true; - mHandler.removeMessages(MSG_ANIMATE); - mHandler.removeMessages(MSG_ANIMATE_REVEAL); - long now = SystemClock.uptimeMillis(); - mAnimLastTime = now; - mCurAnimationTime = now + ANIM_FRAME_DURATION; - mAnimating = true; - mHandler.sendMessageAtTime(mHandler.obtainMessage(MSG_ANIMATE_REVEAL), - mCurAnimationTime); - makeExpandedVisible(); - } else { - // it's open, close it? - if (mAnimating) { - mAnimating = false; - mHandler.removeMessages(MSG_ANIMATE); - } - updateExpandedViewPos(y + mViewDelta); - } - } - - void performFling(int y, float vel, boolean always) { - mAnimatingReveal = false; - mDisplayHeight = mDisplay.getHeight(); - - mAnimY = y; - mAnimVel = vel; - - //Slog.d(TAG, "starting with mAnimY=" + mAnimY + " mAnimVel=" + mAnimVel); - - if (mExpanded) { - if (!always && ( - vel > 200.0f - || (y > (mDisplayHeight-25) && vel > -200.0f))) { - // We are expanded, but they didn't move sufficiently to cause - // us to retract. Animate back to the expanded position. - mAnimAccel = 2000.0f; - if (vel < 0) { - mAnimVel = 0; - } - } - else { - // We are expanded and are now going to animate away. - mAnimAccel = -2000.0f; - if (vel > 0) { - mAnimVel = 0; - } - } - } else { - if (always || ( - vel > 200.0f - || (y > (mDisplayHeight/2) && vel > -200.0f))) { - // We are collapsed, and they moved enough to allow us to - // expand. Animate in the notifications. - mAnimAccel = 2000.0f; - if (vel < 0) { - mAnimVel = 0; - } - } - else { - // We are collapsed, but they didn't move sufficiently to cause - // us to retract. Animate back to the collapsed position. - mAnimAccel = -2000.0f; - if (vel > 0) { - mAnimVel = 0; - } - } - } - //Slog.d(TAG, "mAnimY=" + mAnimY + " mAnimVel=" + mAnimVel - // + " mAnimAccel=" + mAnimAccel); - - long now = SystemClock.uptimeMillis(); - mAnimLastTime = now; - mCurAnimationTime = now + ANIM_FRAME_DURATION; - mAnimating = true; - mHandler.removeMessages(MSG_ANIMATE); - mHandler.removeMessages(MSG_ANIMATE_REVEAL); - mHandler.sendMessageAtTime(mHandler.obtainMessage(MSG_ANIMATE), mCurAnimationTime); - stopTracking(); - } - - boolean interceptTouchEvent(MotionEvent event) { - if (SPEW) { - Slog.d(TAG, "Touch: rawY=" + event.getRawY() + " event=" + event + " mDisabled=" - + mDisabled); - } - - if ((mDisabled & StatusBarManager.DISABLE_EXPAND) != 0) { - return false; - } - - final int statusBarSize = mStatusBarView.getHeight(); - final int hitSize = statusBarSize*2; - if (event.getAction() == MotionEvent.ACTION_DOWN) { - final int y = (int)event.getRawY(); - - if (!mExpanded) { - mViewDelta = statusBarSize - y; - } else { - mTrackingView.getLocationOnScreen(mAbsPos); - mViewDelta = mAbsPos[1] + mTrackingView.getHeight() - y; - } - if ((!mExpanded && y < hitSize) || - (mExpanded && y > (mDisplay.getHeight()-hitSize))) { - - // We drop events at the edge of the screen to make the windowshade come - // down by accident less, especially when pushing open a device with a keyboard - // that rotates (like g1 and droid) - int x = (int)event.getRawX(); - final int edgeBorder = mEdgeBorder; - if (x >= edgeBorder && x < mDisplay.getWidth() - edgeBorder) { - prepareTracking(y, !mExpanded);// opening if we're not already fully visible - mVelocityTracker.addMovement(event); - } - } - } else if (mTracking) { - mVelocityTracker.addMovement(event); - final int minY = statusBarSize + mCloseView.getHeight(); - if (event.getAction() == MotionEvent.ACTION_MOVE) { - int y = (int)event.getRawY(); - if (mAnimatingReveal && y < minY) { - // nothing - } else { - mAnimatingReveal = false; - updateExpandedViewPos(y + mViewDelta); - } - } else if (event.getAction() == MotionEvent.ACTION_UP) { - mVelocityTracker.computeCurrentVelocity(1000); - - float yVel = mVelocityTracker.getYVelocity(); - boolean negative = yVel < 0; - - float xVel = mVelocityTracker.getXVelocity(); - if (xVel < 0) { - xVel = -xVel; - } - if (xVel > 150.0f) { - xVel = 150.0f; // limit how much we care about the x axis - } - - float vel = (float)Math.hypot(yVel, xVel); - if (negative) { - vel = -vel; - } - - performFling((int)event.getRawY(), vel, false); - } - - } - return false; - } - - private class Launcher implements View.OnClickListener { - private PendingIntent mIntent; - private String mPkg; - private String mTag; - private int mId; - - Launcher(PendingIntent intent, String pkg, String tag, int id) { - mIntent = intent; - mPkg = pkg; - mTag = tag; - mId = id; - } - - public void onClick(View v) { - try { - // The intent we are sending is for the application, which - // won't have permission to immediately start an activity after - // the user switches to home. We know it is safe to do at this - // point, so make sure new activity switches are now allowed. - ActivityManagerNative.getDefault().resumeAppSwitches(); - } catch (RemoteException e) { - } - int[] pos = new int[2]; - v.getLocationOnScreen(pos); - Intent overlay = new Intent(); - overlay.setSourceBounds( - new Rect(pos[0], pos[1], pos[0]+v.getWidth(), pos[1]+v.getHeight())); - try { - mIntent.send(mContext, 0, overlay); - mNotificationCallbacks.onNotificationClick(mPkg, mTag, mId); - } catch (PendingIntent.CanceledException e) { - // the stack trace isn't very helpful here. Just log the exception message. - Slog.w(TAG, "Sending contentIntent failed: " + e); - } - deactivate(); - } - } - - Animation.AnimationListener mTickingDoneListener = new Animation.AnimationListener() {; - public void onAnimationEnd(Animation animation) { - mTicking = false; - } - public void onAnimationRepeat(Animation animation) { - } - public void onAnimationStart(Animation animation) { - } - }; - - private Animation loadAnim(int id, Animation.AnimationListener listener) { - Animation anim = AnimationUtils.loadAnimation(mContext, id); - if (listener != null) { - anim.setAnimationListener(listener); - } - return anim; - } - - public String viewInfo(View v) { - return "(" + v.getLeft() + "," + v.getTop() + ")(" + v.getRight() + "," + v.getBottom() - + " " + v.getWidth() + "x" + v.getHeight() + ")"; - } - protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) != PackageManager.PERMISSION_GRANTED) { @@ -1280,22 +379,16 @@ public class StatusBarManagerService extends IStatusBarService.Stub + ", uid=" + Binder.getCallingUid()); return; } + + Slog.d(TAG, "dump!!!"); + pw.println("status!"); + + synchronized (mIcons) { + mIcons.dump(pw); + } synchronized (mQueueLock) { pw.println("Current Status Bar state:"); - pw.println(" mExpanded=" + mExpanded - + ", mExpandedVisible=" + mExpandedVisible); - pw.println(" mTicking=" + mTicking); - pw.println(" mTracking=" + mTracking); - pw.println(" mAnimating=" + mAnimating - + ", mAnimY=" + mAnimY + ", mAnimVel=" + mAnimVel - + ", mAnimAccel=" + mAnimAccel); - pw.println(" mCurAnimationTime=" + mCurAnimationTime - + " mAnimLastTime=" + mAnimLastTime); - pw.println(" mDisplayHeight=" + mDisplayHeight - + " mAnimatingReveal=" + mAnimatingReveal - + " mViewDelta=" + mViewDelta); - pw.println(" mDisplayHeight=" + mDisplayHeight); final int N = mQueue.size(); pw.println(" mQueue.size=" + N); for (int i=0; i