Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2ebdeeca authored by Chris Wren's avatar Chris Wren Committed by Android Git Automerger
Browse files

am ca7febf4: Merge "add rank to notification visibility log" into mnc-dev

* commit 'ca7febf4':
  add rank to notification visibility log
parents ddc6d37e ca7febf4
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.internal.statusbar;
import com.android.internal.statusbar.IStatusBar;
import com.android.internal.statusbar.StatusBarIcon;
import com.android.internal.statusbar.StatusBarIconList;
import com.android.internal.statusbar.NotificationVisibility;
import android.service.notification.StatusBarNotification;

/** @hide */
@@ -53,8 +54,8 @@ interface IStatusBarService
            int uid, int initialPid, String message, int userId);
    void onClearAllNotifications(int userId);
    void onNotificationClear(String pkg, String tag, int id, int userId);
    void onNotificationVisibilityChanged(
            in String[] newlyVisibleKeys, in String[] noLongerVisibleKeys);
    void onNotificationVisibilityChanged( in NotificationVisibility[] newlyVisibleKeys,
            in NotificationVisibility[] noLongerVisibleKeys);
    void onNotificationExpansionChanged(in String key, in boolean userAction, in boolean expanded);
    void setSystemUiVisibility(int vis, int mask, String cause);
    void setWindowState(int window, int state);
+20 −0
Original line number Diff line number Diff line
/*
 * Copyright (c) 2015, 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 NotificationVisibility;
+161 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2015 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.Message;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;

import java.util.ArrayDeque;
import java.util.Collection;

public class NotificationVisibility implements Parcelable {
    private static final String TAG = "NoViz";
    private static final int MAX_POOL_SIZE = 25;
    private static ArrayDeque<NotificationVisibility> sPool = new ArrayDeque<>(MAX_POOL_SIZE);
    private static int sNexrId = 0;

    public String key;
    public int rank;
    public boolean visible = true;
    /*package*/ int id;

    private NotificationVisibility() {
        id = sNexrId++;
    }

    private NotificationVisibility(String key, int rank, boolean visibile) {
        this();
        this.key = key;
        this.rank = rank;
        this.visible = visibile;
    }

    @Override
    public String toString() {
        return "NotificationVisibility(id=" + id
                + "key=" + key
                + " rank=" + rank
                + (visible?" visible":"")
                + " )";
    }

    @Override
    public NotificationVisibility clone() {
        return obtain(this.key, this.rank, this.visible);
    }

    @Override
    public int hashCode() {
        // allow lookups by key, which _should_ never be null.
        return key == null ? 0 : key.hashCode();
    }

    @Override
    public boolean equals(Object that) {
        // allow lookups by key, which _should_ never be null.
        if (that instanceof NotificationVisibility) {
            NotificationVisibility thatViz = (NotificationVisibility) that;
            return (key == null && thatViz.key == null) || key.equals(thatViz.key);
        }
        return false;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeString(this.key);
        out.writeInt(this.rank);
        out.writeInt(this.visible ? 1 : 0);
    }

    private void readFromParcel(Parcel in) {
        this.key = in.readString();
        this.rank = in.readInt();
        this.visible = in.readInt() != 0;
    }

    /**
     * Return a new NotificationVisibility instance from the global pool. Allows us to
     * avoid allocating new objects in many cases.
     */
    public static NotificationVisibility obtain(String key, int rank, boolean visible) {
        NotificationVisibility vo = obtain();
        vo.key = key;
        vo.rank = rank;
        vo.visible = visible;
        return vo;
    }

    private static NotificationVisibility obtain(Parcel in) {
        NotificationVisibility vo = obtain();
        vo.readFromParcel(in);
        return vo;
    }

    private static NotificationVisibility obtain() {
        synchronized (sPool) {
            if (!sPool.isEmpty()) {
                return sPool.poll();
            }
        }
        return new NotificationVisibility();
    }

    /**
     * Return a NotificationVisibility instance to the global pool.
     * <p>
     * You MUST NOT touch the NotificationVisibility after calling this function because it has
     * effectively been freed.
     * </p>
     */
    public void recycle() {
        if (key == null) {
            // do nothing on multiple recycles
            return;
        }
        key = null;
        if (sPool.size() < MAX_POOL_SIZE) {
            synchronized (sPool) {
                sPool.offer(this);
            }
        }
    }

    /**
     * Parcelable.Creator that instantiates NotificationVisibility objects
     */
    public static final Parcelable.Creator<NotificationVisibility> CREATOR
            = new Parcelable.Creator<NotificationVisibility>()
    {
        public NotificationVisibility createFromParcel(Parcel parcel)
        {
            return obtain(parcel);
        }

        public NotificationVisibility[] newArray(int size)
        {
            return new NotificationVisibility[size];
        }
    };
}
+52 −22
Original line number Diff line number Diff line
@@ -96,6 +96,7 @@ import android.widget.ImageView;
import android.widget.TextView;

import com.android.internal.logging.MetricsLogger;
import com.android.internal.statusbar.NotificationVisibility;
import com.android.internal.statusbar.StatusBarIcon;
import com.android.keyguard.KeyguardHostView.OnDismissAction;
import com.android.keyguard.ViewMediatorCallback;
@@ -457,7 +458,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
    private int mDisabledUnmodified2;

    /** Keys of notifications currently visible to the user. */
    private final ArraySet<String> mCurrentlyVisibleNotifications = new ArraySet<String>();
    private final ArraySet<NotificationVisibility> mCurrentlyVisibleNotifications =
            new ArraySet<>();
    private long mLastVisibilityReportUptimeMs;

    private final ShadeUpdates mShadeUpdates = new ShadeUpdates();
@@ -498,12 +500,17 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
    // Tracks notifications currently visible in mNotificationStackScroller and
    // emits visibility events via NoMan on changes.
    private final Runnable mVisibilityReporter = new Runnable() {
        private final ArrayList<String> mTmpNewlyVisibleNotifications = new ArrayList<String>();
        private final ArrayList<String> mTmpCurrentlyVisibleNotifications = new ArrayList<String>();
        private final ArraySet<NotificationVisibility> mTmpNewlyVisibleNotifications =
                new ArraySet<>();
        private final ArraySet<NotificationVisibility> mTmpCurrentlyVisibleNotifications =
                new ArraySet<>();
        private final ArraySet<NotificationVisibility> mTmpNoLongerVisibleNotifications =
                new ArraySet<>();

        @Override
        public void run() {
            mLastVisibilityReportUptimeMs = SystemClock.uptimeMillis();
            final String mediaKey = getCurrentMediaNotificationKey();

            // 1. Loop over mNotificationData entries:
            //   A. Keep list of visible notifications.
@@ -518,31 +525,45 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
            for (int i = 0; i < N; i++) {
                Entry entry = activeNotifications.get(i);
                String key = entry.notification.getKey();
                boolean previouslyVisible = mCurrentlyVisibleNotifications.contains(key);
                boolean currentlyVisible =
                boolean isVisible =
                        (mStackScroller.getChildLocation(entry.row) & VISIBLE_LOCATIONS) != 0;
                if (currentlyVisible) {
                NotificationVisibility visObj = NotificationVisibility.obtain(key, i, isVisible);
                boolean previouslyVisible = mCurrentlyVisibleNotifications.contains(visObj);
                if (isVisible) {
                    // Build new set of visible notifications.
                    mTmpCurrentlyVisibleNotifications.add(key);
                    mTmpCurrentlyVisibleNotifications.add(visObj);
                    if (!previouslyVisible) {
                        mTmpNewlyVisibleNotifications.add(visObj);
                    }
                if (!previouslyVisible && currentlyVisible) {
                    mTmpNewlyVisibleNotifications.add(key);
                } else {
                    // release object
                    visObj.recycle();
                }
            }
            ArraySet<String> noLongerVisibleNotifications = mCurrentlyVisibleNotifications;
            noLongerVisibleNotifications.removeAll(mTmpCurrentlyVisibleNotifications);
            mTmpNoLongerVisibleNotifications.addAll(mCurrentlyVisibleNotifications);
            mTmpNoLongerVisibleNotifications.removeAll(mTmpCurrentlyVisibleNotifications);

            logNotificationVisibilityChanges(
                    mTmpNewlyVisibleNotifications, noLongerVisibleNotifications);
                    mTmpNewlyVisibleNotifications, mTmpNoLongerVisibleNotifications);

            mCurrentlyVisibleNotifications.clear();
            recycleAllVisibilityObjects(mCurrentlyVisibleNotifications);
            mCurrentlyVisibleNotifications.addAll(mTmpCurrentlyVisibleNotifications);

            mTmpNewlyVisibleNotifications.clear();
            recycleAllVisibilityObjects(mTmpNoLongerVisibleNotifications);
            mTmpCurrentlyVisibleNotifications.clear();
            mTmpNewlyVisibleNotifications.clear();
            mTmpNoLongerVisibleNotifications.clear();
        }
    };

    private void recycleAllVisibilityObjects(ArraySet<NotificationVisibility> array) {
        final int N = array.size();
        for (int i = 0 ; i < N; i++) {
            array.valueAt(i).recycle();
        }
        array.clear();
    }

    private final View.OnClickListener mOverflowClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
@@ -2987,9 +3008,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
        // Report all notifications as invisible and turn down the
        // reporter.
        if (!mCurrentlyVisibleNotifications.isEmpty()) {
            logNotificationVisibilityChanges(
                    Collections.<String>emptyList(), mCurrentlyVisibleNotifications);
            mCurrentlyVisibleNotifications.clear();
            logNotificationVisibilityChanges(Collections.<NotificationVisibility>emptyList(),
                    mCurrentlyVisibleNotifications);
            recycleAllVisibilityObjects(mCurrentlyVisibleNotifications);
        }
        mHandler.removeCallbacks(mVisibilityReporter);
        mStackScroller.setChildLocationsChangedListener(null);
@@ -3007,18 +3028,27 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
    }

    private void logNotificationVisibilityChanges(
            Collection<String> newlyVisible, Collection<String> noLongerVisible) {
            Collection<NotificationVisibility> newlyVisible,
            Collection<NotificationVisibility> noLongerVisible) {
        if (newlyVisible.isEmpty() && noLongerVisible.isEmpty()) {
            return;
        }
        String[] newlyVisibleAr = newlyVisible.toArray(new String[newlyVisible.size()]);
        String[] noLongerVisibleAr = noLongerVisible.toArray(new String[noLongerVisible.size()]);
        NotificationVisibility[] newlyVisibleAr =
                newlyVisible.toArray(new NotificationVisibility[newlyVisible.size()]);
        NotificationVisibility[] noLongerVisibleAr =
                noLongerVisible.toArray(new NotificationVisibility[noLongerVisible.size()]);
        try {
            mBarService.onNotificationVisibilityChanged(newlyVisibleAr, noLongerVisibleAr);
        } catch (RemoteException e) {
            // Ignore.
        }
        setNotificationsShown(newlyVisibleAr);

        final int N = newlyVisible.size();
        String[] newlyVisibleKeyAr = new String[N];
        for (int i = 0; i < N; i++) {
            newlyVisibleKeyAr[i] = newlyVisibleAr[i].key;
        }
        setNotificationsShown(newlyVisibleKeyAr);
    }

    // State logging
+1 −1
Original line number Diff line number Diff line
@@ -74,7 +74,7 @@ option java_package com.android.server
# when a notification has been canceled
27530 notification_canceled (key|3),(reason|1),(lifespan|1),(freshness|1),(exposure|1)
# replaces 27510 with a row per notification
27531 notification_visibility (key|3),(visibile|1),(lifespan|1),(freshness|1)
27531 notification_visibility (key|3),(visibile|1),(lifespan|1),(freshness|1),(exposure|1),(rank|1)
# a notification emited noise, vibration, or light
27532 notification_alert (key|3),(buzz|1),(beep|1),(blink|1)

Loading