FileDocCategorySizeDatePackage
StatusBarManagerService.javaAPI DocAndroid 5.1 API23917Thu Mar 12 22:22:42 GMT 2015com.android.server.statusbar

StatusBarManagerService

public class StatusBarManagerService extends IStatusBarService.Stub
A note on locking: We rely on the fact that calls onto mBar are oneway or if they are local, that they just enqueue messages to not deadlock.

Fields Summary
private static final String
TAG
private static final boolean
SPEW
private final android.content.Context
mContext
private final com.android.server.wm.WindowManagerService
mWindowManager
private android.os.Handler
mHandler
private com.android.server.notification.NotificationDelegate
mNotificationDelegate
private volatile com.android.internal.statusbar.IStatusBar
mBar
private com.android.internal.statusbar.StatusBarIconList
mIcons
private final ArrayList
mDisableRecords
private android.os.IBinder
mSysUiVisToken
private int
mDisabled
private Object
mLock
private int
mSystemUiVisibility
private boolean
mMenuVisible
private int
mImeWindowVis
private int
mImeBackDisposition
private boolean
mShowImeSwitcher
private android.os.IBinder
mImeToken
private int
mCurrentUserId
private final StatusBarManagerInternal
mInternalService
Private API used by NotificationManagerService.
Constructors Summary
public StatusBarManagerService(android.content.Context context, com.android.server.wm.WindowManagerService windowManager)
Construct the service, add the status bar view to the window manager

        mContext = context;
        mWindowManager = windowManager;

        final Resources res = context.getResources();
        mIcons.defineSlots(res.getStringArray(com.android.internal.R.array.config_statusBarIcons));

        LocalServices.addService(StatusBarManagerInternal.class, mInternalService);
    
Methods Summary
public voidcancelPreloadRecentApps()

        if (mBar != null) {
            try {
                mBar.cancelPreloadRecentApps();
            } catch (RemoteException ex) {}
        }
    
public voidclearNotificationEffects()

        enforceStatusBarService();
        long identity = Binder.clearCallingIdentity();
        try {
            mNotificationDelegate.clearEffects();
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
    
public voidcollapsePanels()

        enforceExpandStatusBar();

        if (mBar != null) {
            try {
                mBar.animateCollapsePanels();
            } catch (RemoteException ex) {
            }
        }
    
public voiddisable(int what, android.os.IBinder token, java.lang.String pkg)

        disableInternal(mCurrentUserId, what, token, pkg);
    
private voiddisableInternal(int userId, int what, android.os.IBinder token, java.lang.String pkg)

        enforceStatusBar();

        synchronized (mLock) {
            disableLocked(userId, what, token, pkg);
        }
    
private voiddisableLocked(int userId, int what, android.os.IBinder token, java.lang.String pkg)

        // It's important that the the callback and the call to mBar get done
        // in the same order when multiple threads are calling this function
        // so they are paired correctly.  The messages on the handler will be
        // handled in the order they were enqueued, but will be outside the lock.
        manageDisableListLocked(userId, what, token, pkg);

        // Ensure state for the current user is applied, even if passed a non-current user.
        final int net = gatherDisableActionsLocked(mCurrentUserId);
        if (net != mDisabled) {
            mDisabled = net;
            mHandler.post(new Runnable() {
                    public void run() {
                        mNotificationDelegate.onSetDisabled(net);
                    }
                });
            if (mBar != null) {
                try {
                    mBar.disable(net);
                } catch (RemoteException ex) {
                }
            }
        }
    
protected voiddump(java.io.FileDescriptor fd, java.io.PrintWriter pw, java.lang.String[] args)

        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
                != PackageManager.PERMISSION_GRANTED) {
            pw.println("Permission Denial: can't dump StatusBar from from pid="
                    + Binder.getCallingPid()
                    + ", uid=" + Binder.getCallingUid());
            return;
        }

        synchronized (mIcons) {
            mIcons.dump(pw);
        }

        synchronized (mLock) {
            pw.println("  mDisabled=0x" + Integer.toHexString(mDisabled));
            final int N = mDisableRecords.size();
            pw.println("  mDisableRecords.size=" + N);
            for (int i=0; i<N; i++) {
                DisableRecord tok = mDisableRecords.get(i);
                pw.println("    [" + i + "] userId=" + tok.userId
                                + " what=0x" + Integer.toHexString(tok.what)
                                + " pkg=" + tok.pkg
                                + " token=" + tok.token);
            }
        }
    
private voidenforceExpandStatusBar()

        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.EXPAND_STATUS_BAR,
                "StatusBarManagerService");
    
private voidenforceStatusBar()

        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR,
                "StatusBarManagerService");
    
private voidenforceStatusBarService()

        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR_SERVICE,
                "StatusBarManagerService");
    
public voidexpandNotificationsPanel()


    // ================================================================================
    // From IStatusBarService
    // ================================================================================
    
       
        enforceExpandStatusBar();

        if (mBar != null) {
            try {
                mBar.animateExpandNotificationsPanel();
            } catch (RemoteException ex) {
            }
        }
    
public voidexpandSettingsPanel()

        enforceExpandStatusBar();

        if (mBar != null) {
            try {
                mBar.animateExpandSettingsPanel();
            } catch (RemoteException ex) {
            }
        }
    
intgatherDisableActionsLocked(int userId)

        final int N = mDisableRecords.size();
        // gather the new net flags
        int net = 0;
        for (int i=0; i<N; i++) {
            final DisableRecord rec = mDisableRecords.get(i);
            if (rec.userId == userId) {
                net |= rec.what;
            }
        }
        return net;
    
public voidhideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey)

        if (mBar != null) {
            try {
                mBar.hideRecentApps(triggeredFromAltTab, triggeredFromHomeKey);
            } catch (RemoteException ex) {}
        }
    
voidmanageDisableListLocked(int userId, int what, android.os.IBinder token, java.lang.String pkg)

        if (SPEW) {
            Slog.d(TAG, "manageDisableList userId=" + userId
                    + " what=0x" + Integer.toHexString(what) + " pkg=" + pkg);
        }
        // update the list
        final int N = mDisableRecords.size();
        DisableRecord tok = null;
        int i;
        for (i=0; i<N; i++) {
            DisableRecord t = mDisableRecords.get(i);
            if (t.token == token && t.userId == userId) {
                tok = t;
                break;
            }
        }
        if (what == 0 || !token.isBinderAlive()) {
            if (tok != null) {
                mDisableRecords.remove(i);
                tok.token.unlinkToDeath(tok, 0);
            }
        } else {
            if (tok == null) {
                tok = new DisableRecord();
                tok.userId = userId;
                try {
                    token.linkToDeath(tok, 0);
                }
                catch (RemoteException ex) {
                    return; // give up
                }
                mDisableRecords.add(tok);
            }
            tok.what = what;
            tok.token = token;
            tok.pkg = pkg;
        }
    
public voidonClearAllNotifications(int userId)

        enforceStatusBarService();
        final int callingUid = Binder.getCallingUid();
        final int callingPid = Binder.getCallingPid();
        long identity = Binder.clearCallingIdentity();
        try {
            mNotificationDelegate.onClearAll(callingUid, callingPid, userId);
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
    
public voidonNotificationActionClick(java.lang.String key, int actionIndex)

        enforceStatusBarService();
        final int callingUid = Binder.getCallingUid();
        final int callingPid = Binder.getCallingPid();
        long identity = Binder.clearCallingIdentity();
        try {
            mNotificationDelegate.onNotificationActionClick(callingUid, callingPid, key,
                    actionIndex);
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
    
public voidonNotificationClear(java.lang.String pkg, java.lang.String tag, int id, int userId)

        enforceStatusBarService();
        final int callingUid = Binder.getCallingUid();
        final int callingPid = Binder.getCallingPid();
        long identity = Binder.clearCallingIdentity();
        try {
            mNotificationDelegate.onNotificationClear(callingUid, callingPid, pkg, tag, id, userId);
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
    
public voidonNotificationClick(java.lang.String key)

        enforceStatusBarService();
        final int callingUid = Binder.getCallingUid();
        final int callingPid = Binder.getCallingPid();
        long identity = Binder.clearCallingIdentity();
        try {
            mNotificationDelegate.onNotificationClick(callingUid, callingPid, key);
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
    
public voidonNotificationError(java.lang.String pkg, java.lang.String tag, int id, int uid, int initialPid, java.lang.String message, int userId)

        enforceStatusBarService();
        final int callingUid = Binder.getCallingUid();
        final int callingPid = Binder.getCallingPid();
        long identity = Binder.clearCallingIdentity();
        try {
            // WARNING: this will call back into us to do the remove.  Don't hold any locks.
            mNotificationDelegate.onNotificationError(callingUid, callingPid,
                    pkg, tag, id, uid, initialPid, message, userId);
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
    
public voidonNotificationExpansionChanged(java.lang.String key, boolean userAction, boolean expanded)

        enforceStatusBarService();
        long identity = Binder.clearCallingIdentity();
        try {
            mNotificationDelegate.onNotificationExpansionChanged(
                    key, userAction, expanded);
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
    
public voidonNotificationVisibilityChanged(java.lang.String[] newlyVisibleKeys, java.lang.String[] noLongerVisibleKeys)

        enforceStatusBarService();
        long identity = Binder.clearCallingIdentity();
        try {
            mNotificationDelegate.onNotificationVisibilityChanged(
                    newlyVisibleKeys, noLongerVisibleKeys);
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
    
public voidonPanelHidden()

        enforceStatusBarService();
        long identity = Binder.clearCallingIdentity();
        try {
            mNotificationDelegate.onPanelHidden();
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
    
public voidonPanelRevealed(boolean clearNotificationEffects)

param
clearNotificationEffects whether to consider notifications as "shown" and stop LED, vibration, and ringing

        enforceStatusBarService();
        long identity = Binder.clearCallingIdentity();
        try {
            mNotificationDelegate.onPanelRevealed(clearNotificationEffects);
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
    
public voidpreloadRecentApps()

        if (mBar != null) {
            try {
                mBar.preloadRecentApps();
            } catch (RemoteException ex) {}
        }
    
public voidregisterStatusBar(com.android.internal.statusbar.IStatusBar bar, com.android.internal.statusbar.StatusBarIconList iconList, int[] switches, java.util.List binders)

        enforceStatusBarService();

        Slog.i(TAG, "registerStatusBar bar=" + bar);
        mBar = bar;
        synchronized (mIcons) {
            iconList.copyFrom(mIcons);
        }
        synchronized (mLock) {
            switches[0] = gatherDisableActionsLocked(mCurrentUserId);
            switches[1] = mSystemUiVisibility;
            switches[2] = mMenuVisible ? 1 : 0;
            switches[3] = mImeWindowVis;
            switches[4] = mImeBackDisposition;
            switches[5] = mShowImeSwitcher ? 1 : 0;
            binders.add(mImeToken);
        }
    
public voidremoveIcon(java.lang.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);

            if (mBar != null) {
                try {
                    mBar.removeIcon(index);
                } catch (RemoteException ex) {
                }
            }
        }
    
public voidsetCurrentUser(int newUserId)

        if (SPEW) Slog.d(TAG, "Setting current user to user " + newUserId);
        mCurrentUserId = newUserId;
    
public voidsetIcon(java.lang.String slot, java.lang.String iconPackage, int iconId, int iconLevel, java.lang.String contentDescription)

        enforceStatusBar();

        synchronized (mIcons) {
            int index = mIcons.getSlotIndex(slot);
            if (index < 0) {
                throw new SecurityException("invalid status bar icon slot: " + slot);
            }

            StatusBarIcon icon = new StatusBarIcon(iconPackage, UserHandle.OWNER, iconId,
                    iconLevel, 0,
                    contentDescription);
            //Slog.d(TAG, "setIcon slot=" + slot + " index=" + index + " icon=" + icon);
            mIcons.setIcon(index, icon);

            if (mBar != null) {
                try {
                    mBar.setIcon(index, icon);
                } catch (RemoteException ex) {
                }
            }
        }
    
public voidsetIconVisibility(java.lang.String slot, boolean visible)

        enforceStatusBar();

        synchronized (mIcons) {
            int index = mIcons.getSlotIndex(slot);
            if (index < 0) {
                throw new SecurityException("invalid status bar icon slot: " + slot);
            }

            StatusBarIcon icon = mIcons.getIcon(index);
            if (icon == null) {
                return;
            }

            if (icon.visible != visible) {
                icon.visible = visible;

                if (mBar != null) {
                    try {
                        mBar.setIcon(index, icon);
                    } catch (RemoteException ex) {
                    }
                }
            }
        }
    
public voidsetImeWindowStatus(android.os.IBinder token, int vis, int backDisposition, boolean showImeSwitcher)

        enforceStatusBar();

        if (SPEW) {
            Slog.d(TAG, "swetImeWindowStatus vis=" + vis + " backDisposition=" + backDisposition);
        }

        synchronized(mLock) {
            // In case of IME change, we need to call up setImeWindowStatus() regardless of
            // mImeWindowVis because mImeWindowVis may not have been set to false when the
            // previous IME was destroyed.
            mImeWindowVis = vis;
            mImeBackDisposition = backDisposition;
            mImeToken = token;
            mShowImeSwitcher = showImeSwitcher;
            mHandler.post(new Runnable() {
                public void run() {
                    if (mBar != null) {
                        try {
                            mBar.setImeWindowStatus(token, vis, backDisposition, showImeSwitcher);
                        } catch (RemoteException ex) {
                        }
                    }
                }
            });
        }
    
public voidsetSystemUiVisibility(int vis, int mask, java.lang.String cause)

        // also allows calls from window manager which is in this process.
        enforceStatusBarService();

        if (SPEW) Slog.d(TAG, "setSystemUiVisibility(0x" + Integer.toHexString(vis) + ")");

        synchronized (mLock) {
            updateUiVisibilityLocked(vis, mask);
            disableLocked(
                    mCurrentUserId,
                    vis & StatusBarManager.DISABLE_MASK,
                    mSysUiVisToken,
                    cause);
        }
    
public voidsetWindowState(int window, int state)

        if (mBar != null) {
            try {
                mBar.setWindowState(window, state);
            } catch (RemoteException ex) {}
        }
    
public voidshowRecentApps(boolean triggeredFromAltTab)

        if (mBar != null) {
            try {
                mBar.showRecentApps(triggeredFromAltTab);
            } catch (RemoteException ex) {}
        }
    
public voidtoggleRecentApps()

        if (mBar != null) {
            try {
                mBar.toggleRecentApps();
            } catch (RemoteException ex) {}
        }
    
public voidtopAppWindowChanged(boolean menuVisible)
Hide or show the on-screen Menu key. Only call this from the window manager, typically in response to a window with {@link android.view.WindowManager.LayoutParams#needsMenuKey} set to {@link android.view.WindowManager.LayoutParams#NEEDS_MENU_SET_TRUE}.

        enforceStatusBar();

        if (SPEW) Slog.d(TAG, (menuVisible?"showing":"hiding") + " MENU key");

        synchronized(mLock) {
            mMenuVisible = menuVisible;
            mHandler.post(new Runnable() {
                    public void run() {
                        if (mBar != null) {
                            try {
                                mBar.topAppWindowChanged(menuVisible);
                            } catch (RemoteException ex) {
                            }
                        }
                    }
                });
        }
    
private voidupdateUiVisibilityLocked(int vis, int mask)

        if (mSystemUiVisibility != vis) {
            mSystemUiVisibility = vis;
            mHandler.post(new Runnable() {
                    public void run() {
                        if (mBar != null) {
                            try {
                                mBar.setSystemUiVisibility(vis, mask);
                            } catch (RemoteException ex) {
                            }
                        }
                    }
                });
        }