Merge "Group broadcasts occurred within a certain duration into sessions." into tm-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
0a790c6419
@@ -246,6 +246,28 @@ public interface AppStandbyInternal {
|
|||||||
@ProcessState
|
@ProcessState
|
||||||
int getBroadcastResponseFgThresholdState();
|
int getBroadcastResponseFgThresholdState();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the duration within which any broadcasts occurred will be treated as one broadcast
|
||||||
|
* session.
|
||||||
|
*/
|
||||||
|
long getBroadcastSessionsDurationMs();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the duration within which any broadcasts occurred (with a corresponding response
|
||||||
|
* event) will be treated as one broadcast session. This similar to
|
||||||
|
* {@link #getBroadcastSessionsDurationMs()}, except that this duration will be used to group
|
||||||
|
* only broadcasts that have a corresponding response event into sessions.
|
||||||
|
*/
|
||||||
|
long getBroadcastSessionsWithResponseDurationMs();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns {@code true} if the response event should be attributed to all the broadcast
|
||||||
|
* sessions that occurred within the broadcast response window and {@code false} if the
|
||||||
|
* response event should be attributed to only the earliest broadcast session within the
|
||||||
|
* broadcast response window.
|
||||||
|
*/
|
||||||
|
boolean shouldNoteResponseEventForAllBroadcastSessions();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the last known value corresponding to the {@code key} from
|
* Return the last known value corresponding to the {@code key} from
|
||||||
* {@link android.provider.DeviceConfig#NAMESPACE_APP_STANDBY} in AppStandbyController.
|
* {@link android.provider.DeviceConfig#NAMESPACE_APP_STANDBY} in AppStandbyController.
|
||||||
|
|||||||
@@ -376,6 +376,32 @@ public class AppStandbyController
|
|||||||
volatile int mBroadcastResponseFgThresholdState =
|
volatile int mBroadcastResponseFgThresholdState =
|
||||||
ConstantsObserver.DEFAULT_BROADCAST_RESPONSE_FG_THRESHOLD_STATE;
|
ConstantsObserver.DEFAULT_BROADCAST_RESPONSE_FG_THRESHOLD_STATE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Duration (in millis) for the window within which any broadcasts occurred will be
|
||||||
|
* treated as one broadcast session.
|
||||||
|
*/
|
||||||
|
volatile long mBroadcastSessionsDurationMs =
|
||||||
|
ConstantsObserver.DEFAULT_BROADCAST_SESSIONS_DURATION_MS;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Duration (in millis) for the window within which any broadcasts occurred ((with a
|
||||||
|
* corresponding response event) will be treated as one broadcast session. This similar to
|
||||||
|
* {@link #mBroadcastSessionsDurationMs}, except that this duration will be used to group only
|
||||||
|
* broadcasts that have a corresponding response event into sessions.
|
||||||
|
*/
|
||||||
|
volatile long mBroadcastSessionsWithResponseDurationMs =
|
||||||
|
ConstantsObserver.DEFAULT_BROADCAST_SESSIONS_WITH_RESPONSE_DURATION_MS;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Denotes whether the response event should be attributed to all broadcast sessions or not.
|
||||||
|
* If this is {@code true}, then the response event should be attributed to all the broadcast
|
||||||
|
* sessions that occurred within the broadcast response window. Otherwise, the
|
||||||
|
* response event should be attributed to only the earliest broadcast session within the
|
||||||
|
* broadcast response window.
|
||||||
|
*/
|
||||||
|
volatile boolean mNoteResponseEventForAllBroadcastSessions =
|
||||||
|
ConstantsObserver.DEFAULT_NOTE_RESPONSE_EVENT_FOR_ALL_BROADCAST_SESSIONS;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Map of last known values of keys in {@link DeviceConfig#NAMESPACE_APP_STANDBY}.
|
* Map of last known values of keys in {@link DeviceConfig#NAMESPACE_APP_STANDBY}.
|
||||||
*
|
*
|
||||||
@@ -1868,6 +1894,21 @@ public class AppStandbyController
|
|||||||
return mBroadcastResponseFgThresholdState;
|
return mBroadcastResponseFgThresholdState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getBroadcastSessionsDurationMs() {
|
||||||
|
return mBroadcastSessionsDurationMs;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getBroadcastSessionsWithResponseDurationMs() {
|
||||||
|
return mBroadcastSessionsWithResponseDurationMs;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldNoteResponseEventForAllBroadcastSessions() {
|
||||||
|
return mNoteResponseEventForAllBroadcastSessions;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public String getAppStandbyConstant(@NonNull String key) {
|
public String getAppStandbyConstant(@NonNull String key) {
|
||||||
@@ -2202,6 +2243,18 @@ public class AppStandbyController
|
|||||||
pw.print(ActivityManager.procStateToString(mBroadcastResponseFgThresholdState));
|
pw.print(ActivityManager.procStateToString(mBroadcastResponseFgThresholdState));
|
||||||
pw.println();
|
pw.println();
|
||||||
|
|
||||||
|
pw.print(" mBroadcastSessionsDurationMs=");
|
||||||
|
TimeUtils.formatDuration(mBroadcastSessionsDurationMs, pw);
|
||||||
|
pw.println();
|
||||||
|
|
||||||
|
pw.print(" mBroadcastSessionsWithResponseDurationMs=");
|
||||||
|
TimeUtils.formatDuration(mBroadcastSessionsWithResponseDurationMs, pw);
|
||||||
|
pw.println();
|
||||||
|
|
||||||
|
pw.print(" mNoteResponseEventForAllBroadcastSessions=");
|
||||||
|
pw.print(mNoteResponseEventForAllBroadcastSessions);
|
||||||
|
pw.println();
|
||||||
|
|
||||||
pw.println();
|
pw.println();
|
||||||
pw.print("mAppIdleEnabled="); pw.print(mAppIdleEnabled);
|
pw.print("mAppIdleEnabled="); pw.print(mAppIdleEnabled);
|
||||||
pw.print(" mAllowRestrictedBucket=");
|
pw.print(" mAllowRestrictedBucket=");
|
||||||
@@ -2672,6 +2725,13 @@ public class AppStandbyController
|
|||||||
"broadcast_response_window_timeout_ms";
|
"broadcast_response_window_timeout_ms";
|
||||||
private static final String KEY_BROADCAST_RESPONSE_FG_THRESHOLD_STATE =
|
private static final String KEY_BROADCAST_RESPONSE_FG_THRESHOLD_STATE =
|
||||||
"broadcast_response_fg_threshold_state";
|
"broadcast_response_fg_threshold_state";
|
||||||
|
private static final String KEY_BROADCAST_SESSIONS_DURATION_MS =
|
||||||
|
"broadcast_sessions_duration_ms";
|
||||||
|
private static final String KEY_BROADCAST_SESSIONS_WITH_RESPONSE_DURATION_MS =
|
||||||
|
"broadcast_sessions_with_response_duration_ms";
|
||||||
|
private static final String KEY_NOTE_RESPONSE_EVENT_FOR_ALL_BROADCAST_SESSIONS =
|
||||||
|
"note_response_event_for_all_broadcast_sessions";
|
||||||
|
|
||||||
public static final long DEFAULT_CHECK_IDLE_INTERVAL_MS =
|
public static final long DEFAULT_CHECK_IDLE_INTERVAL_MS =
|
||||||
COMPRESS_TIME ? ONE_MINUTE : 4 * ONE_HOUR;
|
COMPRESS_TIME ? ONE_MINUTE : 4 * ONE_HOUR;
|
||||||
public static final long DEFAULT_STRONG_USAGE_TIMEOUT =
|
public static final long DEFAULT_STRONG_USAGE_TIMEOUT =
|
||||||
@@ -2705,6 +2765,12 @@ public class AppStandbyController
|
|||||||
2 * ONE_MINUTE;
|
2 * ONE_MINUTE;
|
||||||
public static final int DEFAULT_BROADCAST_RESPONSE_FG_THRESHOLD_STATE =
|
public static final int DEFAULT_BROADCAST_RESPONSE_FG_THRESHOLD_STATE =
|
||||||
ActivityManager.PROCESS_STATE_TOP;
|
ActivityManager.PROCESS_STATE_TOP;
|
||||||
|
public static final long DEFAULT_BROADCAST_SESSIONS_DURATION_MS =
|
||||||
|
2 * ONE_MINUTE;
|
||||||
|
public static final long DEFAULT_BROADCAST_SESSIONS_WITH_RESPONSE_DURATION_MS =
|
||||||
|
2 * ONE_MINUTE;
|
||||||
|
public static final boolean DEFAULT_NOTE_RESPONSE_EVENT_FOR_ALL_BROADCAST_SESSIONS =
|
||||||
|
true;
|
||||||
|
|
||||||
ConstantsObserver(Handler handler) {
|
ConstantsObserver(Handler handler) {
|
||||||
super(handler);
|
super(handler);
|
||||||
@@ -2832,6 +2898,21 @@ public class AppStandbyController
|
|||||||
KEY_BROADCAST_RESPONSE_FG_THRESHOLD_STATE,
|
KEY_BROADCAST_RESPONSE_FG_THRESHOLD_STATE,
|
||||||
DEFAULT_BROADCAST_RESPONSE_FG_THRESHOLD_STATE);
|
DEFAULT_BROADCAST_RESPONSE_FG_THRESHOLD_STATE);
|
||||||
break;
|
break;
|
||||||
|
case KEY_BROADCAST_SESSIONS_DURATION_MS:
|
||||||
|
mBroadcastSessionsDurationMs = properties.getLong(
|
||||||
|
KEY_BROADCAST_SESSIONS_DURATION_MS,
|
||||||
|
DEFAULT_BROADCAST_SESSIONS_DURATION_MS);
|
||||||
|
break;
|
||||||
|
case KEY_BROADCAST_SESSIONS_WITH_RESPONSE_DURATION_MS:
|
||||||
|
mBroadcastSessionsWithResponseDurationMs = properties.getLong(
|
||||||
|
KEY_BROADCAST_SESSIONS_WITH_RESPONSE_DURATION_MS,
|
||||||
|
DEFAULT_BROADCAST_SESSIONS_WITH_RESPONSE_DURATION_MS);
|
||||||
|
break;
|
||||||
|
case KEY_NOTE_RESPONSE_EVENT_FOR_ALL_BROADCAST_SESSIONS:
|
||||||
|
mNoteResponseEventForAllBroadcastSessions = properties.getBoolean(
|
||||||
|
KEY_NOTE_RESPONSE_EVENT_FOR_ALL_BROADCAST_SESSIONS,
|
||||||
|
DEFAULT_NOTE_RESPONSE_EVENT_FOR_ALL_BROADCAST_SESSIONS);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
if (!timeThresholdsUpdated
|
if (!timeThresholdsUpdated
|
||||||
&& (name.startsWith(KEY_PREFIX_SCREEN_TIME_THRESHOLD)
|
&& (name.startsWith(KEY_PREFIX_SCREEN_TIME_THRESHOLD)
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ package com.android.server.usage;
|
|||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.annotation.UserIdInt;
|
import android.annotation.UserIdInt;
|
||||||
|
import android.util.LongArrayQueue;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
@@ -30,6 +31,7 @@ class BroadcastEvent {
|
|||||||
private String mTargetPackage;
|
private String mTargetPackage;
|
||||||
private int mTargetUserId;
|
private int mTargetUserId;
|
||||||
private long mIdForResponseEvent;
|
private long mIdForResponseEvent;
|
||||||
|
private final LongArrayQueue mTimestampsMs;
|
||||||
|
|
||||||
BroadcastEvent(int sourceUid, @NonNull String targetPackage, @UserIdInt int targetUserId,
|
BroadcastEvent(int sourceUid, @NonNull String targetPackage, @UserIdInt int targetUserId,
|
||||||
long idForResponseEvent) {
|
long idForResponseEvent) {
|
||||||
@@ -37,6 +39,7 @@ class BroadcastEvent {
|
|||||||
mTargetPackage = targetPackage;
|
mTargetPackage = targetPackage;
|
||||||
mTargetUserId = targetUserId;
|
mTargetUserId = targetUserId;
|
||||||
mIdForResponseEvent = idForResponseEvent;
|
mIdForResponseEvent = idForResponseEvent;
|
||||||
|
mTimestampsMs = new LongArrayQueue();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getSourceUid() {
|
public int getSourceUid() {
|
||||||
@@ -55,6 +58,14 @@ class BroadcastEvent {
|
|||||||
return mIdForResponseEvent;
|
return mIdForResponseEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LongArrayQueue getTimestampsMs() {
|
||||||
|
return mTimestampsMs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addTimestampMs(long timestampMs) {
|
||||||
|
mTimestampsMs.addLast(timestampMs);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(@Nullable Object obj) {
|
public boolean equals(@Nullable Object obj) {
|
||||||
if (this == obj) {
|
if (this == obj) {
|
||||||
|
|||||||
@@ -24,8 +24,10 @@ import android.annotation.Nullable;
|
|||||||
import android.annotation.UserIdInt;
|
import android.annotation.UserIdInt;
|
||||||
import android.app.ActivityManager.ProcessState;
|
import android.app.ActivityManager.ProcessState;
|
||||||
import android.app.usage.BroadcastResponseStats;
|
import android.app.usage.BroadcastResponseStats;
|
||||||
|
import android.os.SystemClock;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.util.LongSparseArray;
|
import android.util.ArraySet;
|
||||||
|
import android.util.LongArrayQueue;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
import android.util.SparseArray;
|
import android.util.SparseArray;
|
||||||
|
|
||||||
@@ -89,14 +91,14 @@ class BroadcastResponseStatsTracker {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
final LongSparseArray<BroadcastEvent> broadcastEvents =
|
final ArraySet<BroadcastEvent> broadcastEvents =
|
||||||
getOrCreateBroadcastEventsLocked(targetPackage, targetUser);
|
getOrCreateBroadcastEventsLocked(targetPackage, targetUser);
|
||||||
final BroadcastEvent broadcastEvent = new BroadcastEvent(
|
final BroadcastEvent broadcastEvent = getOrCreateBroadcastEvent(broadcastEvents,
|
||||||
sourceUid, targetPackage, targetUser.getIdentifier(), idForResponseEvent);
|
sourceUid, targetPackage, targetUser.getIdentifier(), idForResponseEvent);
|
||||||
broadcastEvents.append(timestampMs, broadcastEvent);
|
broadcastEvent.addTimestampMs(timestampMs);
|
||||||
final BroadcastResponseStats responseStats =
|
|
||||||
getOrCreateBroadcastResponseStats(broadcastEvent);
|
// Delete any old broadcast event related data so that we don't keep accumulating them.
|
||||||
responseStats.incrementBroadcastsDispatchedCount(1);
|
recordAndPruneOldBroadcastDispatchTimestamps(broadcastEvent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,47 +122,90 @@ class BroadcastResponseStatsTracker {
|
|||||||
@NonNull String packageName, UserHandle user, @ElapsedRealtimeLong long timestampMs) {
|
@NonNull String packageName, UserHandle user, @ElapsedRealtimeLong long timestampMs) {
|
||||||
mLogger.logNotificationEvent(event, packageName, user, timestampMs);
|
mLogger.logNotificationEvent(event, packageName, user, timestampMs);
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
final LongSparseArray<BroadcastEvent> broadcastEvents =
|
final ArraySet<BroadcastEvent> broadcastEvents =
|
||||||
getBroadcastEventsLocked(packageName, user);
|
getBroadcastEventsLocked(packageName, user);
|
||||||
if (broadcastEvents == null) {
|
if (broadcastEvents == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// TODO (206518114): Add LongSparseArray.removeAtRange()
|
final long broadcastResponseWindowDurationMs =
|
||||||
|
mAppStandby.getBroadcastResponseWindowDurationMs();
|
||||||
|
final long broadcastsSessionWithResponseDurationMs =
|
||||||
|
mAppStandby.getBroadcastSessionsWithResponseDurationMs();
|
||||||
|
final boolean recordAllBroadcastsSessionsWithinResponseWindow =
|
||||||
|
mAppStandby.shouldNoteResponseEventForAllBroadcastSessions();
|
||||||
for (int i = broadcastEvents.size() - 1; i >= 0; --i) {
|
for (int i = broadcastEvents.size() - 1; i >= 0; --i) {
|
||||||
final long dispatchTimestampMs = broadcastEvents.keyAt(i);
|
final BroadcastEvent broadcastEvent = broadcastEvents.valueAt(i);
|
||||||
final long elapsedDurationMs = timestampMs - dispatchTimestampMs;
|
recordAndPruneOldBroadcastDispatchTimestamps(broadcastEvent);
|
||||||
if (elapsedDurationMs <= 0) {
|
|
||||||
continue;
|
final LongArrayQueue dispatchTimestampsMs = broadcastEvent.getTimestampsMs();
|
||||||
}
|
long broadcastsSessionEndTimestampMs = 0;
|
||||||
if (dispatchTimestampMs >= timestampMs) {
|
// We only need to look at the broadcast events that occurred before
|
||||||
continue;
|
// this notification related event.
|
||||||
}
|
while (dispatchTimestampsMs.size() > 0
|
||||||
if (elapsedDurationMs <= mAppStandby.getBroadcastResponseWindowDurationMs()) {
|
&& dispatchTimestampsMs.peekFirst() < timestampMs) {
|
||||||
final BroadcastEvent broadcastEvent = broadcastEvents.valueAt(i);
|
final long dispatchTimestampMs = dispatchTimestampsMs.peekFirst();
|
||||||
final BroadcastResponseStats responseStats =
|
final long elapsedDurationMs = timestampMs - dispatchTimestampMs;
|
||||||
getBroadcastResponseStats(broadcastEvent);
|
// Only increment the counts if the broadcast was sent not too long ago, as
|
||||||
if (responseStats == null) {
|
// decided by 'broadcastResponseWindowDurationMs' and is part of a new session.
|
||||||
continue;
|
// That is, it occurred 'broadcastsSessionWithResponseDurationMs' after the
|
||||||
}
|
// previously handled broadcast event which is represented by
|
||||||
switch (event) {
|
// 'broadcastsSessionEndTimestampMs'.
|
||||||
case NOTIFICATION_EVENT_TYPE_POSTED:
|
if (elapsedDurationMs <= broadcastResponseWindowDurationMs
|
||||||
responseStats.incrementNotificationsPostedCount(1);
|
&& dispatchTimestampMs >= broadcastsSessionEndTimestampMs) {
|
||||||
break;
|
if (broadcastsSessionEndTimestampMs != 0
|
||||||
case NOTIFICATION_EVENT_TYPE_UPDATED:
|
&& !recordAllBroadcastsSessionsWithinResponseWindow) {
|
||||||
responseStats.incrementNotificationsUpdatedCount(1);
|
break;
|
||||||
break;
|
}
|
||||||
case NOTIFICATION_EVENT_TYPE_CANCELLED:
|
final BroadcastResponseStats responseStats =
|
||||||
responseStats.incrementNotificationsCancelledCount(1);
|
getOrCreateBroadcastResponseStats(broadcastEvent);
|
||||||
break;
|
responseStats.incrementBroadcastsDispatchedCount(1);
|
||||||
default:
|
broadcastsSessionEndTimestampMs = dispatchTimestampMs
|
||||||
Slog.wtf(TAG, "Unknown event: " + event);
|
+ broadcastsSessionWithResponseDurationMs;
|
||||||
|
switch (event) {
|
||||||
|
case NOTIFICATION_EVENT_TYPE_POSTED:
|
||||||
|
responseStats.incrementNotificationsPostedCount(1);
|
||||||
|
break;
|
||||||
|
case NOTIFICATION_EVENT_TYPE_UPDATED:
|
||||||
|
responseStats.incrementNotificationsUpdatedCount(1);
|
||||||
|
break;
|
||||||
|
case NOTIFICATION_EVENT_TYPE_CANCELLED:
|
||||||
|
responseStats.incrementNotificationsCancelledCount(1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Slog.wtf(TAG, "Unknown event: " + event);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
dispatchTimestampsMs.removeFirst();
|
||||||
|
}
|
||||||
|
if (dispatchTimestampsMs.size() == 0) {
|
||||||
|
broadcastEvents.removeAt(i);
|
||||||
}
|
}
|
||||||
broadcastEvents.removeAt(i);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GuardedBy("mLock")
|
||||||
|
private void recordAndPruneOldBroadcastDispatchTimestamps(BroadcastEvent broadcastEvent) {
|
||||||
|
final LongArrayQueue timestampsMs = broadcastEvent.getTimestampsMs();
|
||||||
|
final long broadcastResponseWindowDurationMs =
|
||||||
|
mAppStandby.getBroadcastResponseWindowDurationMs();
|
||||||
|
final long broadcastsSessionDurationMs =
|
||||||
|
mAppStandby.getBroadcastSessionsDurationMs();
|
||||||
|
final long nowElapsedMs = SystemClock.elapsedRealtime();
|
||||||
|
long broadcastsSessionEndTimestampMs = 0;
|
||||||
|
while (timestampsMs.size() > 0
|
||||||
|
&& timestampsMs.peekFirst() < (nowElapsedMs - broadcastResponseWindowDurationMs)) {
|
||||||
|
final long eventTimestampMs = timestampsMs.peekFirst();
|
||||||
|
if (eventTimestampMs >= broadcastsSessionEndTimestampMs) {
|
||||||
|
final BroadcastResponseStats responseStats =
|
||||||
|
getOrCreateBroadcastResponseStats(broadcastEvent);
|
||||||
|
responseStats.incrementBroadcastsDispatchedCount(1);
|
||||||
|
broadcastsSessionEndTimestampMs = eventTimestampMs + broadcastsSessionDurationMs;
|
||||||
|
}
|
||||||
|
timestampsMs.removeFirst();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@NonNull List<BroadcastResponseStats> queryBroadcastResponseStats(int callingUid,
|
@NonNull List<BroadcastResponseStats> queryBroadcastResponseStats(int callingUid,
|
||||||
@Nullable String packageName, @IntRange(from = 0) long id, @UserIdInt int userId) {
|
@Nullable String packageName, @IntRange(from = 0) long id, @UserIdInt int userId) {
|
||||||
final List<BroadcastResponseStats> broadcastResponseStatsList = new ArrayList<>();
|
final List<BroadcastResponseStats> broadcastResponseStatsList = new ArrayList<>();
|
||||||
@@ -247,7 +292,7 @@ class BroadcastResponseStatsTracker {
|
|||||||
|
|
||||||
@GuardedBy("mLock")
|
@GuardedBy("mLock")
|
||||||
@Nullable
|
@Nullable
|
||||||
private LongSparseArray<BroadcastEvent> getBroadcastEventsLocked(
|
private ArraySet<BroadcastEvent> getBroadcastEventsLocked(
|
||||||
@NonNull String packageName, UserHandle user) {
|
@NonNull String packageName, UserHandle user) {
|
||||||
final UserBroadcastEvents userBroadcastEvents = mUserBroadcastEvents.get(
|
final UserBroadcastEvents userBroadcastEvents = mUserBroadcastEvents.get(
|
||||||
user.getIdentifier());
|
user.getIdentifier());
|
||||||
@@ -259,7 +304,7 @@ class BroadcastResponseStatsTracker {
|
|||||||
|
|
||||||
@GuardedBy("mLock")
|
@GuardedBy("mLock")
|
||||||
@NonNull
|
@NonNull
|
||||||
private LongSparseArray<BroadcastEvent> getOrCreateBroadcastEventsLocked(
|
private ArraySet<BroadcastEvent> getOrCreateBroadcastEventsLocked(
|
||||||
@NonNull String packageName, UserHandle user) {
|
@NonNull String packageName, UserHandle user) {
|
||||||
UserBroadcastEvents userBroadcastEvents = mUserBroadcastEvents.get(user.getIdentifier());
|
UserBroadcastEvents userBroadcastEvents = mUserBroadcastEvents.get(user.getIdentifier());
|
||||||
if (userBroadcastEvents == null) {
|
if (userBroadcastEvents == null) {
|
||||||
@@ -269,16 +314,6 @@ class BroadcastResponseStatsTracker {
|
|||||||
return userBroadcastEvents.getOrCreateBroadcastEvents(packageName);
|
return userBroadcastEvents.getOrCreateBroadcastEvents(packageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GuardedBy("mLock")
|
|
||||||
@Nullable
|
|
||||||
private BroadcastResponseStats getBroadcastResponseStats(
|
|
||||||
@NonNull BroadcastEvent broadcastEvent) {
|
|
||||||
final int sourceUid = broadcastEvent.getSourceUid();
|
|
||||||
final SparseArray<UserBroadcastResponseStats> responseStatsForUid =
|
|
||||||
mUserResponseStats.get(sourceUid);
|
|
||||||
return getBroadcastResponseStats(responseStatsForUid, broadcastEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
@GuardedBy("mLock")
|
@GuardedBy("mLock")
|
||||||
@Nullable
|
@Nullable
|
||||||
private BroadcastResponseStats getBroadcastResponseStats(
|
private BroadcastResponseStats getBroadcastResponseStats(
|
||||||
@@ -315,6 +350,20 @@ class BroadcastResponseStatsTracker {
|
|||||||
return userResponseStats.getOrCreateBroadcastResponseStats(broadcastEvent);
|
return userResponseStats.getOrCreateBroadcastResponseStats(broadcastEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static BroadcastEvent getOrCreateBroadcastEvent(
|
||||||
|
ArraySet<BroadcastEvent> broadcastEvents,
|
||||||
|
int sourceUid, String targetPackage, int targetUserId, long idForResponseEvent) {
|
||||||
|
final BroadcastEvent broadcastEvent = new BroadcastEvent(
|
||||||
|
sourceUid, targetPackage, targetUserId, idForResponseEvent);
|
||||||
|
final int index = broadcastEvents.indexOf(broadcastEvent);
|
||||||
|
if (index >= 0) {
|
||||||
|
return broadcastEvents.valueAt(index);
|
||||||
|
} else {
|
||||||
|
broadcastEvents.add(broadcastEvent);
|
||||||
|
return broadcastEvent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void dump(@NonNull IndentingPrintWriter ipw) {
|
void dump(@NonNull IndentingPrintWriter ipw) {
|
||||||
ipw.println("Broadcast response stats:");
|
ipw.println("Broadcast response stats:");
|
||||||
ipw.increaseIndent();
|
ipw.increaseIndent();
|
||||||
|
|||||||
@@ -19,7 +19,8 @@ package com.android.server.usage;
|
|||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.util.ArrayMap;
|
import android.util.ArrayMap;
|
||||||
import android.util.LongSparseArray;
|
import android.util.ArraySet;
|
||||||
|
import android.util.LongArrayQueue;
|
||||||
import android.util.TimeUtils;
|
import android.util.TimeUtils;
|
||||||
|
|
||||||
import com.android.internal.util.IndentingPrintWriter;
|
import com.android.internal.util.IndentingPrintWriter;
|
||||||
@@ -30,17 +31,17 @@ class UserBroadcastEvents {
|
|||||||
* Here targetPackage refers to the package receiving the broadcast and BroadcastEvent objects
|
* Here targetPackage refers to the package receiving the broadcast and BroadcastEvent objects
|
||||||
* corresponding to each broadcast it is receiving.
|
* corresponding to each broadcast it is receiving.
|
||||||
*/
|
*/
|
||||||
private ArrayMap<String, LongSparseArray<BroadcastEvent>> mBroadcastEvents = new ArrayMap();
|
private ArrayMap<String, ArraySet<BroadcastEvent>> mBroadcastEvents = new ArrayMap();
|
||||||
|
|
||||||
@Nullable LongSparseArray<BroadcastEvent> getBroadcastEvents(@NonNull String packageName) {
|
@Nullable ArraySet<BroadcastEvent> getBroadcastEvents(@NonNull String packageName) {
|
||||||
return mBroadcastEvents.get(packageName);
|
return mBroadcastEvents.get(packageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull LongSparseArray<BroadcastEvent> getOrCreateBroadcastEvents(
|
@NonNull ArraySet<BroadcastEvent> getOrCreateBroadcastEvents(
|
||||||
@NonNull String packageName) {
|
@NonNull String packageName) {
|
||||||
LongSparseArray<BroadcastEvent> broadcastEvents = mBroadcastEvents.get(packageName);
|
ArraySet<BroadcastEvent> broadcastEvents = mBroadcastEvents.get(packageName);
|
||||||
if (broadcastEvents == null) {
|
if (broadcastEvents == null) {
|
||||||
broadcastEvents = new LongSparseArray<>();
|
broadcastEvents = new ArraySet<>();
|
||||||
mBroadcastEvents.put(packageName, broadcastEvents);
|
mBroadcastEvents.put(packageName, broadcastEvents);
|
||||||
}
|
}
|
||||||
return broadcastEvents;
|
return broadcastEvents;
|
||||||
@@ -56,7 +57,7 @@ class UserBroadcastEvents {
|
|||||||
|
|
||||||
void clear(int uid) {
|
void clear(int uid) {
|
||||||
for (int i = mBroadcastEvents.size() - 1; i >= 0; --i) {
|
for (int i = mBroadcastEvents.size() - 1; i >= 0; --i) {
|
||||||
final LongSparseArray<BroadcastEvent> broadcastEvents = mBroadcastEvents.valueAt(i);
|
final ArraySet<BroadcastEvent> broadcastEvents = mBroadcastEvents.valueAt(i);
|
||||||
for (int j = broadcastEvents.size() - 1; j >= 0; --j) {
|
for (int j = broadcastEvents.size() - 1; j >= 0; --j) {
|
||||||
if (broadcastEvents.valueAt(j).getSourceUid() == uid) {
|
if (broadcastEvents.valueAt(j).getSourceUid() == uid) {
|
||||||
broadcastEvents.removeAt(j);
|
broadcastEvents.removeAt(j);
|
||||||
@@ -68,18 +69,26 @@ class UserBroadcastEvents {
|
|||||||
void dump(@NonNull IndentingPrintWriter ipw) {
|
void dump(@NonNull IndentingPrintWriter ipw) {
|
||||||
for (int i = 0; i < mBroadcastEvents.size(); ++i) {
|
for (int i = 0; i < mBroadcastEvents.size(); ++i) {
|
||||||
final String packageName = mBroadcastEvents.keyAt(i);
|
final String packageName = mBroadcastEvents.keyAt(i);
|
||||||
final LongSparseArray<BroadcastEvent> broadcastEvents = mBroadcastEvents.valueAt(i);
|
final ArraySet<BroadcastEvent> broadcastEvents = mBroadcastEvents.valueAt(i);
|
||||||
ipw.println(packageName + ":");
|
ipw.println(packageName + ":");
|
||||||
ipw.increaseIndent();
|
ipw.increaseIndent();
|
||||||
if (broadcastEvents.size() == 0) {
|
if (broadcastEvents.size() == 0) {
|
||||||
ipw.println("<empty>");
|
ipw.println("<empty>");
|
||||||
} else {
|
} else {
|
||||||
for (int j = 0; j < broadcastEvents.size(); ++j) {
|
for (int j = 0; j < broadcastEvents.size(); ++j) {
|
||||||
final long timestampMs = broadcastEvents.keyAt(j);
|
|
||||||
final BroadcastEvent broadcastEvent = broadcastEvents.valueAt(j);
|
final BroadcastEvent broadcastEvent = broadcastEvents.valueAt(j);
|
||||||
TimeUtils.formatDuration(timestampMs, ipw);
|
|
||||||
ipw.print(": ");
|
|
||||||
ipw.println(broadcastEvent);
|
ipw.println(broadcastEvent);
|
||||||
|
ipw.increaseIndent();
|
||||||
|
final LongArrayQueue timestampsMs = broadcastEvent.getTimestampsMs();
|
||||||
|
for (int timestampIdx = 0; timestampIdx < timestampsMs.size(); ++timestampIdx) {
|
||||||
|
if (timestampIdx > 0) {
|
||||||
|
ipw.print(',');
|
||||||
|
}
|
||||||
|
final long timestampMs = timestampsMs.get(timestampIdx);
|
||||||
|
TimeUtils.formatDuration(timestampMs, ipw);
|
||||||
|
}
|
||||||
|
ipw.println();
|
||||||
|
ipw.decreaseIndent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ipw.decreaseIndent();
|
ipw.decreaseIndent();
|
||||||
|
|||||||
Reference in New Issue
Block a user