19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 177a0f36bd93ad8a5b8cb3e1fe56dbdb43a0ad3a57Joe Onoratopackage com.android.server; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.app.StatusBarManager; 205feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandlerimport android.service.notification.StatusBarNotification; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.BroadcastReceiver; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Intent; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.pm.PackageManager; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.Resources; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Binder; 27f3f0e053f0cc66249a11639eb67d0cdc2da26dedJoe Onoratoimport android.os.Handler; 286179ea3196e9306d3f14361fe9ef14191b1edba6Svetoslav Ganovimport android.os.IBinder; 296179ea3196e9306d3f14361fe9ef14191b1edba6Svetoslav Ganovimport android.os.RemoteException; 3098edc951712823dbf5db2b7e9c203a0e98fc616bAmith Yamasaniimport android.os.UserHandle; 318a9b22056b13477f59df934928c00c58b5871c95Joe Onoratoimport android.util.Slog; 320cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato 330cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onoratoimport com.android.internal.statusbar.IStatusBar; 340cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onoratoimport com.android.internal.statusbar.IStatusBarService; 350cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onoratoimport com.android.internal.statusbar.StatusBarIcon; 360cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onoratoimport com.android.internal.statusbar.StatusBarIconList; 37a924dc0db952fe32509435fdb8dc9c84a9e181f3Dianne Hackbornimport com.android.server.wm.WindowManagerService; 38105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileDescriptor; 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.PrintWriter; 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList; 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.HashMap; 4375199e3ddcf7886c8ee5fbf8b486a8c21335bf14Joe Onoratoimport java.util.List; 4475199e3ddcf7886c8ee5fbf8b486a8c21335bf14Joe Onoratoimport java.util.Map; 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 48f3f0e053f0cc66249a11639eb67d0cdc2da26dedJoe Onorato * A note on locking: We rely on the fact that calls onto mBar are oneway or 49f3f0e053f0cc66249a11639eb67d0cdc2da26dedJoe Onorato * if they are local, that they just enqueue messages to not deadlock. 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 51089de88fc2f08d284cf8031aa33cff06011a4162Joe Onoratopublic class StatusBarManagerService extends IStatusBarService.Stub 522992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown implements WindowManagerService.OnHardKeyboardStatusChangeListener 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 544762c2d75a55e0854bbff2f996748116d4ab1a37Joe Onorato static final String TAG = "StatusBarManagerService"; 55431bb2269532f2514861b908d5fafda8fa64da79Joe Onorato static final boolean SPEW = false; 56df7dbb68d330eae88c1ca6d03390dc8c18386871Joe Onorato 57f3f0e053f0cc66249a11639eb67d0cdc2da26dedJoe Onorato final Context mContext; 582992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown final WindowManagerService mWindowManager; 59f3f0e053f0cc66249a11639eb67d0cdc2da26dedJoe Onorato Handler mHandler = new Handler(); 60f3f0e053f0cc66249a11639eb67d0cdc2da26dedJoe Onorato NotificationCallbacks mNotificationCallbacks; 614762c2d75a55e0854bbff2f996748116d4ab1a37Joe Onorato volatile IStatusBar mBar; 62f3f0e053f0cc66249a11639eb67d0cdc2da26dedJoe Onorato StatusBarIconList mIcons = new StatusBarIconList(); 6375199e3ddcf7886c8ee5fbf8b486a8c21335bf14Joe Onorato HashMap<IBinder,StatusBarNotification> mNotifications 6475199e3ddcf7886c8ee5fbf8b486a8c21335bf14Joe Onorato = new HashMap<IBinder,StatusBarNotification>(); 65f3f0e053f0cc66249a11639eb67d0cdc2da26dedJoe Onorato 66f3f0e053f0cc66249a11639eb67d0cdc2da26dedJoe Onorato // for disabling the status bar 6713451a25fff12c1429f9ecdc24b2aa7696359f7dJohn Spurlock final ArrayList<DisableRecord> mDisableRecords = new ArrayList<DisableRecord>(); 687bb8eeb90cf55f409a282c1f36ca08aa48c10543Joe Onorato IBinder mSysUiVisToken = new Binder(); 69f3f0e053f0cc66249a11639eb67d0cdc2da26dedJoe Onorato int mDisabled = 0; 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 719305647eb61bb60a1f42481a0c0d208dc9bbe965Joe Onorato Object mLock = new Object(); 7260ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler // encompasses lights-out mode and other flags defined on View 7360ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler int mSystemUiVisibility = 0; 74e02d808abf370965c3c4e4d38af11bc69110fde2Daniel Sandler boolean mMenuVisible = false; 75857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato int mImeWindowVis = 0; 76857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato int mImeBackDisposition; 77857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato IBinder mImeToken = null; 7813451a25fff12c1429f9ecdc24b2aa7696359f7dJohn Spurlock int mCurrentUserId; 7906487a58be22b100daf3f950b9a1d25c3ea42aa2satok 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class DisableRecord implements IBinder.DeathRecipient { 8113451a25fff12c1429f9ecdc24b2aa7696359f7dJohn Spurlock int userId; 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String pkg; 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int what; 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IBinder token; 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void binderDied() { 878a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.i(TAG, "binder died for pkg=" + pkg); 8813451a25fff12c1429f9ecdc24b2aa7696359f7dJohn Spurlock disableInternal(userId, 0, token, pkg); 89fff2fda0199dedbf1079454dca98a81190dce765Suchi Amalapurapu token.unlinkToDeath(this, 0); 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public interface NotificationCallbacks { 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void onSetDisabled(int status); 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void onClearAll(); 966ecaff15836581336b1e8fad6ac42f3ff4a13544Fred Quintana void onNotificationClick(String pkg, String tag, int id); 970f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler void onNotificationClear(String pkg, String tag, int id); 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void onPanelRevealed(); 999d39d0cb361c5d3bba04a6bacf299be2162a6e92Dianne Hackborn void onNotificationError(String pkg, String tag, int id, 1009d39d0cb361c5d3bba04a6bacf299be2162a6e92Dianne Hackborn int uid, int initialPid, String message); 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Construct the service, add the status bar view to the window manager 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1062992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown public StatusBarManagerService(Context context, WindowManagerService windowManager) { 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext = context; 1082992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown mWindowManager = windowManager; 1092992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown mWindowManager.setOnHardKeyboardStatusChangeListener(this); 1100cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato 1110cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato final Resources res = context.getResources(); 11275144ea38e79e3827e69a9f5b53a6fd3a74c4df5Joe Onorato mIcons.defineSlots(res.getStringArray(com.android.internal.R.array.config_statusBarIcons)); 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setNotificationCallbacks(NotificationCallbacks listener) { 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNotificationCallbacks = listener; 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // ================================================================================ 12025f95f92005594f2ef094001c54cb4c39eec3adeJoe Onorato // From IStatusBarService 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // ================================================================================ 12211cf178100e71d3f9f34ab5865e03a277c5eadaaDaniel Sandler public void expandNotificationsPanel() { 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project enforceExpandStatusBar(); 1244762c2d75a55e0854bbff2f996748116d4ab1a37Joe Onorato 1254762c2d75a55e0854bbff2f996748116d4ab1a37Joe Onorato if (mBar != null) { 1264762c2d75a55e0854bbff2f996748116d4ab1a37Joe Onorato try { 12711cf178100e71d3f9f34ab5865e03a277c5eadaaDaniel Sandler mBar.animateExpandNotificationsPanel(); 1284762c2d75a55e0854bbff2f996748116d4ab1a37Joe Onorato } catch (RemoteException ex) { 1294762c2d75a55e0854bbff2f996748116d4ab1a37Joe Onorato } 1304762c2d75a55e0854bbff2f996748116d4ab1a37Joe Onorato } 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13311cf178100e71d3f9f34ab5865e03a277c5eadaaDaniel Sandler public void collapsePanels() { 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project enforceExpandStatusBar(); 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1364762c2d75a55e0854bbff2f996748116d4ab1a37Joe Onorato if (mBar != null) { 1374762c2d75a55e0854bbff2f996748116d4ab1a37Joe Onorato try { 13811cf178100e71d3f9f34ab5865e03a277c5eadaaDaniel Sandler mBar.animateCollapsePanels(); 139e20a177d3f147f3011647c3bdab401f90b2c5d1dSvetoslav Ganov } catch (RemoteException ex) { 140e20a177d3f147f3011647c3bdab401f90b2c5d1dSvetoslav Ganov } 141e20a177d3f147f3011647c3bdab401f90b2c5d1dSvetoslav Ganov } 142e20a177d3f147f3011647c3bdab401f90b2c5d1dSvetoslav Ganov } 143e20a177d3f147f3011647c3bdab401f90b2c5d1dSvetoslav Ganov 14411cf178100e71d3f9f34ab5865e03a277c5eadaaDaniel Sandler public void expandSettingsPanel() { 145e20a177d3f147f3011647c3bdab401f90b2c5d1dSvetoslav Ganov enforceExpandStatusBar(); 146e20a177d3f147f3011647c3bdab401f90b2c5d1dSvetoslav Ganov 147e20a177d3f147f3011647c3bdab401f90b2c5d1dSvetoslav Ganov if (mBar != null) { 148e20a177d3f147f3011647c3bdab401f90b2c5d1dSvetoslav Ganov try { 14911cf178100e71d3f9f34ab5865e03a277c5eadaaDaniel Sandler mBar.animateExpandSettingsPanel(); 1504762c2d75a55e0854bbff2f996748116d4ab1a37Joe Onorato } catch (RemoteException ex) { 1514762c2d75a55e0854bbff2f996748116d4ab1a37Joe Onorato } 1524762c2d75a55e0854bbff2f996748116d4ab1a37Joe Onorato } 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void disable(int what, IBinder token, String pkg) { 15613451a25fff12c1429f9ecdc24b2aa7696359f7dJohn Spurlock disableInternal(mCurrentUserId, what, token, pkg); 15713451a25fff12c1429f9ecdc24b2aa7696359f7dJohn Spurlock } 15813451a25fff12c1429f9ecdc24b2aa7696359f7dJohn Spurlock 15913451a25fff12c1429f9ecdc24b2aa7696359f7dJohn Spurlock private void disableInternal(int userId, int what, IBinder token, String pkg) { 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project enforceStatusBar(); 161f3f0e053f0cc66249a11639eb67d0cdc2da26dedJoe Onorato 1627bb8eeb90cf55f409a282c1f36ca08aa48c10543Joe Onorato synchronized (mLock) { 16313451a25fff12c1429f9ecdc24b2aa7696359f7dJohn Spurlock disableLocked(userId, what, token, pkg); 1647bb8eeb90cf55f409a282c1f36ca08aa48c10543Joe Onorato } 1657bb8eeb90cf55f409a282c1f36ca08aa48c10543Joe Onorato } 1667bb8eeb90cf55f409a282c1f36ca08aa48c10543Joe Onorato 16713451a25fff12c1429f9ecdc24b2aa7696359f7dJohn Spurlock private void disableLocked(int userId, int what, IBinder token, String pkg) { 168f3f0e053f0cc66249a11639eb67d0cdc2da26dedJoe Onorato // It's important that the the callback and the call to mBar get done 169f3f0e053f0cc66249a11639eb67d0cdc2da26dedJoe Onorato // in the same order when multiple threads are calling this function 170f3f0e053f0cc66249a11639eb67d0cdc2da26dedJoe Onorato // so they are paired correctly. The messages on the handler will be 171f3f0e053f0cc66249a11639eb67d0cdc2da26dedJoe Onorato // handled in the order they were enqueued, but will be outside the lock. 17213451a25fff12c1429f9ecdc24b2aa7696359f7dJohn Spurlock manageDisableListLocked(userId, what, token, pkg); 1738f3e6d5c836353444082e4696f5e933266384580John Spurlock 1748f3e6d5c836353444082e4696f5e933266384580John Spurlock // Ensure state for the current user is applied, even if passed a non-current user. 1758f3e6d5c836353444082e4696f5e933266384580John Spurlock final int net = gatherDisableActionsLocked(mCurrentUserId); 1767bb8eeb90cf55f409a282c1f36ca08aa48c10543Joe Onorato if (net != mDisabled) { 1777bb8eeb90cf55f409a282c1f36ca08aa48c10543Joe Onorato mDisabled = net; 1787bb8eeb90cf55f409a282c1f36ca08aa48c10543Joe Onorato mHandler.post(new Runnable() { 1797bb8eeb90cf55f409a282c1f36ca08aa48c10543Joe Onorato public void run() { 1807bb8eeb90cf55f409a282c1f36ca08aa48c10543Joe Onorato mNotificationCallbacks.onSetDisabled(net); 181f3f0e053f0cc66249a11639eb67d0cdc2da26dedJoe Onorato } 1827bb8eeb90cf55f409a282c1f36ca08aa48c10543Joe Onorato }); 1837bb8eeb90cf55f409a282c1f36ca08aa48c10543Joe Onorato if (mBar != null) { 1847bb8eeb90cf55f409a282c1f36ca08aa48c10543Joe Onorato try { 1857bb8eeb90cf55f409a282c1f36ca08aa48c10543Joe Onorato mBar.disable(net); 1867bb8eeb90cf55f409a282c1f36ca08aa48c10543Joe Onorato } catch (RemoteException ex) { 187f3f0e053f0cc66249a11639eb67d0cdc2da26dedJoe Onorato } 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1926179ea3196e9306d3f14361fe9ef14191b1edba6Svetoslav Ganov public void setIcon(String slot, String iconPackage, int iconId, int iconLevel, 1936179ea3196e9306d3f14361fe9ef14191b1edba6Svetoslav Ganov String contentDescription) { 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project enforceStatusBar(); 1950cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato 1960cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato synchronized (mIcons) { 1970cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato int index = mIcons.getSlotIndex(slot); 1980cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato if (index < 0) { 1990cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato throw new SecurityException("invalid status bar icon slot: " + slot); 2000cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato } 2010cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato 20298edc951712823dbf5db2b7e9c203a0e98fc616bAmith Yamasani StatusBarIcon icon = new StatusBarIcon(iconPackage, UserHandle.OWNER, iconId, 20398edc951712823dbf5db2b7e9c203a0e98fc616bAmith Yamasani iconLevel, 0, 2046179ea3196e9306d3f14361fe9ef14191b1edba6Svetoslav Ganov contentDescription); 20566d7d01ed91968f4ed2e2669fd306aa2af61cd16Joe Onorato //Slog.d(TAG, "setIcon slot=" + slot + " index=" + index + " icon=" + icon); 2060cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato mIcons.setIcon(index, icon); 2070cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato 2080cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato if (mBar != null) { 2090cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato try { 2100cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato mBar.setIcon(index, icon); 2110cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato } catch (RemoteException ex) { 2120cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato } 2130cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato } 2140cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato } 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2170cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato public void setIconVisibility(String slot, boolean visible) { 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project enforceStatusBar(); 2190cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato 220514ad663f0a8b239cc59409175e0bd489c591aa0Joe Onorato synchronized (mIcons) { 221514ad663f0a8b239cc59409175e0bd489c591aa0Joe Onorato int index = mIcons.getSlotIndex(slot); 222514ad663f0a8b239cc59409175e0bd489c591aa0Joe Onorato if (index < 0) { 223514ad663f0a8b239cc59409175e0bd489c591aa0Joe Onorato throw new SecurityException("invalid status bar icon slot: " + slot); 224514ad663f0a8b239cc59409175e0bd489c591aa0Joe Onorato } 225514ad663f0a8b239cc59409175e0bd489c591aa0Joe Onorato 226514ad663f0a8b239cc59409175e0bd489c591aa0Joe Onorato StatusBarIcon icon = mIcons.getIcon(index); 227514ad663f0a8b239cc59409175e0bd489c591aa0Joe Onorato if (icon == null) { 228514ad663f0a8b239cc59409175e0bd489c591aa0Joe Onorato return; 229514ad663f0a8b239cc59409175e0bd489c591aa0Joe Onorato } 230514ad663f0a8b239cc59409175e0bd489c591aa0Joe Onorato 231514ad663f0a8b239cc59409175e0bd489c591aa0Joe Onorato if (icon.visible != visible) { 232514ad663f0a8b239cc59409175e0bd489c591aa0Joe Onorato icon.visible = visible; 233514ad663f0a8b239cc59409175e0bd489c591aa0Joe Onorato 234514ad663f0a8b239cc59409175e0bd489c591aa0Joe Onorato if (mBar != null) { 235514ad663f0a8b239cc59409175e0bd489c591aa0Joe Onorato try { 236514ad663f0a8b239cc59409175e0bd489c591aa0Joe Onorato mBar.setIcon(index, icon); 237514ad663f0a8b239cc59409175e0bd489c591aa0Joe Onorato } catch (RemoteException ex) { 238514ad663f0a8b239cc59409175e0bd489c591aa0Joe Onorato } 239514ad663f0a8b239cc59409175e0bd489c591aa0Joe Onorato } 240514ad663f0a8b239cc59409175e0bd489c591aa0Joe Onorato } 241514ad663f0a8b239cc59409175e0bd489c591aa0Joe Onorato } 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2440cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato public void removeIcon(String slot) { 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project enforceStatusBar(); 2460cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato 2470cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato synchronized (mIcons) { 2480cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato int index = mIcons.getSlotIndex(slot); 2490cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato if (index < 0) { 2500cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato throw new SecurityException("invalid status bar icon slot: " + slot); 2510cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato } 2520cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato 2530cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato mIcons.removeIcon(index); 2540cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato 2550cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato if (mBar != null) { 2560cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato try { 2570cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato mBar.removeIcon(index); 2580cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato } catch (RemoteException ex) { 2590cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato } 2600cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato } 2610cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato } 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 264e02d808abf370965c3c4e4d38af11bc69110fde2Daniel Sandler /** 265e02d808abf370965c3c4e4d38af11bc69110fde2Daniel Sandler * Hide or show the on-screen Menu key. Only call this from the window manager, typically in 266e02d808abf370965c3c4e4d38af11bc69110fde2Daniel Sandler * response to a window with FLAG_NEEDS_MENU_KEY set. 267e02d808abf370965c3c4e4d38af11bc69110fde2Daniel Sandler */ 2687d04932ef5c001769ccef244f551b75773f1666bDianne Hackborn public void topAppWindowChanged(final boolean menuVisible) { 269e02d808abf370965c3c4e4d38af11bc69110fde2Daniel Sandler enforceStatusBar(); 270e02d808abf370965c3c4e4d38af11bc69110fde2Daniel Sandler 2717d04932ef5c001769ccef244f551b75773f1666bDianne Hackborn if (SPEW) Slog.d(TAG, (menuVisible?"showing":"hiding") + " MENU key"); 272e02d808abf370965c3c4e4d38af11bc69110fde2Daniel Sandler 273e02d808abf370965c3c4e4d38af11bc69110fde2Daniel Sandler synchronized(mLock) { 2747d04932ef5c001769ccef244f551b75773f1666bDianne Hackborn mMenuVisible = menuVisible; 2757d04932ef5c001769ccef244f551b75773f1666bDianne Hackborn mHandler.post(new Runnable() { 2767d04932ef5c001769ccef244f551b75773f1666bDianne Hackborn public void run() { 2777d04932ef5c001769ccef244f551b75773f1666bDianne Hackborn if (mBar != null) { 2787d04932ef5c001769ccef244f551b75773f1666bDianne Hackborn try { 2797d04932ef5c001769ccef244f551b75773f1666bDianne Hackborn mBar.topAppWindowChanged(menuVisible); 2807d04932ef5c001769ccef244f551b75773f1666bDianne Hackborn } catch (RemoteException ex) { 281e02d808abf370965c3c4e4d38af11bc69110fde2Daniel Sandler } 282e02d808abf370965c3c4e4d38af11bc69110fde2Daniel Sandler } 2837d04932ef5c001769ccef244f551b75773f1666bDianne Hackborn } 2847d04932ef5c001769ccef244f551b75773f1666bDianne Hackborn }); 285e02d808abf370965c3c4e4d38af11bc69110fde2Daniel Sandler } 286e02d808abf370965c3c4e4d38af11bc69110fde2Daniel Sandler } 287e02d808abf370965c3c4e4d38af11bc69110fde2Daniel Sandler 288857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato public void setImeWindowStatus(final IBinder token, final int vis, final int backDisposition) { 28906487a58be22b100daf3f950b9a1d25c3ea42aa2satok enforceStatusBar(); 29006487a58be22b100daf3f950b9a1d25c3ea42aa2satok 291857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato if (SPEW) { 292857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato Slog.d(TAG, "swetImeWindowStatus vis=" + vis + " backDisposition=" + backDisposition); 293857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato } 29406487a58be22b100daf3f950b9a1d25c3ea42aa2satok 29506487a58be22b100daf3f950b9a1d25c3ea42aa2satok synchronized(mLock) { 296857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato // In case of IME change, we need to call up setImeWindowStatus() regardless of 297857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato // mImeWindowVis because mImeWindowVis may not have been set to false when the 29806e0744e9e1a04a07e2e1bf9279124223bd674dasatok // previous IME was destroyed. 299857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato mImeWindowVis = vis; 300857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato mImeBackDisposition = backDisposition; 301857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato mImeToken = token; 30206e0744e9e1a04a07e2e1bf9279124223bd674dasatok mHandler.post(new Runnable() { 30306e0744e9e1a04a07e2e1bf9279124223bd674dasatok public void run() { 30406e0744e9e1a04a07e2e1bf9279124223bd674dasatok if (mBar != null) { 30506e0744e9e1a04a07e2e1bf9279124223bd674dasatok try { 306857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato mBar.setImeWindowStatus(token, vis, backDisposition); 30706e0744e9e1a04a07e2e1bf9279124223bd674dasatok } catch (RemoteException ex) { 30806487a58be22b100daf3f950b9a1d25c3ea42aa2satok } 30906487a58be22b100daf3f950b9a1d25c3ea42aa2satok } 31006e0744e9e1a04a07e2e1bf9279124223bd674dasatok } 31106e0744e9e1a04a07e2e1bf9279124223bd674dasatok }); 31206487a58be22b100daf3f950b9a1d25c3ea42aa2satok } 31306487a58be22b100daf3f950b9a1d25c3ea42aa2satok } 31406487a58be22b100daf3f950b9a1d25c3ea42aa2satok 3153a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn public void setSystemUiVisibility(int vis, int mask) { 31655bf3809b98dad0b8268804e684d63ea59124148Joe Onorato // also allows calls from window manager which is in this process. 317f63b0f44eb53f535a65bd83dbc1d8b95abc501daJoe Onorato enforceStatusBarService(); 318f63b0f44eb53f535a65bd83dbc1d8b95abc501daJoe Onorato 3194519a02608b9e02a2c0dbc7dff37c21167db8f24Jeff Sharkey if (SPEW) Slog.d(TAG, "setSystemUiVisibility(0x" + Integer.toHexString(vis) + ")"); 32060ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler 321f63b0f44eb53f535a65bd83dbc1d8b95abc501daJoe Onorato synchronized (mLock) { 3223a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn updateUiVisibilityLocked(vis, mask); 32313451a25fff12c1429f9ecdc24b2aa7696359f7dJohn Spurlock disableLocked( 32413451a25fff12c1429f9ecdc24b2aa7696359f7dJohn Spurlock mCurrentUserId, 32513451a25fff12c1429f9ecdc24b2aa7696359f7dJohn Spurlock vis & StatusBarManager.DISABLE_MASK, 32613451a25fff12c1429f9ecdc24b2aa7696359f7dJohn Spurlock mSysUiVisToken, 3277bb8eeb90cf55f409a282c1f36ca08aa48c10543Joe Onorato "WindowManager.LayoutParams"); 328f63b0f44eb53f535a65bd83dbc1d8b95abc501daJoe Onorato } 329f63b0f44eb53f535a65bd83dbc1d8b95abc501daJoe Onorato } 330f63b0f44eb53f535a65bd83dbc1d8b95abc501daJoe Onorato 3313a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn private void updateUiVisibilityLocked(final int vis, final int mask) { 33260ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler if (mSystemUiVisibility != vis) { 33360ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler mSystemUiVisibility = vis; 334f63b0f44eb53f535a65bd83dbc1d8b95abc501daJoe Onorato mHandler.post(new Runnable() { 335f63b0f44eb53f535a65bd83dbc1d8b95abc501daJoe Onorato public void run() { 336f63b0f44eb53f535a65bd83dbc1d8b95abc501daJoe Onorato if (mBar != null) { 337f63b0f44eb53f535a65bd83dbc1d8b95abc501daJoe Onorato try { 3383a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn mBar.setSystemUiVisibility(vis, mask); 339f63b0f44eb53f535a65bd83dbc1d8b95abc501daJoe Onorato } catch (RemoteException ex) { 3409305647eb61bb60a1f42481a0c0d208dc9bbe965Joe Onorato } 3419305647eb61bb60a1f42481a0c0d208dc9bbe965Joe Onorato } 342f63b0f44eb53f535a65bd83dbc1d8b95abc501daJoe Onorato } 343f63b0f44eb53f535a65bd83dbc1d8b95abc501daJoe Onorato }); 3449305647eb61bb60a1f42481a0c0d208dc9bbe965Joe Onorato } 3459305647eb61bb60a1f42481a0c0d208dc9bbe965Joe Onorato } 3469305647eb61bb60a1f42481a0c0d208dc9bbe965Joe Onorato 3472992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown public void setHardKeyboardEnabled(final boolean enabled) { 3482992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown mHandler.post(new Runnable() { 3492992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown public void run() { 3502992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown mWindowManager.setHardKeyboardEnabled(enabled); 3512992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown } 3522992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown }); 3532992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown } 3542992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown 3552992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown @Override 3562992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown public void onHardKeyboardStatusChange(final boolean available, final boolean enabled) { 3572992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown mHandler.post(new Runnable() { 3582992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown public void run() { 3592992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown if (mBar != null) { 3602992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown try { 3612992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown mBar.setHardKeyboardStatus(available, enabled); 3622992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown } catch (RemoteException ex) { 3632992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown } 3642992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown } 3652992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown } 3662992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown }); 3672992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown } 3682992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown 3693b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka @Override 3703b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka public void toggleRecentApps() { 3713b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka if (mBar != null) { 3723b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka try { 3733b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka mBar.toggleRecentApps(); 3743b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka } catch (RemoteException ex) {} 3753b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka } 3763b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka } 3773b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka 3787f2668c8469934ce83a5647977f6e74ab782cf07Michael Jurka @Override 3797f2668c8469934ce83a5647977f6e74ab782cf07Michael Jurka public void preloadRecentApps() { 3807f2668c8469934ce83a5647977f6e74ab782cf07Michael Jurka if (mBar != null) { 3817f2668c8469934ce83a5647977f6e74ab782cf07Michael Jurka try { 3827f2668c8469934ce83a5647977f6e74ab782cf07Michael Jurka mBar.preloadRecentApps(); 3837f2668c8469934ce83a5647977f6e74ab782cf07Michael Jurka } catch (RemoteException ex) {} 3847f2668c8469934ce83a5647977f6e74ab782cf07Michael Jurka } 3857f2668c8469934ce83a5647977f6e74ab782cf07Michael Jurka } 3867f2668c8469934ce83a5647977f6e74ab782cf07Michael Jurka 3877f2668c8469934ce83a5647977f6e74ab782cf07Michael Jurka @Override 3887f2668c8469934ce83a5647977f6e74ab782cf07Michael Jurka public void cancelPreloadRecentApps() { 3897f2668c8469934ce83a5647977f6e74ab782cf07Michael Jurka if (mBar != null) { 3907f2668c8469934ce83a5647977f6e74ab782cf07Michael Jurka try { 3917f2668c8469934ce83a5647977f6e74ab782cf07Michael Jurka mBar.cancelPreloadRecentApps(); 3927f2668c8469934ce83a5647977f6e74ab782cf07Michael Jurka } catch (RemoteException ex) {} 3937f2668c8469934ce83a5647977f6e74ab782cf07Michael Jurka } 3947f2668c8469934ce83a5647977f6e74ab782cf07Michael Jurka } 3957f2668c8469934ce83a5647977f6e74ab782cf07Michael Jurka 39613451a25fff12c1429f9ecdc24b2aa7696359f7dJohn Spurlock @Override 39713451a25fff12c1429f9ecdc24b2aa7696359f7dJohn Spurlock public void setCurrentUser(int newUserId) { 39813451a25fff12c1429f9ecdc24b2aa7696359f7dJohn Spurlock if (SPEW) Slog.d(TAG, "Setting current user to user " + newUserId); 39913451a25fff12c1429f9ecdc24b2aa7696359f7dJohn Spurlock mCurrentUserId = newUserId; 40013451a25fff12c1429f9ecdc24b2aa7696359f7dJohn Spurlock } 40113451a25fff12c1429f9ecdc24b2aa7696359f7dJohn Spurlock 4029764218ff979f735aee2f1189e3547d5f3b02f83John Spurlock @Override 4039764218ff979f735aee2f1189e3547d5f3b02f83John Spurlock public void setWindowState(int window, int state) { 4049764218ff979f735aee2f1189e3547d5f3b02f83John Spurlock if (mBar != null) { 4059764218ff979f735aee2f1189e3547d5f3b02f83John Spurlock try { 4069764218ff979f735aee2f1189e3547d5f3b02f83John Spurlock mBar.setWindowState(window, state); 4079764218ff979f735aee2f1189e3547d5f3b02f83John Spurlock } catch (RemoteException ex) {} 4089764218ff979f735aee2f1189e3547d5f3b02f83John Spurlock } 4099764218ff979f735aee2f1189e3547d5f3b02f83John Spurlock } 4109764218ff979f735aee2f1189e3547d5f3b02f83John Spurlock 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void enforceStatusBar() { 4120cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato mContext.enforceCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR, 413089de88fc2f08d284cf8031aa33cff06011a4162Joe Onorato "StatusBarManagerService"); 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void enforceExpandStatusBar() { 4170cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato mContext.enforceCallingOrSelfPermission(android.Manifest.permission.EXPAND_STATUS_BAR, 418089de88fc2f08d284cf8031aa33cff06011a4162Joe Onorato "StatusBarManagerService"); 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4218bc6c5141974dbc36a6fe416853f558921be9f24Joe Onorato private void enforceStatusBarService() { 4228bc6c5141974dbc36a6fe416853f558921be9f24Joe Onorato mContext.enforceCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR_SERVICE, 4238bc6c5141974dbc36a6fe416853f558921be9f24Joe Onorato "StatusBarManagerService"); 4248bc6c5141974dbc36a6fe416853f558921be9f24Joe Onorato } 4258bc6c5141974dbc36a6fe416853f558921be9f24Joe Onorato 4264762c2d75a55e0854bbff2f996748116d4ab1a37Joe Onorato // ================================================================================ 4274762c2d75a55e0854bbff2f996748116d4ab1a37Joe Onorato // Callbacks from the status bar service. 4284762c2d75a55e0854bbff2f996748116d4ab1a37Joe Onorato // ================================================================================ 42975199e3ddcf7886c8ee5fbf8b486a8c21335bf14Joe Onorato public void registerStatusBar(IStatusBar bar, StatusBarIconList iconList, 4309305647eb61bb60a1f42481a0c0d208dc9bbe965Joe Onorato List<IBinder> notificationKeys, List<StatusBarNotification> notifications, 431cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok int switches[], List<IBinder> binders) { 4328bc6c5141974dbc36a6fe416853f558921be9f24Joe Onorato enforceStatusBarService(); 4338bc6c5141974dbc36a6fe416853f558921be9f24Joe Onorato 4340cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato Slog.i(TAG, "registerStatusBar bar=" + bar); 4350cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato mBar = bar; 43675199e3ddcf7886c8ee5fbf8b486a8c21335bf14Joe Onorato synchronized (mIcons) { 43775199e3ddcf7886c8ee5fbf8b486a8c21335bf14Joe Onorato iconList.copyFrom(mIcons); 43875199e3ddcf7886c8ee5fbf8b486a8c21335bf14Joe Onorato } 43975199e3ddcf7886c8ee5fbf8b486a8c21335bf14Joe Onorato synchronized (mNotifications) { 44075199e3ddcf7886c8ee5fbf8b486a8c21335bf14Joe Onorato for (Map.Entry<IBinder,StatusBarNotification> e: mNotifications.entrySet()) { 44175199e3ddcf7886c8ee5fbf8b486a8c21335bf14Joe Onorato notificationKeys.add(e.getKey()); 44275199e3ddcf7886c8ee5fbf8b486a8c21335bf14Joe Onorato notifications.add(e.getValue()); 44375199e3ddcf7886c8ee5fbf8b486a8c21335bf14Joe Onorato } 44475199e3ddcf7886c8ee5fbf8b486a8c21335bf14Joe Onorato } 4459305647eb61bb60a1f42481a0c0d208dc9bbe965Joe Onorato synchronized (mLock) { 44613451a25fff12c1429f9ecdc24b2aa7696359f7dJohn Spurlock switches[0] = gatherDisableActionsLocked(mCurrentUserId); 44760ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler switches[1] = mSystemUiVisibility; 448e4c7b3f25ee3cb8d3fba4d15a8fbb97bc83d8dd1Joe Onorato switches[2] = mMenuVisible ? 1 : 0; 449857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato switches[3] = mImeWindowVis; 450857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato switches[4] = mImeBackDisposition; 451857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato binders.add(mImeToken); 4529305647eb61bb60a1f42481a0c0d208dc9bbe965Joe Onorato } 4532992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown switches[5] = mWindowManager.isHardKeyboardAvailable() ? 1 : 0; 4542992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown switches[6] = mWindowManager.isHardKeyboardEnabled() ? 1 : 0; 4552314aab5064ce09f09270e52fa12a38d07464278Joe Onorato } 456aaba60b281713d45a0f232580302c7b54a7207dfJoe Onorato 4574762c2d75a55e0854bbff2f996748116d4ab1a37Joe Onorato /** 458f1f259165ffaa4095afbd50fea47ed091cbc14b3Joe Onorato * The status bar service should call this each time the user brings the panel from 459f1f259165ffaa4095afbd50fea47ed091cbc14b3Joe Onorato * invisible to visible in order to clear the notification light. 4604762c2d75a55e0854bbff2f996748116d4ab1a37Joe Onorato */ 461f1f259165ffaa4095afbd50fea47ed091cbc14b3Joe Onorato public void onPanelRevealed() { 4628bc6c5141974dbc36a6fe416853f558921be9f24Joe Onorato enforceStatusBarService(); 4638bc6c5141974dbc36a6fe416853f558921be9f24Joe Onorato 464f1f259165ffaa4095afbd50fea47ed091cbc14b3Joe Onorato // tell the notification manager to turn off the lights. 465f1f259165ffaa4095afbd50fea47ed091cbc14b3Joe Onorato mNotificationCallbacks.onPanelRevealed(); 4664762c2d75a55e0854bbff2f996748116d4ab1a37Joe Onorato } 4674762c2d75a55e0854bbff2f996748116d4ab1a37Joe Onorato 468aaba60b281713d45a0f232580302c7b54a7207dfJoe Onorato public void onNotificationClick(String pkg, String tag, int id) { 4698bc6c5141974dbc36a6fe416853f558921be9f24Joe Onorato enforceStatusBarService(); 4708bc6c5141974dbc36a6fe416853f558921be9f24Joe Onorato 471aaba60b281713d45a0f232580302c7b54a7207dfJoe Onorato mNotificationCallbacks.onNotificationClick(pkg, tag, id); 472aaba60b281713d45a0f232580302c7b54a7207dfJoe Onorato } 473aaba60b281713d45a0f232580302c7b54a7207dfJoe Onorato 4749d39d0cb361c5d3bba04a6bacf299be2162a6e92Dianne Hackborn public void onNotificationError(String pkg, String tag, int id, 4759d39d0cb361c5d3bba04a6bacf299be2162a6e92Dianne Hackborn int uid, int initialPid, String message) { 4768bc6c5141974dbc36a6fe416853f558921be9f24Joe Onorato enforceStatusBarService(); 4778bc6c5141974dbc36a6fe416853f558921be9f24Joe Onorato 478005847b03b2ebe3eb1a974a8a04ad51bca6636cdJoe Onorato // WARNING: this will call back into us to do the remove. Don't hold any locks. 4799d39d0cb361c5d3bba04a6bacf299be2162a6e92Dianne Hackborn mNotificationCallbacks.onNotificationError(pkg, tag, id, uid, initialPid, message); 480005847b03b2ebe3eb1a974a8a04ad51bca6636cdJoe Onorato } 481005847b03b2ebe3eb1a974a8a04ad51bca6636cdJoe Onorato 4820f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler public void onNotificationClear(String pkg, String tag, int id) { 4830f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler enforceStatusBarService(); 4840f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler 4850f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler mNotificationCallbacks.onNotificationClear(pkg, tag, id); 4860f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler } 4870f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler 488aaba60b281713d45a0f232580302c7b54a7207dfJoe Onorato public void onClearAllNotifications() { 4898bc6c5141974dbc36a6fe416853f558921be9f24Joe Onorato enforceStatusBarService(); 4908bc6c5141974dbc36a6fe416853f558921be9f24Joe Onorato 491aaba60b281713d45a0f232580302c7b54a7207dfJoe Onorato mNotificationCallbacks.onClearAll(); 492aaba60b281713d45a0f232580302c7b54a7207dfJoe Onorato } 493aaba60b281713d45a0f232580302c7b54a7207dfJoe Onorato 49418e69dfc7235f8a4bfe257f9d1c43539049a22ceJoe Onorato // ================================================================================ 49518e69dfc7235f8a4bfe257f9d1c43539049a22ceJoe Onorato // Callbacks for NotificationManagerService. 49618e69dfc7235f8a4bfe257f9d1c43539049a22ceJoe Onorato // ================================================================================ 49718e69dfc7235f8a4bfe257f9d1c43539049a22ceJoe Onorato public IBinder addNotification(StatusBarNotification notification) { 49818e69dfc7235f8a4bfe257f9d1c43539049a22ceJoe Onorato synchronized (mNotifications) { 499a0c56fe93925d20d9c0b830b9664699ce557e78cJoe Onorato IBinder key = new Binder(); 50075199e3ddcf7886c8ee5fbf8b486a8c21335bf14Joe Onorato mNotifications.put(key, notification); 501e345fff2f80947b0a821f6674c197a02b7bff08eJoe Onorato if (mBar != null) { 502e345fff2f80947b0a821f6674c197a02b7bff08eJoe Onorato try { 503e345fff2f80947b0a821f6674c197a02b7bff08eJoe Onorato mBar.addNotification(key, notification); 504e345fff2f80947b0a821f6674c197a02b7bff08eJoe Onorato } catch (RemoteException ex) { 505e345fff2f80947b0a821f6674c197a02b7bff08eJoe Onorato } 506e345fff2f80947b0a821f6674c197a02b7bff08eJoe Onorato } 50718e69dfc7235f8a4bfe257f9d1c43539049a22ceJoe Onorato return key; 50818e69dfc7235f8a4bfe257f9d1c43539049a22ceJoe Onorato } 5090cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato } 5102314aab5064ce09f09270e52fa12a38d07464278Joe Onorato 51118e69dfc7235f8a4bfe257f9d1c43539049a22ceJoe Onorato public void updateNotification(IBinder key, StatusBarNotification notification) { 51218e69dfc7235f8a4bfe257f9d1c43539049a22ceJoe Onorato synchronized (mNotifications) { 51375199e3ddcf7886c8ee5fbf8b486a8c21335bf14Joe Onorato if (!mNotifications.containsKey(key)) { 51475199e3ddcf7886c8ee5fbf8b486a8c21335bf14Joe Onorato throw new IllegalArgumentException("updateNotification key not found: " + key); 51575199e3ddcf7886c8ee5fbf8b486a8c21335bf14Joe Onorato } 51675199e3ddcf7886c8ee5fbf8b486a8c21335bf14Joe Onorato mNotifications.put(key, notification); 517e345fff2f80947b0a821f6674c197a02b7bff08eJoe Onorato if (mBar != null) { 518e345fff2f80947b0a821f6674c197a02b7bff08eJoe Onorato try { 519e345fff2f80947b0a821f6674c197a02b7bff08eJoe Onorato mBar.updateNotification(key, notification); 520e345fff2f80947b0a821f6674c197a02b7bff08eJoe Onorato } catch (RemoteException ex) { 521e345fff2f80947b0a821f6674c197a02b7bff08eJoe Onorato } 522e345fff2f80947b0a821f6674c197a02b7bff08eJoe Onorato } 52318e69dfc7235f8a4bfe257f9d1c43539049a22ceJoe Onorato } 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5260cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato public void removeNotification(IBinder key) { 52718e69dfc7235f8a4bfe257f9d1c43539049a22ceJoe Onorato synchronized (mNotifications) { 52875199e3ddcf7886c8ee5fbf8b486a8c21335bf14Joe Onorato final StatusBarNotification n = mNotifications.remove(key); 52975199e3ddcf7886c8ee5fbf8b486a8c21335bf14Joe Onorato if (n == null) { 530fe0806a3b60ff54c7444a51b91353e2299ed1bcaDaniel Sandler Slog.e(TAG, "removeNotification key not found: " + key); 531fe0806a3b60ff54c7444a51b91353e2299ed1bcaDaniel Sandler return; 53275199e3ddcf7886c8ee5fbf8b486a8c21335bf14Joe Onorato } 533e345fff2f80947b0a821f6674c197a02b7bff08eJoe Onorato if (mBar != null) { 534e345fff2f80947b0a821f6674c197a02b7bff08eJoe Onorato try { 535e345fff2f80947b0a821f6674c197a02b7bff08eJoe Onorato mBar.removeNotification(key); 536e345fff2f80947b0a821f6674c197a02b7bff08eJoe Onorato } catch (RemoteException ex) { 537e345fff2f80947b0a821f6674c197a02b7bff08eJoe Onorato } 538e345fff2f80947b0a821f6674c197a02b7bff08eJoe Onorato } 53918e69dfc7235f8a4bfe257f9d1c43539049a22ceJoe Onorato } 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5420cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato // ================================================================================ 5430cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato // Can be called from any thread 5440cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato // ================================================================================ 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // lock on mDisableRecords 54713451a25fff12c1429f9ecdc24b2aa7696359f7dJohn Spurlock void manageDisableListLocked(int userId, int what, IBinder token, String pkg) { 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (SPEW) { 54913451a25fff12c1429f9ecdc24b2aa7696359f7dJohn Spurlock Slog.d(TAG, "manageDisableList userId=" + userId 55013451a25fff12c1429f9ecdc24b2aa7696359f7dJohn Spurlock + " what=0x" + Integer.toHexString(what) + " pkg=" + pkg); 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // update the list 5537bb8eeb90cf55f409a282c1f36ca08aa48c10543Joe Onorato final int N = mDisableRecords.size(); 5547bb8eeb90cf55f409a282c1f36ca08aa48c10543Joe Onorato DisableRecord tok = null; 5557bb8eeb90cf55f409a282c1f36ca08aa48c10543Joe Onorato int i; 5567bb8eeb90cf55f409a282c1f36ca08aa48c10543Joe Onorato for (i=0; i<N; i++) { 5577bb8eeb90cf55f409a282c1f36ca08aa48c10543Joe Onorato DisableRecord t = mDisableRecords.get(i); 5584e6922d89e72e79a8ab31ae2cb8a19d85bee91f8John Spurlock if (t.token == token && t.userId == userId) { 5597bb8eeb90cf55f409a282c1f36ca08aa48c10543Joe Onorato tok = t; 5607bb8eeb90cf55f409a282c1f36ca08aa48c10543Joe Onorato break; 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5627bb8eeb90cf55f409a282c1f36ca08aa48c10543Joe Onorato } 5637bb8eeb90cf55f409a282c1f36ca08aa48c10543Joe Onorato if (what == 0 || !token.isBinderAlive()) { 5647bb8eeb90cf55f409a282c1f36ca08aa48c10543Joe Onorato if (tok != null) { 5657bb8eeb90cf55f409a282c1f36ca08aa48c10543Joe Onorato mDisableRecords.remove(i); 5667bb8eeb90cf55f409a282c1f36ca08aa48c10543Joe Onorato tok.token.unlinkToDeath(tok, 0); 5677bb8eeb90cf55f409a282c1f36ca08aa48c10543Joe Onorato } 5687bb8eeb90cf55f409a282c1f36ca08aa48c10543Joe Onorato } else { 5697bb8eeb90cf55f409a282c1f36ca08aa48c10543Joe Onorato if (tok == null) { 5707bb8eeb90cf55f409a282c1f36ca08aa48c10543Joe Onorato tok = new DisableRecord(); 57113451a25fff12c1429f9ecdc24b2aa7696359f7dJohn Spurlock tok.userId = userId; 5727bb8eeb90cf55f409a282c1f36ca08aa48c10543Joe Onorato try { 5737bb8eeb90cf55f409a282c1f36ca08aa48c10543Joe Onorato token.linkToDeath(tok, 0); 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5757bb8eeb90cf55f409a282c1f36ca08aa48c10543Joe Onorato catch (RemoteException ex) { 5767bb8eeb90cf55f409a282c1f36ca08aa48c10543Joe Onorato return; // give up 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5787bb8eeb90cf55f409a282c1f36ca08aa48c10543Joe Onorato mDisableRecords.add(tok); 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5807bb8eeb90cf55f409a282c1f36ca08aa48c10543Joe Onorato tok.what = what; 5817bb8eeb90cf55f409a282c1f36ca08aa48c10543Joe Onorato tok.token = token; 5827bb8eeb90cf55f409a282c1f36ca08aa48c10543Joe Onorato tok.pkg = pkg; 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // lock on mDisableRecords 58713451a25fff12c1429f9ecdc24b2aa7696359f7dJohn Spurlock int gatherDisableActionsLocked(int userId) { 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int N = mDisableRecords.size(); 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // gather the new net flags 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int net = 0; 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0; i<N; i++) { 59213451a25fff12c1429f9ecdc24b2aa7696359f7dJohn Spurlock final DisableRecord rec = mDisableRecords.get(i); 59313451a25fff12c1429f9ecdc24b2aa7696359f7dJohn Spurlock if (rec.userId == userId) { 59413451a25fff12c1429f9ecdc24b2aa7696359f7dJohn Spurlock net |= rec.what; 59513451a25fff12c1429f9ecdc24b2aa7696359f7dJohn Spurlock } 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return net; 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // ================================================================================ 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Always called from UI thread 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // ================================================================================ 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project != PackageManager.PERMISSION_GRANTED) { 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println("Permission Denial: can't dump StatusBar from from pid=" 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + Binder.getCallingPid() 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + ", uid=" + Binder.getCallingUid()); 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6120cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato 6130cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato synchronized (mIcons) { 6140cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato mIcons.dump(pw); 6150cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato } 61618e69dfc7235f8a4bfe257f9d1c43539049a22ceJoe Onorato 61718e69dfc7235f8a4bfe257f9d1c43539049a22ceJoe Onorato synchronized (mNotifications) { 61875199e3ddcf7886c8ee5fbf8b486a8c21335bf14Joe Onorato int i=0; 61975199e3ddcf7886c8ee5fbf8b486a8c21335bf14Joe Onorato pw.println("Notification list:"); 62075199e3ddcf7886c8ee5fbf8b486a8c21335bf14Joe Onorato for (Map.Entry<IBinder,StatusBarNotification> e: mNotifications.entrySet()) { 62175199e3ddcf7886c8ee5fbf8b486a8c21335bf14Joe Onorato pw.printf(" %2d: %s\n", i, e.getValue().toString()); 62275199e3ddcf7886c8ee5fbf8b486a8c21335bf14Joe Onorato i++; 62375199e3ddcf7886c8ee5fbf8b486a8c21335bf14Joe Onorato } 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 62518e69dfc7235f8a4bfe257f9d1c43539049a22ceJoe Onorato 6267bb8eeb90cf55f409a282c1f36ca08aa48c10543Joe Onorato synchronized (mLock) { 62713451a25fff12c1429f9ecdc24b2aa7696359f7dJohn Spurlock pw.println(" mDisabled=0x" + Integer.toHexString(mDisabled)); 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int N = mDisableRecords.size(); 62913451a25fff12c1429f9ecdc24b2aa7696359f7dJohn Spurlock pw.println(" mDisableRecords.size=" + N); 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0; i<N; i++) { 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project DisableRecord tok = mDisableRecords.get(i); 63213451a25fff12c1429f9ecdc24b2aa7696359f7dJohn Spurlock pw.println(" [" + i + "] userId=" + tok.userId 63313451a25fff12c1429f9ecdc24b2aa7696359f7dJohn Spurlock + " what=0x" + Integer.toHexString(tok.what) 63413451a25fff12c1429f9ecdc24b2aa7696359f7dJohn Spurlock + " pkg=" + tok.pkg 63513451a25fff12c1429f9ecdc24b2aa7696359f7dJohn Spurlock + " token=" + tok.token); 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onReceive(Context context, Intent intent) { 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String action = intent.getAction(); 643f9e0e6bd5e070d4c213e0237fa2fb8d4bb558bcbJoe Onorato if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action) 644f9e0e6bd5e070d4c213e0237fa2fb8d4bb558bcbJoe Onorato || Intent.ACTION_SCREEN_OFF.equals(action)) { 64511cf178100e71d3f9f34ab5865e03a277c5eadaaDaniel Sandler collapsePanels(); 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6470cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato /* 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else if (Telephony.Intents.SPN_STRINGS_UPDATED_ACTION.equals(action)) { 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateNetworkName(intent.getBooleanExtra(Telephony.Intents.EXTRA_SHOW_SPN, false), 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent.getStringExtra(Telephony.Intents.EXTRA_SPN), 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent.getBooleanExtra(Telephony.Intents.EXTRA_SHOW_PLMN, false), 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent.getStringExtra(Telephony.Intents.EXTRA_PLMN)); 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) { 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateResources(); 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6570cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato */ 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 662