Merge "Write eventlog entries for notification visibility"
This commit is contained in:
committed by
Android (Google) Code Review
commit
97096fd0e6
@@ -47,6 +47,8 @@ interface IStatusBarService
|
|||||||
int uid, int initialPid, String message, int userId);
|
int uid, int initialPid, String message, int userId);
|
||||||
void onClearAllNotifications(int userId);
|
void onClearAllNotifications(int userId);
|
||||||
void onNotificationClear(String pkg, String tag, int id, int userId);
|
void onNotificationClear(String pkg, String tag, int id, int userId);
|
||||||
|
void onNotificationVisibilityChanged(
|
||||||
|
in String[] newlyVisibleKeys, in String[] noLongerVisibleKeys);
|
||||||
void setSystemUiVisibility(int vis, int mask);
|
void setSystemUiVisibility(int vis, int mask);
|
||||||
void setHardKeyboardEnabled(boolean enabled);
|
void setHardKeyboardEnabled(boolean enabled);
|
||||||
void toggleRecentApps();
|
void toggleRecentApps();
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ import android.os.UserHandle;
|
|||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.provider.Settings.Global;
|
import android.provider.Settings.Global;
|
||||||
import android.service.notification.StatusBarNotification;
|
import android.service.notification.StatusBarNotification;
|
||||||
|
import android.util.ArraySet;
|
||||||
import android.util.DisplayMetrics;
|
import android.util.DisplayMetrics;
|
||||||
import android.util.EventLog;
|
import android.util.EventLog;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
@@ -111,10 +112,14 @@ import com.android.systemui.statusbar.policy.LocationController;
|
|||||||
import com.android.systemui.statusbar.policy.NetworkController;
|
import com.android.systemui.statusbar.policy.NetworkController;
|
||||||
import com.android.systemui.statusbar.policy.RotationLockController;
|
import com.android.systemui.statusbar.policy.RotationLockController;
|
||||||
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
|
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
|
||||||
|
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout.OnChildLocationsChangedListener;
|
||||||
|
import com.android.systemui.statusbar.stack.StackScrollState.ViewState;
|
||||||
|
|
||||||
import java.io.FileDescriptor;
|
import java.io.FileDescriptor;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
|
public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
|
||||||
static final String TAG = "PhoneStatusBar";
|
static final String TAG = "PhoneStatusBar";
|
||||||
@@ -147,6 +152,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
|
|||||||
View.STATUS_BAR_TRANSIENT | View.NAVIGATION_BAR_TRANSIENT;
|
View.STATUS_BAR_TRANSIENT | View.NAVIGATION_BAR_TRANSIENT;
|
||||||
private static final long AUTOHIDE_TIMEOUT_MS = 3000;
|
private static final long AUTOHIDE_TIMEOUT_MS = 3000;
|
||||||
|
|
||||||
|
/** The minimum delay in ms between reports of notification visibility. */
|
||||||
|
private static final int VISIBILITY_REPORT_MIN_DELAY_MS = 500;
|
||||||
|
|
||||||
// fling gesture tuning parameters, scaled to display density
|
// fling gesture tuning parameters, scaled to display density
|
||||||
private float mSelfExpandVelocityPx; // classic value: 2000px/s
|
private float mSelfExpandVelocityPx; // classic value: 2000px/s
|
||||||
private float mSelfCollapseVelocityPx; // classic value: 2000px/s (will be negated to collapse "up")
|
private float mSelfCollapseVelocityPx; // classic value: 2000px/s (will be negated to collapse "up")
|
||||||
@@ -376,6 +384,82 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
|
|||||||
mOnFlipRunnable = onFlipRunnable;
|
mOnFlipRunnable = onFlipRunnable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Keys of notifications currently visible to the user. */
|
||||||
|
private final ArraySet<String> mCurrentlyVisibleNotifications = new ArraySet<String>();
|
||||||
|
private long mLastVisibilityReportUptimeMs;
|
||||||
|
|
||||||
|
private static final int VISIBLE_LOCATIONS = ViewState.LOCATION_FIRST_CARD
|
||||||
|
| ViewState.LOCATION_TOP_STACK_PEEKING
|
||||||
|
| ViewState.LOCATION_MAIN_AREA
|
||||||
|
| ViewState.LOCATION_BOTTOM_STACK_PEEKING;
|
||||||
|
|
||||||
|
private final OnChildLocationsChangedListener mNotificationLocationsChangedListener =
|
||||||
|
new OnChildLocationsChangedListener() {
|
||||||
|
@Override
|
||||||
|
public void onChildLocationsChanged(
|
||||||
|
NotificationStackScrollLayout stackScrollLayout) {
|
||||||
|
if (mHandler.hasCallbacks(mVisibilityReporter)) {
|
||||||
|
// Visibilities will be reported when the existing
|
||||||
|
// callback is executed.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Calculate when we're allowed to run the visibility
|
||||||
|
// reporter. Note that this timestamp might already have
|
||||||
|
// passed. That's OK, the callback will just be executed
|
||||||
|
// ASAP.
|
||||||
|
long nextReportUptimeMs =
|
||||||
|
mLastVisibilityReportUptimeMs + VISIBILITY_REPORT_MIN_DELAY_MS;
|
||||||
|
mHandler.postAtTime(mVisibilityReporter, nextReportUptimeMs);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 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>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
mLastVisibilityReportUptimeMs = SystemClock.uptimeMillis();
|
||||||
|
|
||||||
|
// 1. Loop over mNotificationData entries:
|
||||||
|
// A. Keep list of visible notifications.
|
||||||
|
// B. Keep list of previously hidden, now visible notifications.
|
||||||
|
// 2. Compute no-longer visible notifications by removing currently
|
||||||
|
// visible notifications from the set of previously visible
|
||||||
|
// notifications.
|
||||||
|
// 3. Report newly visible and no-longer visible notifications.
|
||||||
|
// 4. Keep currently visible notifications for next report.
|
||||||
|
int N = mNotificationData.size();
|
||||||
|
for (int i = 0; i < N; i++) {
|
||||||
|
Entry entry = mNotificationData.get(i);
|
||||||
|
String key = entry.notification.getKey();
|
||||||
|
boolean previouslyVisible = mCurrentlyVisibleNotifications.contains(key);
|
||||||
|
boolean currentlyVisible =
|
||||||
|
(mStackScroller.getChildLocation(entry.row) & VISIBLE_LOCATIONS) != 0;
|
||||||
|
if (currentlyVisible) {
|
||||||
|
// Build new set of visible notifications.
|
||||||
|
mTmpCurrentlyVisibleNotifications.add(key);
|
||||||
|
}
|
||||||
|
if (!previouslyVisible && currentlyVisible) {
|
||||||
|
mTmpNewlyVisibleNotifications.add(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ArraySet<String> noLongerVisibleNotifications = mCurrentlyVisibleNotifications;
|
||||||
|
noLongerVisibleNotifications.removeAll(mTmpCurrentlyVisibleNotifications);
|
||||||
|
|
||||||
|
logNotificationVisibilityChanges(
|
||||||
|
mTmpNewlyVisibleNotifications, noLongerVisibleNotifications);
|
||||||
|
|
||||||
|
mCurrentlyVisibleNotifications.clear();
|
||||||
|
mCurrentlyVisibleNotifications.addAll(mTmpCurrentlyVisibleNotifications);
|
||||||
|
|
||||||
|
mTmpNewlyVisibleNotifications.clear();
|
||||||
|
mTmpCurrentlyVisibleNotifications.clear();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setZenMode(int mode) {
|
public void setZenMode(int mode) {
|
||||||
super.setZenMode(mode);
|
super.setZenMode(mode);
|
||||||
@@ -2647,6 +2731,41 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
|
|||||||
if (false) Log.v(TAG, "updateResources");
|
if (false) Log.v(TAG, "updateResources");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Visibility reporting
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void visibilityChanged(boolean visible) {
|
||||||
|
if (visible) {
|
||||||
|
mStackScroller.setChildLocationsChangedListener(mNotificationLocationsChangedListener);
|
||||||
|
} else {
|
||||||
|
// Report all notifications as invisible and turn down the
|
||||||
|
// reporter.
|
||||||
|
if (!mCurrentlyVisibleNotifications.isEmpty()) {
|
||||||
|
logNotificationVisibilityChanges(
|
||||||
|
Collections.<String>emptyList(), mCurrentlyVisibleNotifications);
|
||||||
|
mCurrentlyVisibleNotifications.clear();
|
||||||
|
}
|
||||||
|
mHandler.removeCallbacks(mVisibilityReporter);
|
||||||
|
mStackScroller.setChildLocationsChangedListener(null);
|
||||||
|
}
|
||||||
|
super.visibilityChanged(visible);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void logNotificationVisibilityChanges(
|
||||||
|
Collection<String> newlyVisible, Collection<String> noLongerVisible) {
|
||||||
|
if (newlyVisible.isEmpty() && noLongerVisible.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] newlyVisibleAr = newlyVisible.toArray(new String[newlyVisible.size()]);
|
||||||
|
String[] noLongerVisibleAr = noLongerVisible.toArray(new String[noLongerVisible.size()]);
|
||||||
|
try {
|
||||||
|
mBarService.onNotificationVisibilityChanged(newlyVisibleAr, noLongerVisibleAr);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
// Ignore.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// tracing
|
// tracing
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -63,6 +63,8 @@ option java_package com.android.server
|
|||||||
27500 notification_panel_revealed
|
27500 notification_panel_revealed
|
||||||
# when the notification panel is hidden
|
# when the notification panel is hidden
|
||||||
27501 notification_panel_hidden
|
27501 notification_panel_hidden
|
||||||
|
# when notifications are newly displayed on screen, or disappear from screen
|
||||||
|
27510 notification_visibility_changed (newlyVisibleKeys|3),(noLongerVisibleKeys|3)
|
||||||
|
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
# Watchdog.java
|
# Watchdog.java
|
||||||
|
|||||||
@@ -31,4 +31,6 @@ public interface NotificationDelegate {
|
|||||||
void onPanelRevealed();
|
void onPanelRevealed();
|
||||||
void onPanelHidden();
|
void onPanelHidden();
|
||||||
boolean allowDisable(int what, IBinder token, String pkg);
|
boolean allowDisable(int what, IBinder token, String pkg);
|
||||||
|
void onNotificationVisibilityChanged(
|
||||||
|
String[] newlyVisibleKeys, String[] noLongerVisibleKeys);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1071,6 +1071,16 @@ public class NotificationManagerService extends SystemService {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNotificationVisibilityChanged(
|
||||||
|
String[] newlyVisibleKeys, String[] noLongerVisibleKeys) {
|
||||||
|
// Using ';' as separator since eventlogs uses ',' to separate
|
||||||
|
// args.
|
||||||
|
EventLogTags.writeNotificationVisibilityChanged(
|
||||||
|
TextUtils.join(";", newlyVisibleKeys),
|
||||||
|
TextUtils.join(";", noLongerVisibleKeys));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
|
private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
|
||||||
|
|||||||
@@ -587,6 +587,19 @@ public class StatusBarManagerService extends IStatusBarService.Stub
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNotificationVisibilityChanged(
|
||||||
|
String[] newlyVisibleKeys, String[] noLongerVisibleKeys) throws RemoteException {
|
||||||
|
enforceStatusBarService();
|
||||||
|
long identity = Binder.clearCallingIdentity();
|
||||||
|
try {
|
||||||
|
mNotificationDelegate.onNotificationVisibilityChanged(
|
||||||
|
newlyVisibleKeys, noLongerVisibleKeys);
|
||||||
|
} finally {
|
||||||
|
Binder.restoreCallingIdentity(identity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClearAllNotifications(int userId) {
|
public void onClearAllNotifications(int userId) {
|
||||||
enforceStatusBarService();
|
enforceStatusBarService();
|
||||||
|
|||||||
Reference in New Issue
Block a user