diff --git a/Android.mk b/Android.mk
index e219661b19f1ddd9795be2bc0302c446c214d66d..d7d9c900e3bf9fca03f6960687e61b699754a2a8 100644
--- a/Android.mk
+++ b/Android.mk
@@ -252,6 +252,11 @@ framework_docs_LOCAL_DROIDDOC_OPTIONS += \
-federate SupportLib https://developer.android.com \
-federationapi SupportLib prebuilts/sdk/current/support-api.txt
+# Federate AndroidX references against local API file.
+framework_docs_LOCAL_DROIDDOC_OPTIONS += \
+ -federate AndroidX https://developer.android.com \
+ -federationapi AndroidX prebuilts/sdk/current/androidx-api.txt
+
# ==== Public API diff ===========================
include $(CLEAR_VARS)
diff --git a/apct-tests/perftests/core/AndroidTest.xml b/apct-tests/perftests/core/AndroidTest.xml
new file mode 100644
index 0000000000000000000000000000000000000000..6aa34a627940adf67417831988e7c239e5376eb7
--- /dev/null
+++ b/apct-tests/perftests/core/AndroidTest.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apct-tests/perftests/multiuser/Android.mk b/apct-tests/perftests/multiuser/Android.mk
index a803369d1e03a74ae508cf612a4562a709808392..9bc7d051121ad98ee987fe8b0d35f37df55d0cd8 100644
--- a/apct-tests/perftests/multiuser/Android.mk
+++ b/apct-tests/perftests/multiuser/Android.mk
@@ -26,6 +26,8 @@ LOCAL_STATIC_JAVA_LIBRARIES := \
LOCAL_PACKAGE_NAME := MultiUserPerfTests
LOCAL_PRIVATE_PLATFORM_APIS := true
+LOCAL_COMPATIBILITY_SUITE += device-tests
+
LOCAL_CERTIFICATE := platform
include $(BUILD_PACKAGE)
diff --git a/apct-tests/perftests/multiuser/AndroidTest.xml b/apct-tests/perftests/multiuser/AndroidTest.xml
new file mode 100644
index 0000000000000000000000000000000000000000..6ede8275afcb612a5e2d04413f8def0678c81f42
--- /dev/null
+++ b/apct-tests/perftests/multiuser/AndroidTest.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/api/current.txt b/api/current.txt
index 406ebac6c5ebe0882df35a4d05016082c9a4bb5e..992c60c383d2a0811e6692defcabba3a6fe9bcca 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -1605,17 +1605,17 @@ package android {
field public static final int holo_purple = 17170458; // 0x106001a
field public static final int holo_red_dark = 17170455; // 0x1060017
field public static final int holo_red_light = 17170454; // 0x1060016
- field public static final int primary_text_dark = 17170433; // 0x1060001
- field public static final int primary_text_dark_nodisable = 17170434; // 0x1060002
- field public static final int primary_text_light = 17170435; // 0x1060003
- field public static final int primary_text_light_nodisable = 17170436; // 0x1060004
- field public static final int secondary_text_dark = 17170437; // 0x1060005
- field public static final int secondary_text_dark_nodisable = 17170438; // 0x1060006
- field public static final int secondary_text_light = 17170439; // 0x1060007
- field public static final int secondary_text_light_nodisable = 17170440; // 0x1060008
+ field public static final deprecated int primary_text_dark = 17170433; // 0x1060001
+ field public static final deprecated int primary_text_dark_nodisable = 17170434; // 0x1060002
+ field public static final deprecated int primary_text_light = 17170435; // 0x1060003
+ field public static final deprecated int primary_text_light_nodisable = 17170436; // 0x1060004
+ field public static final deprecated int secondary_text_dark = 17170437; // 0x1060005
+ field public static final deprecated int secondary_text_dark_nodisable = 17170438; // 0x1060006
+ field public static final deprecated int secondary_text_light = 17170439; // 0x1060007
+ field public static final deprecated int secondary_text_light_nodisable = 17170440; // 0x1060008
field public static final int tab_indicator_text = 17170441; // 0x1060009
- field public static final int tertiary_text_dark = 17170448; // 0x1060010
- field public static final int tertiary_text_light = 17170449; // 0x1060011
+ field public static final deprecated int tertiary_text_dark = 17170448; // 0x1060010
+ field public static final deprecated int tertiary_text_light = 17170449; // 0x1060011
field public static final int transparent = 17170445; // 0x106000d
field public static final int white = 17170443; // 0x106000b
field public static final int widget_edittext_dark = 17170442; // 0x106000a
@@ -6115,8 +6115,12 @@ package android.app {
method public android.view.WindowAnimationFrameStats getWindowAnimationFrameStats();
method public android.view.WindowContentFrameStats getWindowContentFrameStats(int);
method public java.util.List getWindows();
+ method public void grantRuntimePermission(java.lang.String, java.lang.String);
+ method public void grantRuntimePermissionAsUser(java.lang.String, java.lang.String, android.os.UserHandle);
method public boolean injectInputEvent(android.view.InputEvent, boolean);
method public boolean performGlobalAction(int);
+ method public void revokeRuntimePermission(java.lang.String, java.lang.String);
+ method public void revokeRuntimePermissionAsUser(java.lang.String, java.lang.String, android.os.UserHandle);
method public void setOnAccessibilityEventListener(android.app.UiAutomation.OnAccessibilityEventListener);
method public boolean setRotation(int);
method public void setRunAsMonkey(boolean);
@@ -6464,7 +6468,6 @@ package android.app.admin {
method public java.lang.CharSequence getOrganizationName(android.content.ComponentName);
method public java.util.List getOverrideApns(android.content.ComponentName);
method public android.app.admin.DevicePolicyManager getParentProfileInstance(android.content.ComponentName);
- method public java.lang.String getPasswordBlacklistName(android.content.ComponentName);
method public long getPasswordExpiration(android.content.ComponentName);
method public long getPasswordExpirationTimeout(android.content.ComponentName);
method public int getPasswordHistoryLength(android.content.ComponentName);
@@ -6501,7 +6504,7 @@ package android.app.admin {
method public boolean installExistingPackage(android.content.ComponentName, java.lang.String);
method public boolean installKeyPair(android.content.ComponentName, java.security.PrivateKey, java.security.cert.Certificate, java.lang.String);
method public boolean installKeyPair(android.content.ComponentName, java.security.PrivateKey, java.security.cert.Certificate[], java.lang.String, boolean);
- method public boolean installKeyPair(android.content.ComponentName, java.security.PrivateKey, java.security.cert.Certificate[], java.lang.String, boolean, boolean);
+ method public boolean installKeyPair(android.content.ComponentName, java.security.PrivateKey, java.security.cert.Certificate[], java.lang.String, int);
method public boolean isActivePasswordSufficient();
method public boolean isAdminActive(android.content.ComponentName);
method public boolean isAffiliatedUser();
@@ -6573,7 +6576,6 @@ package android.app.admin {
method public void setOrganizationName(android.content.ComponentName, java.lang.CharSequence);
method public void setOverrideApnsEnabled(android.content.ComponentName, boolean);
method public java.lang.String[] setPackagesSuspended(android.content.ComponentName, java.lang.String[], boolean);
- method public boolean setPasswordBlacklist(android.content.ComponentName, java.lang.String, java.util.List);
method public void setPasswordExpirationTimeout(android.content.ComponentName, long);
method public void setPasswordHistoryLength(android.content.ComponentName, int);
method public void setPasswordMinimumLength(android.content.ComponentName, int);
@@ -6685,6 +6687,8 @@ package android.app.admin {
field public static final int ID_TYPE_IMEI = 4; // 0x4
field public static final int ID_TYPE_MEID = 8; // 0x8
field public static final int ID_TYPE_SERIAL = 2; // 0x2
+ field public static final int INSTALLKEY_REQUEST_CREDENTIALS_ACCESS = 1; // 0x1
+ field public static final int INSTALLKEY_SET_USER_SELECTABLE = 2; // 0x2
field public static final int KEYGUARD_DISABLE_BIOMETRICS = 416; // 0x1a0
field public static final int KEYGUARD_DISABLE_FACE = 128; // 0x80
field public static final int KEYGUARD_DISABLE_FEATURES_ALL = 2147483647; // 0x7fffffff
@@ -7213,6 +7217,7 @@ package android.app.slice {
field public static final java.lang.String HINT_LIST_ITEM = "list_item";
field public static final java.lang.String HINT_NO_TINT = "no_tint";
field public static final java.lang.String HINT_PARTIAL = "partial";
+ field public static final java.lang.String HINT_PERMISSION_REQUEST = "permission_request";
field public static final java.lang.String HINT_SEE_MORE = "see_more";
field public static final java.lang.String HINT_SELECTED = "selected";
field public static final java.lang.String HINT_SHORTCUT = "shortcut";
@@ -7221,6 +7226,7 @@ package android.app.slice {
field public static final java.lang.String HINT_TTL = "ttl";
field public static final java.lang.String SUBTYPE_COLOR = "color";
field public static final java.lang.String SUBTYPE_CONTENT_DESCRIPTION = "content_description";
+ field public static final java.lang.String SUBTYPE_LAYOUT_DIRECTION = "layout_direction";
field public static final java.lang.String SUBTYPE_MAX = "max";
field public static final java.lang.String SUBTYPE_MESSAGE = "message";
field public static final java.lang.String SUBTYPE_MILLIS = "millis";
@@ -7281,11 +7287,14 @@ package android.app.slice {
public class SliceManager {
method public android.app.slice.Slice bindSlice(android.net.Uri, java.util.List);
method public android.app.slice.Slice bindSlice(android.content.Intent, java.util.List);
+ method public int checkSlicePermission(android.net.Uri, int, int);
method public java.util.List getPinnedSlices();
method public java.util.List getPinnedSpecs(android.net.Uri);
method public java.util.Collection getSliceDescendants(android.net.Uri);
+ method public void grantSlicePermission(java.lang.String, android.net.Uri);
method public android.net.Uri mapIntentToUri(android.content.Intent);
method public void pinSlice(android.net.Uri, java.util.List);
+ method public void revokeSlicePermission(java.lang.String, android.net.Uri);
method public void unpinSlice(android.net.Uri);
field public static final java.lang.String CATEGORY_SLICE = "android.app.slice.category.SLICE";
field public static final java.lang.String SLICE_METADATA_KEY = "android.metadata.SLICE_URI";
@@ -7299,6 +7308,7 @@ package android.app.slice {
}
public abstract class SliceProvider extends android.content.ContentProvider {
+ ctor public SliceProvider(java.lang.String...);
ctor public SliceProvider();
method public final int delete(android.net.Uri, java.lang.String, java.lang.String[]);
method public final java.lang.String getType(android.net.Uri);
@@ -10904,6 +10914,7 @@ package android.content.pm {
method public java.util.List getShortcutConfigActivityList(java.lang.String, android.os.UserHandle);
method public android.graphics.drawable.Drawable getShortcutIconDrawable(android.content.pm.ShortcutInfo, int);
method public java.util.List getShortcuts(android.content.pm.LauncherApps.ShortcutQuery, android.os.UserHandle);
+ method public android.os.Bundle getSuspendedPackageLauncherExtras(java.lang.String, android.os.UserHandle);
method public boolean hasShortcutHostPermission();
method public boolean isActivityEnabled(android.content.ComponentName, android.os.UserHandle);
method public boolean isPackageEnabled(java.lang.String, android.os.UserHandle);
@@ -10928,6 +10939,7 @@ package android.content.pm {
method public abstract void onPackageRemoved(java.lang.String, android.os.UserHandle);
method public abstract void onPackagesAvailable(java.lang.String[], android.os.UserHandle, boolean);
method public void onPackagesSuspended(java.lang.String[], android.os.UserHandle);
+ method public void onPackagesSuspended(java.lang.String[], android.os.Bundle, android.os.UserHandle);
method public abstract void onPackagesUnavailable(java.lang.String[], android.os.UserHandle, boolean);
method public void onPackagesUnsuspended(java.lang.String[], android.os.UserHandle);
method public void onShortcutsChanged(java.lang.String, java.util.List, android.os.UserHandle);
@@ -13639,22 +13651,22 @@ package android.graphics {
method public int getAllocator();
method public boolean getConserveMemory();
method public android.graphics.Rect getCrop();
- method public boolean getDecodeAsAlphaMask();
- method public boolean getMutable();
method public android.graphics.ImageDecoder.OnPartialImageListener getOnPartialImageListener();
method public android.graphics.PostProcessor getPostProcessor();
- method public boolean getRequireUnpremultiplied();
- method public android.util.Size getSampledSize(int);
- method public android.graphics.ImageDecoder setAllocator(int);
- method public android.graphics.ImageDecoder setConserveMemory(boolean);
- method public android.graphics.ImageDecoder setCrop(android.graphics.Rect);
- method public android.graphics.ImageDecoder setDecodeAsAlphaMask(boolean);
- method public android.graphics.ImageDecoder setMutable(boolean);
- method public android.graphics.ImageDecoder setOnPartialImageListener(android.graphics.ImageDecoder.OnPartialImageListener);
- method public android.graphics.ImageDecoder setPostProcessor(android.graphics.PostProcessor);
- method public android.graphics.ImageDecoder setRequireUnpremultiplied(boolean);
- method public android.graphics.ImageDecoder setResize(int, int);
- method public android.graphics.ImageDecoder setResize(int);
+ method public boolean isDecodeAsAlphaMaskEnabled();
+ method public boolean isMutableRequired();
+ method public boolean isUnpremultipliedRequired();
+ method public void setAllocator(int);
+ method public void setConserveMemory(boolean);
+ method public void setCrop(android.graphics.Rect);
+ method public void setDecodeAsAlphaMaskEnabled(boolean);
+ method public void setMutableRequired(boolean);
+ method public void setOnPartialImageListener(android.graphics.ImageDecoder.OnPartialImageListener);
+ method public void setPostProcessor(android.graphics.PostProcessor);
+ method public void setTargetColorSpace(android.graphics.ColorSpace);
+ method public void setTargetSampleSize(int);
+ method public void setTargetSize(int, int);
+ method public void setUnpremultipliedRequired(boolean);
field public static final int ALLOCATOR_DEFAULT = 0; // 0x0
field public static final int ALLOCATOR_HARDWARE = 3; // 0x3
field public static final int ALLOCATOR_SHARED_MEMORY = 2; // 0x2
@@ -13670,6 +13682,7 @@ package android.graphics {
}
public static class ImageDecoder.ImageInfo {
+ method public android.graphics.ColorSpace getColorSpace();
method public java.lang.String getMimeType();
method public android.util.Size getSize();
method public boolean isAnimated();
@@ -21957,6 +21970,7 @@ package android.media {
}
public final class AudioDeviceInfo {
+ method public java.lang.String getAddress();
method public int[] getChannelCounts();
method public int[] getChannelIndexMasks();
method public int[] getChannelMasks();
@@ -24004,6 +24018,7 @@ package android.media {
field public static final int MEDIA_INFO_BUFFERING_START = 701; // 0x2bd
field public static final int MEDIA_INFO_METADATA_UPDATE = 802; // 0x322
field public static final int MEDIA_INFO_NOT_SEEKABLE = 801; // 0x321
+ field public static final int MEDIA_INFO_STARTED_AS_NEXT = 2; // 0x2
field public static final int MEDIA_INFO_SUBTITLE_TIMED_OUT = 902; // 0x386
field public static final int MEDIA_INFO_UNKNOWN = 1; // 0x1
field public static final int MEDIA_INFO_UNSUPPORTED_SUBTITLE = 901; // 0x385
@@ -24447,6 +24462,7 @@ package android.media {
}
public final class MicrophoneInfo {
+ method public java.lang.String getAddress();
method public java.util.List> getChannelMapping();
method public java.lang.String getDescription();
method public int getDirectionality();
@@ -27003,8 +27019,8 @@ package android.net {
public static final class IpSecManager.UdpEncapsulationSocket implements java.lang.AutoCloseable {
method public void close() throws java.io.IOException;
+ method public java.io.FileDescriptor getFileDescriptor();
method public int getPort();
- method public java.io.FileDescriptor getSocket();
}
public final class IpSecTransform implements java.lang.AutoCloseable {
@@ -27133,6 +27149,7 @@ package android.net {
method public void bindSocket(java.net.Socket) throws java.io.IOException;
method public void bindSocket(java.io.FileDescriptor) throws java.io.IOException;
method public int describeContents();
+ method public static android.net.Network fromNetworkHandle(long);
method public java.net.InetAddress[] getAllByName(java.lang.String) throws java.net.UnknownHostException;
method public java.net.InetAddress getByName(java.lang.String) throws java.net.UnknownHostException;
method public long getNetworkHandle();
@@ -27232,6 +27249,8 @@ package android.net {
public class NetworkRequest implements android.os.Parcelable {
method public int describeContents();
+ method public boolean hasCapability(int);
+ method public boolean hasTransport(int);
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator CREATOR;
}
@@ -38554,6 +38573,7 @@ package android.security.keystore {
method public boolean isRandomizedEncryptionRequired();
method public boolean isStrongBoxBacked();
method public boolean isTrustedUserPresenceRequired();
+ method public boolean isUnlockedDeviceRequired();
method public boolean isUserAuthenticationRequired();
method public boolean isUserAuthenticationValidWhileOnBody();
method public boolean isUserConfirmationRequired();
@@ -38581,6 +38601,7 @@ package android.security.keystore {
method public android.security.keystore.KeyGenParameterSpec.Builder setRandomizedEncryptionRequired(boolean);
method public android.security.keystore.KeyGenParameterSpec.Builder setSignaturePaddings(java.lang.String...);
method public android.security.keystore.KeyGenParameterSpec.Builder setTrustedUserPresenceRequired(boolean);
+ method public android.security.keystore.KeyGenParameterSpec.Builder setUnlockedDeviceRequired(boolean);
method public android.security.keystore.KeyGenParameterSpec.Builder setUserAuthenticationRequired(boolean);
method public android.security.keystore.KeyGenParameterSpec.Builder setUserAuthenticationValidWhileOnBody(boolean);
method public android.security.keystore.KeyGenParameterSpec.Builder setUserAuthenticationValidityDurationSeconds(int);
@@ -38673,6 +38694,7 @@ package android.security.keystore {
method public boolean isInvalidatedByBiometricEnrollment();
method public boolean isRandomizedEncryptionRequired();
method public boolean isTrustedUserPresenceRequired();
+ method public boolean isUnlockedDeviceRequired();
method public boolean isUserAuthenticationRequired();
method public boolean isUserAuthenticationValidWhileOnBody();
method public boolean isUserConfirmationRequired();
@@ -38692,6 +38714,7 @@ package android.security.keystore {
method public android.security.keystore.KeyProtection.Builder setRandomizedEncryptionRequired(boolean);
method public android.security.keystore.KeyProtection.Builder setSignaturePaddings(java.lang.String...);
method public android.security.keystore.KeyProtection.Builder setTrustedUserPresenceRequired(boolean);
+ method public android.security.keystore.KeyProtection.Builder setUnlockedDeviceRequired(boolean);
method public android.security.keystore.KeyProtection.Builder setUserAuthenticationRequired(boolean);
method public android.security.keystore.KeyProtection.Builder setUserAuthenticationValidWhileOnBody(boolean);
method public android.security.keystore.KeyProtection.Builder setUserAuthenticationValidityDurationSeconds(int);
@@ -41911,17 +41934,17 @@ package android.telephony {
}
public class MbmsDownloadSession implements java.lang.AutoCloseable {
- method public int addProgressListener(android.telephony.mbms.DownloadRequest, java.util.concurrent.Executor, android.telephony.mbms.DownloadProgressListener);
- method public int addStatusListener(android.telephony.mbms.DownloadRequest, java.util.concurrent.Executor, android.telephony.mbms.DownloadStatusListener);
- method public int cancelDownload(android.telephony.mbms.DownloadRequest);
+ method public void addProgressListener(android.telephony.mbms.DownloadRequest, java.util.concurrent.Executor, android.telephony.mbms.DownloadProgressListener);
+ method public void addStatusListener(android.telephony.mbms.DownloadRequest, java.util.concurrent.Executor, android.telephony.mbms.DownloadStatusListener);
+ method public void cancelDownload(android.telephony.mbms.DownloadRequest);
method public void close();
method public static android.telephony.MbmsDownloadSession create(android.content.Context, java.util.concurrent.Executor, android.telephony.mbms.MbmsDownloadSessionCallback);
method public static android.telephony.MbmsDownloadSession create(android.content.Context, java.util.concurrent.Executor, int, android.telephony.mbms.MbmsDownloadSessionCallback);
- method public int download(android.telephony.mbms.DownloadRequest);
+ method public void download(android.telephony.mbms.DownloadRequest);
method public java.io.File getTempFileRootDirectory();
method public java.util.List listPendingDownloads();
- method public int removeProgressListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadProgressListener);
- method public int removeStatusListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStatusListener);
+ method public void removeProgressListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadProgressListener);
+ method public void removeStatusListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStatusListener);
method public void requestDownloadState(android.telephony.mbms.DownloadRequest, android.telephony.mbms.FileInfo);
method public void requestUpdateFileServices(java.util.List);
method public void resetDownloadKnowledge(android.telephony.mbms.DownloadRequest);
@@ -42888,6 +42911,7 @@ package android.telephony.mbms {
field public static final int ERROR_MIDDLEWARE_NOT_BOUND = 2; // 0x2
field public static final int ERROR_NO_UNIQUE_MIDDLEWARE = 1; // 0x1
field public static final int SUCCESS = 0; // 0x0
+ field public static final int UNKNOWN = -1; // 0xffffffff
}
public static class MbmsErrors.DownloadErrors {
@@ -47277,10 +47301,10 @@ package android.view {
method public void addExtraDataToAccessibilityNodeInfo(android.view.accessibility.AccessibilityNodeInfo, java.lang.String, android.os.Bundle);
method public void addFocusables(java.util.ArrayList, int);
method public void addFocusables(java.util.ArrayList, int, int);
- method public void addKeyFallbackListener(android.view.View.OnKeyFallbackListener);
method public void addKeyboardNavigationClusters(java.util.Collection, int);
method public void addOnAttachStateChangeListener(android.view.View.OnAttachStateChangeListener);
method public void addOnLayoutChangeListener(android.view.View.OnLayoutChangeListener);
+ method public void addOnUnhandledKeyEventListener(android.view.View.OnUnhandledKeyEventListener);
method public void addTouchables(java.util.ArrayList);
method public android.view.ViewPropertyAnimator animate();
method public void announceForAccessibility(java.lang.CharSequence);
@@ -47618,7 +47642,6 @@ package android.view {
method public void onInitializeAccessibilityEvent(android.view.accessibility.AccessibilityEvent);
method public void onInitializeAccessibilityNodeInfo(android.view.accessibility.AccessibilityNodeInfo);
method public boolean onKeyDown(int, android.view.KeyEvent);
- method public boolean onKeyFallback(android.view.KeyEvent);
method public boolean onKeyLongPress(int, android.view.KeyEvent);
method public boolean onKeyMultiple(int, int, android.view.KeyEvent);
method public boolean onKeyPreIme(int, android.view.KeyEvent);
@@ -47672,9 +47695,9 @@ package android.view {
method public void refreshDrawableState();
method public void releasePointerCapture();
method public boolean removeCallbacks(java.lang.Runnable);
- method public void removeKeyFallbackListener(android.view.View.OnKeyFallbackListener);
method public void removeOnAttachStateChangeListener(android.view.View.OnAttachStateChangeListener);
method public void removeOnLayoutChangeListener(android.view.View.OnLayoutChangeListener);
+ method public void removeOnUnhandledKeyEventListener(android.view.View.OnUnhandledKeyEventListener);
method public void requestApplyInsets();
method public deprecated void requestFitSystemWindows();
method public final boolean requestFocus();
@@ -48098,10 +48121,6 @@ package android.view {
method public abstract boolean onHover(android.view.View, android.view.MotionEvent);
}
- public static abstract interface View.OnKeyFallbackListener {
- method public abstract boolean onKeyFallback(android.view.View, android.view.KeyEvent);
- }
-
public static abstract interface View.OnKeyListener {
method public abstract boolean onKey(android.view.View, int, android.view.KeyEvent);
}
@@ -48126,6 +48145,10 @@ package android.view {
method public abstract boolean onTouch(android.view.View, android.view.MotionEvent);
}
+ public static abstract interface View.OnUnhandledKeyEventListener {
+ method public abstract boolean onUnhandledKeyEvent(android.view.View, android.view.KeyEvent);
+ }
+
public final class ViewAnimationUtils {
method public static android.animation.Animator createCircularReveal(android.view.View, int, int, float, float);
}
@@ -50412,9 +50435,9 @@ package android.view.textclassifier {
ctor public TextClassification.Options();
method public int describeContents();
method public android.os.LocaleList getDefaultLocales();
- method public java.util.Calendar getReferenceTime();
+ method public java.time.ZonedDateTime getReferenceTime();
method public android.view.textclassifier.TextClassification.Options setDefaultLocales(android.os.LocaleList);
- method public android.view.textclassifier.TextClassification.Options setReferenceTime(java.util.Calendar);
+ method public android.view.textclassifier.TextClassification.Options setReferenceTime(java.time.ZonedDateTime);
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator CREATOR;
}
diff --git a/api/removed.txt b/api/removed.txt
index 9fe25c90872b87ce432341d288f574ee4da89665..2d76c5a575a0e70fcc2fe14ef63d0766119266b1 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -183,7 +183,15 @@ package android.graphics {
public final class ImageDecoder implements java.lang.AutoCloseable {
method public deprecated boolean getAsAlphaMask();
+ method public deprecated boolean getDecodeAsAlphaMask();
+ method public deprecated boolean getMutable();
+ method public deprecated boolean getRequireUnpremultiplied();
method public deprecated android.graphics.ImageDecoder setAsAlphaMask(boolean);
+ method public deprecated android.graphics.ImageDecoder setDecodeAsAlphaMask(boolean);
+ method public deprecated android.graphics.ImageDecoder setMutable(boolean);
+ method public deprecated android.graphics.ImageDecoder setRequireUnpremultiplied(boolean);
+ method public deprecated android.graphics.ImageDecoder setResize(int, int);
+ method public deprecated android.graphics.ImageDecoder setResize(int);
field public static final deprecated int ERROR_SOURCE_ERROR = 3; // 0x3
field public static final deprecated int ERROR_SOURCE_EXCEPTION = 1; // 0x1
field public static final deprecated int ERROR_SOURCE_INCOMPLETE = 2; // 0x2
diff --git a/api/system-current.txt b/api/system-current.txt
index 5568dbad0e8c778699d9179f6248879485a4a9d9..165c6ae1e628984dc510c8d2c57c90f94414849a 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -57,6 +57,7 @@ package android {
field public static final java.lang.String CONFIGURE_DISPLAY_BRIGHTNESS = "android.permission.CONFIGURE_DISPLAY_BRIGHTNESS";
field public static final java.lang.String CONNECTIVITY_INTERNAL = "android.permission.CONNECTIVITY_INTERNAL";
field public static final java.lang.String CONNECTIVITY_USE_RESTRICTED_NETWORKS = "android.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS";
+ field public static final java.lang.String CONTROL_DISPLAY_SATURATION = "android.permission.CONTROL_DISPLAY_SATURATION";
field public static final java.lang.String CONTROL_INCALL_EXPERIENCE = "android.permission.CONTROL_INCALL_EXPERIENCE";
field public static final java.lang.String CONTROL_LOCATION_UPDATES = "android.permission.CONTROL_LOCATION_UPDATES";
field public static final java.lang.String CONTROL_VPN = "android.permission.CONTROL_VPN";
@@ -1252,6 +1253,7 @@ package android.hardware.display {
method public android.hardware.display.BrightnessConfiguration getDefaultBrightnessConfiguration();
method public android.graphics.Point getStableDisplaySize();
method public void setBrightnessConfiguration(android.hardware.display.BrightnessConfiguration);
+ method public void setSaturationLevel(float);
}
}
@@ -2101,6 +2103,7 @@ package android.hardware.radio {
method public java.lang.String getVersion();
method public boolean isBackgroundScanningSupported();
method public boolean isCaptureSupported();
+ method public boolean isInitializationRequired();
method public boolean isProgramIdentifierSupported(int);
method public boolean isProgramTypeSupported(int);
method public void writeToParcel(android.os.Parcel, int);
@@ -3102,6 +3105,10 @@ package android.net {
field public static final int ERROR_INVALID_NETWORK = 1; // 0x1
}
+ public final class NetworkCapabilities implements android.os.Parcelable {
+ field public static final int NET_CAPABILITY_OEM_PAID = 22; // 0x16
+ }
+
public class NetworkKey implements android.os.Parcelable {
ctor public NetworkKey(android.net.WifiKey);
method public int describeContents();
@@ -5549,6 +5556,7 @@ package android.telephony.euicc {
package android.telephony.ims {
public final class ImsCallForwardInfo implements android.os.Parcelable {
+ ctor public ImsCallForwardInfo(int, int, int, int, java.lang.String, int);
method public int describeContents();
method public int getCondition();
method public java.lang.String getNumber();
@@ -5863,7 +5871,7 @@ package android.telephony.ims {
}
public final class ImsSsData implements android.os.Parcelable {
- ctor public ImsSsData();
+ ctor public ImsSsData(int, int, int, int, int);
method public int describeContents();
method public boolean isTypeBarring();
method public boolean isTypeCf();
@@ -5914,7 +5922,7 @@ package android.telephony.ims {
}
public final class ImsSsInfo implements android.os.Parcelable {
- ctor public ImsSsInfo();
+ ctor public ImsSsInfo(int, java.lang.String);
method public int describeContents();
method public java.lang.String getIcbNum();
method public int getStatus();
diff --git a/api/test-current.txt b/api/test-current.txt
index d32372517431593801efffc1a1f998b378e19652..b520dfb441d01a521227a305bafaceb2be258990 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -1,8 +1,10 @@
package android {
public static final class Manifest.permission {
+ field public static final java.lang.String ACTIVITY_EMBEDDING = "android.permission.ACTIVITY_EMBEDDING";
field public static final java.lang.String BRIGHTNESS_SLIDER_USAGE = "android.permission.BRIGHTNESS_SLIDER_USAGE";
field public static final java.lang.String CONFIGURE_DISPLAY_BRIGHTNESS = "android.permission.CONFIGURE_DISPLAY_BRIGHTNESS";
+ field public static final java.lang.String MANAGE_ACTIVITY_STACKS = "android.permission.MANAGE_ACTIVITY_STACKS";
}
}
@@ -127,8 +129,8 @@ package android.app {
public final class UiAutomation {
method public void destroy();
method public android.os.ParcelFileDescriptor[] executeShellCommandRw(java.lang.String);
- method public boolean grantRuntimePermission(java.lang.String, java.lang.String, android.os.UserHandle);
- method public boolean revokeRuntimePermission(java.lang.String, java.lang.String, android.os.UserHandle);
+ method public deprecated boolean grantRuntimePermission(java.lang.String, java.lang.String, android.os.UserHandle);
+ method public deprecated boolean revokeRuntimePermission(java.lang.String, java.lang.String, android.os.UserHandle);
}
public class UiModeManager {
diff --git a/cmds/incidentd/src/FdBuffer.cpp b/cmds/incidentd/src/FdBuffer.cpp
index 2b85ec08f9a6dccb17422508dc725f3ba872e670..c6e561f840528c50caa57ab04b45f0565fe86322 100644
--- a/cmds/incidentd/src/FdBuffer.cpp
+++ b/cmds/incidentd/src/FdBuffer.cpp
@@ -34,11 +34,11 @@ FdBuffer::FdBuffer()
FdBuffer::~FdBuffer() {}
-status_t FdBuffer::read(unique_fd* fd, int64_t timeout) {
- struct pollfd pfds = {.fd = fd->get(), .events = POLLIN};
+status_t FdBuffer::read(int fd, int64_t timeout) {
+ struct pollfd pfds = {.fd = fd, .events = POLLIN};
mStartTime = uptimeMillis();
- fcntl(fd->get(), F_SETFL, fcntl(fd->get(), F_GETFL, 0) | O_NONBLOCK);
+ fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK);
while (true) {
if (mBuffer.size() >= MAX_BUFFER_COUNT * BUFFER_SIZE) {
@@ -67,16 +67,16 @@ status_t FdBuffer::read(unique_fd* fd, int64_t timeout) {
VLOG("return event has error %s", strerror(errno));
return errno != 0 ? -errno : UNKNOWN_ERROR;
} else {
- ssize_t amt = ::read(fd->get(), mBuffer.writeBuffer(), mBuffer.currentToWrite());
+ ssize_t amt = ::read(fd, mBuffer.writeBuffer(), mBuffer.currentToWrite());
if (amt < 0) {
if (errno == EAGAIN || errno == EWOULDBLOCK) {
continue;
} else {
- VLOG("Fail to read %d: %s", fd->get(), strerror(errno));
+ VLOG("Fail to read %d: %s", fd, strerror(errno));
return -errno;
}
} else if (amt == 0) {
- VLOG("Reached EOF of fd=%d", fd->get());
+ VLOG("Reached EOF of fd=%d", fd);
break;
}
mBuffer.wp()->move(amt);
@@ -87,7 +87,7 @@ status_t FdBuffer::read(unique_fd* fd, int64_t timeout) {
return NO_ERROR;
}
-status_t FdBuffer::readFully(unique_fd* fd) {
+status_t FdBuffer::readFully(int fd) {
mStartTime = uptimeMillis();
while (true) {
@@ -99,10 +99,10 @@ status_t FdBuffer::readFully(unique_fd* fd) {
}
if (mBuffer.writeBuffer() == NULL) return NO_MEMORY;
- ssize_t amt = TEMP_FAILURE_RETRY(
- ::read(fd->get(), mBuffer.writeBuffer(), mBuffer.currentToWrite()));
+ ssize_t amt =
+ TEMP_FAILURE_RETRY(::read(fd, mBuffer.writeBuffer(), mBuffer.currentToWrite()));
if (amt < 0) {
- VLOG("Fail to read %d: %s", fd->get(), strerror(errno));
+ VLOG("Fail to read %d: %s", fd, strerror(errno));
return -errno;
} else if (amt == 0) {
VLOG("Done reading %zu bytes", mBuffer.size());
@@ -116,20 +116,20 @@ status_t FdBuffer::readFully(unique_fd* fd) {
return NO_ERROR;
}
-status_t FdBuffer::readProcessedDataInStream(unique_fd* fd, unique_fd* toFd, unique_fd* fromFd,
+status_t FdBuffer::readProcessedDataInStream(int fd, unique_fd toFd, unique_fd fromFd,
int64_t timeoutMs, const bool isSysfs) {
struct pollfd pfds[] = {
- {.fd = fd->get(), .events = POLLIN},
- {.fd = toFd->get(), .events = POLLOUT},
- {.fd = fromFd->get(), .events = POLLIN},
+ {.fd = fd, .events = POLLIN},
+ {.fd = toFd.get(), .events = POLLOUT},
+ {.fd = fromFd.get(), .events = POLLIN},
};
mStartTime = uptimeMillis();
// mark all fds non blocking
- fcntl(fd->get(), F_SETFL, fcntl(fd->get(), F_GETFL, 0) | O_NONBLOCK);
- fcntl(toFd->get(), F_SETFL, fcntl(toFd->get(), F_GETFL, 0) | O_NONBLOCK);
- fcntl(fromFd->get(), F_SETFL, fcntl(fromFd->get(), F_GETFL, 0) | O_NONBLOCK);
+ fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK);
+ fcntl(toFd.get(), F_SETFL, fcntl(toFd.get(), F_GETFL, 0) | O_NONBLOCK);
+ fcntl(fromFd.get(), F_SETFL, fcntl(fromFd.get(), F_GETFL, 0) | O_NONBLOCK);
// A circular buffer holds data read from fd and writes to parsing process
uint8_t cirBuf[BUFFER_SIZE];
@@ -166,10 +166,10 @@ status_t FdBuffer::readProcessedDataInStream(unique_fd* fd, unique_fd* toFd, uni
for (int i = 0; i < 3; ++i) {
if ((pfds[i].revents & POLLERR) != 0) {
if (i == 0 && isSysfs) {
- VLOG("fd %d is sysfs, ignore its POLLERR return value", fd->get());
+ VLOG("fd %d is sysfs, ignore its POLLERR return value", fd);
continue;
}
- VLOG("fd[%d]=%d returns error events: %s", i, fd->get(), strerror(errno));
+ VLOG("fd[%d]=%d returns error events: %s", i, fd, strerror(errno));
return errno != 0 ? -errno : UNKNOWN_ERROR;
}
}
@@ -178,17 +178,17 @@ status_t FdBuffer::readProcessedDataInStream(unique_fd* fd, unique_fd* toFd, uni
if (cirSize != BUFFER_SIZE && pfds[0].fd != -1) {
ssize_t amt;
if (rpos >= wpos) {
- amt = ::read(fd->get(), cirBuf + rpos, BUFFER_SIZE - rpos);
+ amt = ::read(fd, cirBuf + rpos, BUFFER_SIZE - rpos);
} else {
- amt = ::read(fd->get(), cirBuf + rpos, wpos - rpos);
+ amt = ::read(fd, cirBuf + rpos, wpos - rpos);
}
if (amt < 0) {
if (!(errno == EAGAIN || errno == EWOULDBLOCK)) {
- VLOG("Fail to read fd %d: %s", fd->get(), strerror(errno));
+ VLOG("Fail to read fd %d: %s", fd, strerror(errno));
return -errno;
} // otherwise just continue
} else if (amt == 0) {
- VLOG("Reached EOF of input file %d", fd->get());
+ VLOG("Reached EOF of input file %d", fd);
pfds[0].fd = -1; // reach EOF so don't have to poll pfds[0].
} else {
rpos += amt;
@@ -200,13 +200,13 @@ status_t FdBuffer::readProcessedDataInStream(unique_fd* fd, unique_fd* toFd, uni
if (cirSize > 0 && pfds[1].fd != -1) {
ssize_t amt;
if (rpos > wpos) {
- amt = ::write(toFd->get(), cirBuf + wpos, rpos - wpos);
+ amt = ::write(toFd.get(), cirBuf + wpos, rpos - wpos);
} else {
- amt = ::write(toFd->get(), cirBuf + wpos, BUFFER_SIZE - wpos);
+ amt = ::write(toFd.get(), cirBuf + wpos, BUFFER_SIZE - wpos);
}
if (amt < 0) {
if (!(errno == EAGAIN || errno == EWOULDBLOCK)) {
- VLOG("Fail to write toFd %d: %s", toFd->get(), strerror(errno));
+ VLOG("Fail to write toFd.get() %d: %s", toFd.get(), strerror(errno));
return -errno;
} // otherwise just continue
} else {
@@ -217,8 +217,8 @@ status_t FdBuffer::readProcessedDataInStream(unique_fd* fd, unique_fd* toFd, uni
// if buffer is empty and fd is closed, close write fd.
if (cirSize == 0 && pfds[0].fd == -1 && pfds[1].fd != -1) {
- VLOG("Close write pipe %d", toFd->get());
- toFd->reset();
+ VLOG("Close write pipe %d", toFd.get());
+ toFd.reset();
pfds[1].fd = -1;
}
@@ -231,14 +231,14 @@ status_t FdBuffer::readProcessedDataInStream(unique_fd* fd, unique_fd* toFd, uni
}
// read from parsing process
- ssize_t amt = ::read(fromFd->get(), mBuffer.writeBuffer(), mBuffer.currentToWrite());
+ ssize_t amt = ::read(fromFd.get(), mBuffer.writeBuffer(), mBuffer.currentToWrite());
if (amt < 0) {
if (!(errno == EAGAIN || errno == EWOULDBLOCK)) {
- VLOG("Fail to read fromFd %d: %s", fromFd->get(), strerror(errno));
+ VLOG("Fail to read fromFd.get() %d: %s", fromFd.get(), strerror(errno));
return -errno;
} // otherwise just continue
} else if (amt == 0) {
- VLOG("Reached EOF of fromFd %d", fromFd->get());
+ VLOG("Reached EOF of fromFd.get() %d", fromFd.get());
break;
} else {
mBuffer.wp()->move(amt);
diff --git a/cmds/incidentd/src/FdBuffer.h b/cmds/incidentd/src/FdBuffer.h
index db3a74b7817821fe9be60cf81eb18b426846f4c3..f467da86602416df68a0851130cda92098bd010b 100644
--- a/cmds/incidentd/src/FdBuffer.h
+++ b/cmds/incidentd/src/FdBuffer.h
@@ -40,13 +40,13 @@ public:
* Returns NO_ERROR if there were no errors or if we timed out.
* Will mark the file O_NONBLOCK.
*/
- status_t read(unique_fd* fd, int64_t timeoutMs);
+ status_t read(int fd, int64_t timeoutMs);
/**
* Read the data until we hit eof.
* Returns NO_ERROR if there were no errors.
*/
- status_t readFully(unique_fd* fd);
+ status_t readFully(int fd);
/**
* Read processed results by streaming data to a parsing process, e.g. incident helper.
@@ -58,8 +58,8 @@ public:
*
* Poll will return POLLERR if fd is from sysfs, handle this edge case.
*/
- status_t readProcessedDataInStream(unique_fd* fd, unique_fd* toFd, unique_fd* fromFd,
- int64_t timeoutMs, const bool isSysfs = false);
+ status_t readProcessedDataInStream(int fd, unique_fd toFd, unique_fd fromFd, int64_t timeoutMs,
+ const bool isSysfs = false);
/**
* Whether we timed out.
diff --git a/cmds/incidentd/src/IncidentService.cpp b/cmds/incidentd/src/IncidentService.cpp
index aeccefdd15c0dbb9c23c5432dd76d4c6526248b3..d02b4dd99067ea69b41553b6cac483dd821c8026 100644
--- a/cmds/incidentd/src/IncidentService.cpp
+++ b/cmds/incidentd/src/IncidentService.cpp
@@ -352,8 +352,7 @@ status_t IncidentService::cmd_privacy(FILE* in, FILE* out, FILE* err, VectortimeoutMs, mIsSysfs);
+ status_t readStatus = buffer.readProcessedDataInStream(fd.get(), std::move(p2cPipe.writeFd()),
+ std::move(c2pPipe.readFd()),
+ this->timeoutMs, mIsSysfs);
if (readStatus != NO_ERROR || buffer.timedOut()) {
ALOGW("FileSection '%s' failed to read data from incident helper: %s, timedout: %s",
@@ -319,8 +320,10 @@ status_t GZipSection::Execute(ReportRequestSet* requests) const {
index++; // look at the next file.
}
VLOG("GZipSection is using file %s, fd=%d", mFilenames[index], fd.get());
- if (fd.get() == -1) return -1;
-
+ if (fd.get() == -1) {
+ ALOGW("GZipSection %s can't open all the files", this->name.string());
+ return NO_ERROR; // e.g. LAST_KMSG will reach here in user build.
+ }
FdBuffer buffer;
Fpipe p2cPipe;
Fpipe c2pPipe;
@@ -354,9 +357,9 @@ status_t GZipSection::Execute(ReportRequestSet* requests) const {
VLOG("GZipSection '%s' editPos=%zd, dataBeginAt=%zd", this->name.string(), editPos,
dataBeginAt);
- status_t readStatus =
- buffer.readProcessedDataInStream(&fd, &p2cPipe.writeFd(), &c2pPipe.readFd(),
- this->timeoutMs, isSysfs(mFilenames[index]));
+ status_t readStatus = buffer.readProcessedDataInStream(
+ fd.get(), std::move(p2cPipe.writeFd()), std::move(c2pPipe.readFd()), this->timeoutMs,
+ isSysfs(mFilenames[index]));
if (readStatus != NO_ERROR || buffer.timedOut()) {
ALOGW("GZipSection '%s' failed to read data from gzip: %s, timedout: %s",
@@ -466,7 +469,7 @@ status_t WorkerThreadSection::Execute(ReportRequestSet* requests) const {
pthread_attr_destroy(&attr);
// Loop reading until either the timeout or the worker side is done (i.e. eof).
- err = buffer.read(&data->pipe.readFd(), this->timeoutMs);
+ err = buffer.read(data->pipe.readFd().get(), this->timeoutMs);
if (err != NO_ERROR) {
// TODO: Log this error into the incident report.
ALOGW("WorkerThreadSection '%s' reader failed with error '%s'", this->name.string(),
@@ -573,7 +576,7 @@ status_t CommandSection::Execute(ReportRequestSet* requests) const {
}
cmdPipe.writeFd().reset();
- status_t readStatus = buffer.read(&ihPipe.readFd(), this->timeoutMs);
+ status_t readStatus = buffer.read(ihPipe.readFd().get(), this->timeoutMs);
if (readStatus != NO_ERROR || buffer.timedOut()) {
ALOGW("CommandSection '%s' failed to read data from incident helper: %s, timedout: %s",
this->name.string(), strerror(-readStatus), buffer.timedOut() ? "true" : "false");
@@ -892,7 +895,7 @@ status_t TombstoneSection::BlockingCall(int pipeWriteFd) const {
// Parent process.
// Read from the pipe concurrently to avoid blocking the child.
FdBuffer buffer;
- err = buffer.readFully(&dumpPipe.readFd());
+ err = buffer.readFully(dumpPipe.readFd().get());
if (err != NO_ERROR) {
ALOGW("TombstoneSection '%s' failed to read stack dump: %d", this->name.string(), err);
dumpPipe.readFd().reset();
diff --git a/cmds/incidentd/tests/FdBuffer_test.cpp b/cmds/incidentd/tests/FdBuffer_test.cpp
index bf770173793f1284e868e0cdb1bd1f75d2392738..7a05d7e071d0ef992311ed582a9d62d9dbcf815a 100644
--- a/cmds/incidentd/tests/FdBuffer_test.cpp
+++ b/cmds/incidentd/tests/FdBuffer_test.cpp
@@ -37,7 +37,6 @@ class FdBufferTest : public Test {
public:
virtual void SetUp() override {
ASSERT_NE(tf.fd, -1);
- tffd.reset(tf.fd);
ASSERT_NE(p2cPipe.init(), -1);
ASSERT_NE(c2pPipe.init(), -1);
}
@@ -57,13 +56,13 @@ public:
EXPECT_EQ(expected[i], '\0');
}
- bool DoDataStream(unique_fd* rFd, unique_fd* wFd) {
+ bool DoDataStream(const unique_fd& rFd, const unique_fd& wFd) {
char buf[BUFFER_SIZE];
ssize_t nRead;
- while ((nRead = read(rFd->get(), buf, BUFFER_SIZE)) > 0) {
+ while ((nRead = read(rFd.get(), buf, BUFFER_SIZE)) > 0) {
ssize_t nWritten = 0;
while (nWritten < nRead) {
- ssize_t amt = write(wFd->get(), buf + nWritten, nRead - nWritten);
+ ssize_t amt = write(wFd.get(), buf + nWritten, nRead - nWritten);
if (amt < 0) {
return false;
}
@@ -76,7 +75,6 @@ public:
protected:
FdBuffer buffer;
TemporaryFile tf;
- unique_fd tffd;
Fpipe p2cPipe;
Fpipe c2pPipe;
@@ -87,7 +85,7 @@ protected:
TEST_F(FdBufferTest, ReadAndWrite) {
std::string testdata = "FdBuffer test string";
ASSERT_TRUE(WriteStringToFile(testdata, tf.path));
- ASSERT_EQ(NO_ERROR, buffer.read(&tffd, READ_TIMEOUT));
+ ASSERT_EQ(NO_ERROR, buffer.read(tf.fd, READ_TIMEOUT));
AssertBufferReadSuccessful(testdata.size());
AssertBufferContent(testdata.c_str());
}
@@ -100,7 +98,7 @@ TEST_F(FdBufferTest, IterateEmpty) {
TEST_F(FdBufferTest, ReadAndIterate) {
std::string testdata = "FdBuffer test string";
ASSERT_TRUE(WriteStringToFile(testdata, tf.path));
- ASSERT_EQ(NO_ERROR, buffer.read(&tffd, READ_TIMEOUT));
+ ASSERT_EQ(NO_ERROR, buffer.read(tf.fd, READ_TIMEOUT));
int i = 0;
EncodedBuffer::iterator it = buffer.data();
@@ -128,7 +126,7 @@ TEST_F(FdBufferTest, ReadTimeout) {
} else {
c2pPipe.writeFd().reset();
- status_t status = buffer.read(&c2pPipe.readFd(), QUICK_TIMEOUT_MS);
+ status_t status = buffer.read(c2pPipe.readFd().get(), QUICK_TIMEOUT_MS);
ASSERT_EQ(NO_ERROR, status);
EXPECT_TRUE(buffer.timedOut());
@@ -148,7 +146,7 @@ TEST_F(FdBufferTest, ReadInStreamAndWrite) {
p2cPipe.writeFd().reset();
c2pPipe.readFd().reset();
ASSERT_TRUE(WriteStringToFd(HEAD, c2pPipe.writeFd()));
- ASSERT_TRUE(DoDataStream(&p2cPipe.readFd(), &c2pPipe.writeFd()));
+ ASSERT_TRUE(DoDataStream(p2cPipe.readFd(), c2pPipe.writeFd()));
p2cPipe.readFd().reset();
c2pPipe.writeFd().reset();
// Must exit here otherwise the child process will continue executing the test binary.
@@ -157,8 +155,9 @@ TEST_F(FdBufferTest, ReadInStreamAndWrite) {
p2cPipe.readFd().reset();
c2pPipe.writeFd().reset();
- ASSERT_EQ(NO_ERROR, buffer.readProcessedDataInStream(&tffd, &p2cPipe.writeFd(),
- &c2pPipe.readFd(), READ_TIMEOUT));
+ ASSERT_EQ(NO_ERROR,
+ buffer.readProcessedDataInStream(tf.fd, std::move(p2cPipe.writeFd()),
+ std::move(c2pPipe.readFd()), READ_TIMEOUT));
AssertBufferReadSuccessful(HEAD.size() + testdata.size());
AssertBufferContent(expected.c_str());
wait(&pid);
@@ -189,8 +188,9 @@ TEST_F(FdBufferTest, ReadInStreamAndWriteAllAtOnce) {
p2cPipe.readFd().reset();
c2pPipe.writeFd().reset();
- ASSERT_EQ(NO_ERROR, buffer.readProcessedDataInStream(&tffd, &p2cPipe.writeFd(),
- &c2pPipe.readFd(), READ_TIMEOUT));
+ ASSERT_EQ(NO_ERROR,
+ buffer.readProcessedDataInStream(tf.fd, std::move(p2cPipe.writeFd()),
+ std::move(c2pPipe.readFd()), READ_TIMEOUT));
AssertBufferReadSuccessful(HEAD.size() + testdata.size());
AssertBufferContent(expected.c_str());
wait(&pid);
@@ -206,7 +206,7 @@ TEST_F(FdBufferTest, ReadInStreamEmpty) {
if (pid == 0) {
p2cPipe.writeFd().reset();
c2pPipe.readFd().reset();
- ASSERT_TRUE(DoDataStream(&p2cPipe.readFd(), &c2pPipe.writeFd()));
+ ASSERT_TRUE(DoDataStream(p2cPipe.readFd(), c2pPipe.writeFd()));
p2cPipe.readFd().reset();
c2pPipe.writeFd().reset();
_exit(EXIT_SUCCESS);
@@ -214,8 +214,9 @@ TEST_F(FdBufferTest, ReadInStreamEmpty) {
p2cPipe.readFd().reset();
c2pPipe.writeFd().reset();
- ASSERT_EQ(NO_ERROR, buffer.readProcessedDataInStream(&tffd, &p2cPipe.writeFd(),
- &c2pPipe.readFd(), READ_TIMEOUT));
+ ASSERT_EQ(NO_ERROR,
+ buffer.readProcessedDataInStream(tf.fd, std::move(p2cPipe.writeFd()),
+ std::move(c2pPipe.readFd()), READ_TIMEOUT));
AssertBufferReadSuccessful(0);
AssertBufferContent("");
wait(&pid);
@@ -233,7 +234,7 @@ TEST_F(FdBufferTest, ReadInStreamMoreThan4MB) {
if (pid == 0) {
p2cPipe.writeFd().reset();
c2pPipe.readFd().reset();
- ASSERT_TRUE(DoDataStream(&p2cPipe.readFd(), &c2pPipe.writeFd()));
+ ASSERT_TRUE(DoDataStream(p2cPipe.readFd(), c2pPipe.writeFd()));
p2cPipe.readFd().reset();
c2pPipe.writeFd().reset();
_exit(EXIT_SUCCESS);
@@ -241,8 +242,9 @@ TEST_F(FdBufferTest, ReadInStreamMoreThan4MB) {
p2cPipe.readFd().reset();
c2pPipe.writeFd().reset();
- ASSERT_EQ(NO_ERROR, buffer.readProcessedDataInStream(&fd, &p2cPipe.writeFd(),
- &c2pPipe.readFd(), READ_TIMEOUT));
+ ASSERT_EQ(NO_ERROR,
+ buffer.readProcessedDataInStream(fd, std::move(p2cPipe.writeFd()),
+ std::move(c2pPipe.readFd()), READ_TIMEOUT));
EXPECT_EQ(buffer.size(), fourMB);
EXPECT_FALSE(buffer.timedOut());
EXPECT_TRUE(buffer.truncated());
@@ -278,8 +280,9 @@ TEST_F(FdBufferTest, ReadInStreamTimeOut) {
p2cPipe.readFd().reset();
c2pPipe.writeFd().reset();
- ASSERT_EQ(NO_ERROR, buffer.readProcessedDataInStream(&tffd, &p2cPipe.writeFd(),
- &c2pPipe.readFd(), QUICK_TIMEOUT_MS));
+ ASSERT_EQ(NO_ERROR,
+ buffer.readProcessedDataInStream(tf.fd, std::move(p2cPipe.writeFd()),
+ std::move(c2pPipe.readFd()), QUICK_TIMEOUT_MS));
EXPECT_TRUE(buffer.timedOut());
kill(pid, SIGKILL); // reap the child process
}
diff --git a/cmds/incidentd/tests/PrivacyBuffer_test.cpp b/cmds/incidentd/tests/PrivacyBuffer_test.cpp
index 5edc0c79785b38de0a54e426cc5cc2b94e7b1043..10c2981d6403de2625a618294db77538ea5011c1 100644
--- a/cmds/incidentd/tests/PrivacyBuffer_test.cpp
+++ b/cmds/incidentd/tests/PrivacyBuffer_test.cpp
@@ -38,7 +38,7 @@ const uint8_t STRING_TYPE = 9;
const uint8_t MESSAGE_TYPE = 11;
const string STRING_FIELD_0 = "\x02\viamtestdata";
const string VARINT_FIELD_1 = "\x08\x96\x01"; // 150
-const string STRING_FIELD_2 = "\x12\vwhatthefuck";
+const string STRING_FIELD_2 = "\x12\vandroidwins";
const string FIX64_FIELD_3 = "\x19\xff\xff\xff\xff\xff\xff\xff\xff"; // -1
const string FIX32_FIELD_4 = "\x25\xff\xff\xff\xff"; // -1
const string MESSAGE_FIELD_5 = "\x2a\x10" + VARINT_FIELD_1 + STRING_FIELD_2;
@@ -58,8 +58,7 @@ public:
void writeToFdBuffer(string str) {
ASSERT_TRUE(WriteStringToFile(str, tf.path));
- unique_fd tffd(tf.fd);
- ASSERT_EQ(NO_ERROR, buffer.read(&tffd, 10000));
+ ASSERT_EQ(NO_ERROR, buffer.read(tf.fd, 10000));
ASSERT_EQ(str.size(), buffer.size());
}
@@ -274,4 +273,4 @@ TEST_F(PrivacyBufferTest, AutoMessage) {
autoMsg->children = list;
string expected = "\x2a\xd" + STRING_FIELD_2;
assertStripByFields(DEST_AUTOMATIC, expected, 1, autoMsg);
-}
\ No newline at end of file
+}
diff --git a/cmds/incidentd/tests/Section_test.cpp b/cmds/incidentd/tests/Section_test.cpp
index f93839b62dcff415d111cd55d347adde987886fc..2f6698bc3116786b43cc284001e926d439897542 100644
--- a/cmds/incidentd/tests/Section_test.cpp
+++ b/cmds/incidentd/tests/Section_test.cpp
@@ -19,6 +19,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -31,12 +32,13 @@ const int REVERSE_PARSER = 1;
const int QUICK_TIMEOUT_MS = 100;
const string VARINT_FIELD_1 = "\x08\x96\x01"; // 150
-const string STRING_FIELD_2 = "\x12\vwhatthefuck";
+const string STRING_FIELD_2 = "\x12\vandroidwins";
const string FIX64_FIELD_3 = "\x19\xff\xff\xff\xff\xff\xff\xff\xff"; // -1
using namespace android::base;
using namespace android::binder;
using namespace android::os;
+using namespace android::util;
using namespace std;
using ::testing::StrEq;
using ::testing::Test;
@@ -154,17 +156,26 @@ TEST_F(SectionTest, GZipSection) {
requests.setMainDest(android::os::DEST_LOCAL);
ASSERT_EQ(NO_ERROR, gs.Execute(&requests));
- std::string expect, gzFile, actual;
+ std::string expected, gzFile, actual;
ASSERT_TRUE(ReadFileToString(testGzFile, &gzFile));
ASSERT_TRUE(ReadFileToString(tf.path, &actual));
- expect = "\x2\xC6\x6\n\"" + testFile + "\x12\x9F\x6" + gzFile;
- EXPECT_THAT(actual, StrEq(expect));
+ // generates the expected protobuf result.
+ size_t fileLen = testFile.size();
+ size_t totalLen = 1 + get_varint_size(fileLen) + fileLen + 3 + gzFile.size();
+ uint8_t header[20];
+ header[0] = '\x2'; // header 0 << 3 + 2
+ uint8_t* ptr = write_raw_varint(header + 1, totalLen);
+ *ptr = '\n'; // header 1 << 3 + 2
+ ptr = write_raw_varint(++ptr, fileLen);
+ expected.assign((const char*)header, ptr - header);
+ expected += testFile + "\x12\x9F\x6" + gzFile;
+ EXPECT_THAT(actual, StrEq(expected));
}
TEST_F(SectionTest, GZipSectionNoFileFound) {
GZipSection gs(NOOP_PARSER, "/tmp/nonexist1", "/tmp/nonexist2", NULL);
requests.setMainFd(STDOUT_FILENO);
- ASSERT_EQ(-1, gs.Execute(&requests));
+ ASSERT_EQ(NO_ERROR, gs.Execute(&requests));
}
TEST_F(SectionTest, CommandSectionConstructor) {
diff --git a/cmds/requestsync/src/com/android/commands/requestsync/RequestSync.java b/cmds/requestsync/src/com/android/commands/requestsync/RequestSync.java
index b76d6694ca2dbf6a3b2a69d6aea926fd81c25560..37b7acfaf5e6a8b3a98205978cbbb806bf990a0e 100644
--- a/cmds/requestsync/src/com/android/commands/requestsync/RequestSync.java
+++ b/cmds/requestsync/src/com/android/commands/requestsync/RequestSync.java
@@ -29,23 +29,21 @@ public class RequestSync {
private String[] mArgs;
private int mNextArg;
private String mCurArgData;
- private boolean mIsForegroundRequest;
+
+ private int mExemptionFlag = ContentResolver.SYNC_EXEMPTION_NONE;
enum Operation {
REQUEST_SYNC {
@Override
void invoke(RequestSync caller) {
- if (caller.mIsForegroundRequest) {
- caller.mExtras.putBoolean(
- ContentResolver.SYNC_VIRTUAL_EXTRAS_FORCE_FG_SYNC, true);
- } else {
- caller.mExtras.putBoolean(
- ContentResolver.SYNC_VIRTUAL_EXTRAS_FORCE_BG_SYNC, true);
+ final int flag = caller.mExemptionFlag;
+ caller.mExtras.putInt(ContentResolver.SYNC_VIRTUAL_EXTRAS_EXEMPTION_FLAG, flag);
+ if (flag == ContentResolver.SYNC_EXEMPTION_NONE) {
System.out.println(
"Making a sync request as a background app.\n"
+ "Note: request may be throttled by App Standby.\n"
+ "To override this behavior and run a sync immediately,"
- + " pass a -f option.\n");
+ + " pass a -f or -F option (use -h for help).\n");
}
final SyncRequest request =
new SyncRequest.Builder()
@@ -213,7 +211,10 @@ public class RequestSync {
mExtras.putBoolean(key, Boolean.valueOf(value));
} else if (opt.equals("-f") || opt.equals("--foreground")) {
- mIsForegroundRequest = true;
+ mExemptionFlag = ContentResolver.SYNC_EXEMPTION_ACTIVE;
+
+ } else if (opt.equals("-F") || opt.equals("--top")) {
+ mExemptionFlag = ContentResolver.SYNC_EXEMPTION_ACTIVE_WITH_TEMP;
} else {
System.err.println("Error: Unknown option: " + opt);
@@ -293,7 +294,9 @@ public class RequestSync {
" -a|--authority \n" +
" App-standby related options\n" +
"\n" +
- " -f|--foreground (Exempt a sync from app standby)\n" +
+ " -f|--foreground (cause WORKING_SET, FREQUENT sync adapters" +
+ " to run immediately)\n" +
+ " -F|--top (cause even RARE sync adapters to run immediately)\n" +
" ContentResolver extra options:\n" +
" --is|--ignore-settings: Add SYNC_EXTRAS_IGNORE_SETTINGS\n" +
" --ib|--ignore-backoff: Add SYNC_EXTRAS_IGNORE_BACKOFF\n" +
diff --git a/cmds/statsd/Android.mk b/cmds/statsd/Android.mk
index 1aef0c4c43c51057be8cc1f361db79cde92e2594..7723615245b7928704da3dc5d9b25bb16be3ac40 100644
--- a/cmds/statsd/Android.mk
+++ b/cmds/statsd/Android.mk
@@ -202,6 +202,7 @@ LOCAL_SRC_FILES := \
tests/statsd_test_util.cpp \
tests/e2e/WakelockDuration_e2e_test.cpp \
tests/e2e/MetricConditionLink_e2e_test.cpp \
+ tests/e2e/Alarm_e2e_test.cpp \
tests/e2e/Attribution_e2e_test.cpp \
tests/e2e/GaugeMetric_e2e_push_test.cpp \
tests/e2e/DimensionInCondition_e2e_combination_AND_cond_test.cpp \
diff --git a/cmds/statsd/benchmark/metric_util.cpp b/cmds/statsd/benchmark/metric_util.cpp
index b67764bd5130aa8c0408be8e84ebd60bc75a1752..50b05cd5b1d869931a6dc42c4b7b062a6fce4d11 100644
--- a/cmds/statsd/benchmark/metric_util.cpp
+++ b/cmds/statsd/benchmark/metric_util.cpp
@@ -127,25 +127,25 @@ AtomMatcher CreateSyncEndAtomMatcher() {
}
AtomMatcher CreateActivityForegroundStateChangedAtomMatcher(
- const string& name, ActivityForegroundStateChanged::Activity activity) {
+ const string& name, ActivityForegroundStateChanged::State state) {
AtomMatcher atom_matcher;
atom_matcher.set_id(StringToId(name));
auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
simple_atom_matcher->set_atom_id(android::util::ACTIVITY_FOREGROUND_STATE_CHANGED);
auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
field_value_matcher->set_field(4); // Activity field.
- field_value_matcher->set_eq_int(activity);
+ field_value_matcher->set_eq_int(state);
return atom_matcher;
}
AtomMatcher CreateMoveToBackgroundAtomMatcher() {
return CreateActivityForegroundStateChangedAtomMatcher(
- "MoveToBackground", ActivityForegroundStateChanged::MOVE_TO_BACKGROUND);
+ "MoveToBackground", ActivityForegroundStateChanged::BACKGROUND);
}
AtomMatcher CreateMoveToForegroundAtomMatcher() {
return CreateActivityForegroundStateChangedAtomMatcher(
- "MoveToForeground", ActivityForegroundStateChanged::MOVE_TO_FOREGROUND);
+ "MoveToForeground", ActivityForegroundStateChanged::FOREGROUND);
}
Predicate CreateScheduledJobPredicate() {
@@ -315,25 +315,25 @@ std::unique_ptr CreateReleaseWakelockEvent(
}
std::unique_ptr CreateActivityForegroundStateChangedEvent(
- const int uid, const ActivityForegroundStateChanged::Activity activity, uint64_t timestampNs) {
+ const int uid, const ActivityForegroundStateChanged::State state, uint64_t timestampNs) {
auto event = std::make_unique(
android::util::ACTIVITY_FOREGROUND_STATE_CHANGED, timestampNs);
event->write(uid);
event->write("pkg_name");
event->write("class_name");
- event->write(activity);
+ event->write(state);
event->init();
return event;
}
std::unique_ptr CreateMoveToBackgroundEvent(const int uid, uint64_t timestampNs) {
return CreateActivityForegroundStateChangedEvent(
- uid, ActivityForegroundStateChanged::MOVE_TO_BACKGROUND, timestampNs);
+ uid, ActivityForegroundStateChanged::BACKGROUND, timestampNs);
}
std::unique_ptr CreateMoveToForegroundEvent(const int uid, uint64_t timestampNs) {
return CreateActivityForegroundStateChangedEvent(
- uid, ActivityForegroundStateChanged::MOVE_TO_FOREGROUND, timestampNs);
+ uid, ActivityForegroundStateChanged::FOREGROUND, timestampNs);
}
std::unique_ptr CreateSyncStateChangedEvent(
diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp
index a458c07394a7d904f33a645d4c6807a22b2d2a30..13f2679e9b0e3a9469eef43740783ec22cc5b58c 100644
--- a/cmds/statsd/src/StatsLogProcessor.cpp
+++ b/cmds/statsd/src/StatsLogProcessor.cpp
@@ -79,15 +79,13 @@ StatsLogProcessor::StatsLogProcessor(const sp& uidMap,
mSendBroadcast(sendBroadcast),
mTimeBaseSec(timeBaseSec),
mLastLogTimestamp(0) {
- StatsPullerManager statsPullerManager;
- statsPullerManager.SetTimeBaseSec(mTimeBaseSec);
}
StatsLogProcessor::~StatsLogProcessor() {
}
void StatsLogProcessor::onAnomalyAlarmFired(
- const uint64_t timestampNs,
+ const uint64_t& timestampNs,
unordered_set, SpHash> alarmSet) {
std::lock_guard lock(mMetricsMutex);
for (const auto& itr : mMetricsManagers) {
@@ -95,7 +93,7 @@ void StatsLogProcessor::onAnomalyAlarmFired(
}
}
void StatsLogProcessor::onPeriodicAlarmFired(
- const uint64_t timestampNs,
+ const uint64_t& timestampNs,
unordered_set, SpHash> alarmSet) {
std::lock_guard lock(mMetricsMutex);
@@ -177,7 +175,7 @@ void StatsLogProcessor::OnLogEvent(LogEvent* event) {
uint64_t curTimeSec = getElapsedRealtimeSec();
if (curTimeSec - mLastPullerCacheClearTimeSec > StatsdStats::kPullerCacheClearIntervalSec) {
- mStatsPullerManager.ClearPullerCacheIfNecessary(curTimeSec);
+ mStatsPullerManager.ClearPullerCacheIfNecessary(curTimeSec * NS_PER_SEC);
mLastPullerCacheClearTimeSec = curTimeSec;
}
diff --git a/cmds/statsd/src/StatsLogProcessor.h b/cmds/statsd/src/StatsLogProcessor.h
index a07a35587b11fc267c5ecd9e5d647dd025f0bb5a..387a9295055f223147fde3f9024e8c57adc902b3 100644
--- a/cmds/statsd/src/StatsLogProcessor.h
+++ b/cmds/statsd/src/StatsLogProcessor.h
@@ -51,12 +51,12 @@ public:
/* Tells MetricsManager that the alarms in alarmSet have fired. Modifies anomaly alarmSet. */
void onAnomalyAlarmFired(
- const uint64_t timestampNs,
+ const uint64_t& timestampNs,
unordered_set, SpHash> alarmSet);
/* Tells MetricsManager that the alarms in alarmSet have fired. Modifies periodic alarmSet. */
void onPeriodicAlarmFired(
- const uint64_t timestampNs,
+ const uint64_t& timestampNs,
unordered_set, SpHash> alarmSet);
/* Flushes data to disk. Data on memory will be gone after written to disk. */
@@ -74,6 +74,10 @@ private:
return mAnomalyAlarmMonitor;
}
+ inline sp getPeriodicAlarmMonitor() const {
+ return mPeriodicAlarmMonitor;
+ }
+
mutable mutex mMetricsMutex;
std::unordered_map> mMetricsManagers;
@@ -147,6 +151,7 @@ private:
FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_single_bucket);
FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_multiple_buckets);
FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_long_refractory_period);
+ FRIEND_TEST(AlarmE2eTest, TestMultipleAlarms);
};
} // namespace statsd
diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp
index b03b4b4a942c59c5b40eabed4ae8a342144879d0..7b0d5d9ca8849bbb508115391cceda1192fd829b 100644
--- a/cmds/statsd/src/StatsService.cpp
+++ b/cmds/statsd/src/StatsService.cpp
@@ -595,7 +595,7 @@ status_t StatsService::cmd_log_app_breadcrumb(FILE* out, const Vector&
status_t StatsService::cmd_print_pulled_metrics(FILE* out, const Vector& args) {
int s = atoi(args[1].c_str());
vector > stats;
- if (mStatsPullerManager.Pull(s, &stats)) {
+ if (mStatsPullerManager.Pull(s, getElapsedRealtimeNs(), &stats)) {
for (const auto& it : stats) {
fprintf(out, "Pull from %d: %s\n", s, it->ToString().c_str());
}
@@ -698,7 +698,7 @@ Status StatsService::informAlarmForSubscriberTriggeringFired() {
"Only system uid can call informAlarmForSubscriberTriggeringFired");
}
- uint64_t currentTimeSec = time(nullptr);
+ uint64_t currentTimeSec = getElapsedRealtimeSec();
std::unordered_set, SpHash> alarmSet =
mPeriodicAlarmMonitor->popSoonerThan(static_cast(currentTimeSec));
if (alarmSet.size() > 0) {
diff --git a/cmds/statsd/src/anomaly/AlarmTracker.cpp b/cmds/statsd/src/anomaly/AlarmTracker.cpp
index eb283838afd76172b46a2a65bc572ee8718e3891..249cb596d3c6c8612c2605320ed457eff7a572df 100644
--- a/cmds/statsd/src/anomaly/AlarmTracker.cpp
+++ b/cmds/statsd/src/anomaly/AlarmTracker.cpp
@@ -39,12 +39,14 @@ AlarmTracker::AlarmTracker(uint64_t startMillis,
VLOG("AlarmTracker() called");
mAlarmSec = (startMillis + mAlarmConfig.offset_millis()) / MS_PER_SEC;
mInternalAlarm = new InternalAlarm{static_cast(mAlarmSec)};
- mAlarmMonitor->add(mInternalAlarm);
+ if (mAlarmMonitor != nullptr) {
+ mAlarmMonitor->add(mInternalAlarm);
+ }
}
AlarmTracker::~AlarmTracker() {
VLOG("~AlarmTracker() called");
- if (mInternalAlarm != nullptr) {
+ if (mInternalAlarm != nullptr && mAlarmMonitor != nullptr) {
mAlarmMonitor->remove(mInternalAlarm);
}
}
@@ -61,7 +63,8 @@ uint64_t AlarmTracker::findNextAlarmSec(uint64_t currentTimeSec) {
void AlarmTracker::informAlarmsFired(
const uint64_t& timestampNs,
unordered_set, SpHash>& firedAlarms) {
- if (firedAlarms.empty() || firedAlarms.find(mInternalAlarm) == firedAlarms.end()) {
+ if (firedAlarms.empty() || mInternalAlarm == nullptr ||
+ firedAlarms.find(mInternalAlarm) == firedAlarms.end()) {
return;
}
if (!mSubscriptions.empty()) {
@@ -69,9 +72,11 @@ void AlarmTracker::informAlarmsFired(
mSubscriptions);
}
firedAlarms.erase(mInternalAlarm);
- mAlarmSec = findNextAlarmSec(timestampNs / NS_PER_SEC);
+ mAlarmSec = findNextAlarmSec((timestampNs-1) / NS_PER_SEC + 1); // round up
mInternalAlarm = new InternalAlarm{static_cast(mAlarmSec)};
- mAlarmMonitor->add(mInternalAlarm);
+ if (mAlarmMonitor != nullptr) {
+ mAlarmMonitor->add(mInternalAlarm);
+ }
}
} // namespace statsd
diff --git a/cmds/statsd/src/anomaly/AlarmTracker.h b/cmds/statsd/src/anomaly/AlarmTracker.h
index d59dacaa1b6983b0fe9dc74483316d1d9e469294..13180a53ccbf1e22b57050bccceb12d76daafd06 100644
--- a/cmds/statsd/src/anomaly/AlarmTracker.h
+++ b/cmds/statsd/src/anomaly/AlarmTracker.h
@@ -48,6 +48,11 @@ public:
unordered_set, SpHash>& firedAlarms);
protected:
+ // For test only. Returns the alarm timestamp in seconds. Otherwise returns 0.
+ inline uint32_t getAlarmTimestampSec() const {
+ return mInternalAlarm == nullptr ? 0 : mInternalAlarm->timestampSec;
+ }
+
uint64_t findNextAlarmSec(uint64_t currentTimeMillis);
// statsd_config.proto Alarm message that defines this tracker.
@@ -69,6 +74,7 @@ protected:
sp mInternalAlarm;
FRIEND_TEST(AlarmTrackerTest, TestTriggerTimestamp);
+ FRIEND_TEST(AlarmE2eTest, TestMultipleAlarms);
};
} // namespace statsd
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 5e75359f111e17618b113de271261ce8148ef10b..7fe8e6208e1e80079b28589d1be4309e3444cf63 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -16,7 +16,6 @@
syntax = "proto2";
-// TODO: Not the right package and class name
package android.os.statsd;
option java_package = "com.android.os";
option java_outer_classname = "AtomsProto";
@@ -49,7 +48,7 @@ message Atom {
oneof pushed {
// For StatsLog reasons, 1 is illegal and will not work. Must start at 2.
BleScanStateChanged ble_scan_state_changed = 2;
- // TODO: 3 is blank, but need not be
+ // 3 is available for use
BleScanResultReceived ble_scan_result_received = 4;
SensorStateChanged sensor_state_changed = 5;
GpsScanStateChanged gps_scan_state_changed = 6;
@@ -60,12 +59,12 @@ message Atom {
LongPartialWakelockStateChanged long_partial_wakelock_state_changed = 11;
MobileRadioPowerStateChanged mobile_radio_power_state_changed = 12;
WifiRadioPowerStateChanged wifi_radio_power_state_changed = 13;
- // TODO: 14-19 are blank, but need not be
+ // 14 - 19 are available
BatterySaverModeStateChanged battery_saver_mode_state_changed = 20;
DeviceIdleModeStateChanged device_idle_mode_state_changed = 21;
DeviceIdlingModeStateChanged device_idling_mode_state_changed = 22;
AudioStateChanged audio_state_changed = 23;
- MediaCodecActivityChanged media_codec_activity_changed = 24;
+ MediaCodecStateChanged media_codec_state_changed = 24;
CameraStateChanged camera_state_changed = 25;
FlashlightStateChanged flashlight_state_changed = 26;
UidProcessStateChanged uid_process_state_changed = 27;
@@ -74,8 +73,7 @@ message Atom {
BatteryLevelChanged battery_level_changed = 30;
ChargingStateChanged charging_state_changed = 31;
PluggedStateChanged plugged_state_changed = 32;
- // TODO: 33 is blank, but is available for use.
- DeviceOnStatusChanged device_on_status_changed = 34;
+ // 33 - 34 are available
WakeupAlarmOccurred wakeup_alarm_occurred = 35;
KernelWakeupReported kernel_wakeup_reported = 36;
WifiLockStateChanged wifi_lock_state_changed = 37;
@@ -86,12 +84,12 @@ message Atom {
ActivityForegroundStateChanged activity_foreground_state_changed = 42;
IsolatedUidChanged isolated_uid_changed = 43;
PacketWakeupOccurred packet_wakeup_occurred = 44;
- DropboxErrorChanged dropbox_error_changed = 45;
+ // 45 is available
AnomalyDetected anomaly_detected = 46;
AppBreadcrumbReported app_breadcrumb_reported = 47;
- AppStartChanged app_start_changed = 48;
- AppStartCancelChanged app_start_cancel_changed = 49;
- AppStartFullyDrawnChanged app_start_fully_drawn_changed = 50;
+ AppStartOccurred app_start_occurred = 48;
+ AppStartCanceled app_start_canceled = 49;
+ AppStartFullyDrawn app_start_fully_drawn = 50;
LmkKillOccurred lmk_kill_occurred = 51;
PictureInPictureStateChanged picture_in_picture_state_changed = 52;
WifiMulticastLockStateChanged wifi_multicast_lock_state_changed = 53;
@@ -106,7 +104,7 @@ message Atom {
KeyguardStateChanged keyguard_state_changed = 62;
KeyguardBouncerStateChanged keyguard_bouncer_state_changed = 63;
KeyguardBouncerPasswordEntered keyguard_bouncer_password_entered = 64;
- AppDied app_died=65;
+ AppDied app_died = 65;
ResourceConfigurationChanged resource_configuration_changed = 66;
BluetoothEnabledStateChanged bluetooth_enabled_state_changed = 67;
BluetoothConnectionStateChanged bluetooth_connection_state_changed = 68;
@@ -119,6 +117,12 @@ message Atom {
MobileConnectionStateChanged mobile_connection_state_changed = 75;
MobileRadioTechnologyChanged mobile_radio_technology_changed = 76;
UsbDeviceAttached usb_device_attached = 77;
+ AppCrashOccurred app_crash_occurred = 78;
+ ANROccurred anr_occurred = 79;
+ WTFOccurred wtf_occurred = 80;
+ LowMemReported low_mem_reported = 81;
+
+
}
// Pulled events will start at field 10000.
@@ -134,7 +138,7 @@ message Atom {
CpuTimePerFreq cpu_time_per_freq = 10008;
CpuTimePerUid cpu_time_per_uid = 10009;
CpuTimePerUidFreq cpu_time_per_uid_freq = 10010;
- WifiActivityEnergyInfo wifi_activity_energy_info = 10011;
+ WifiActivityInfo wifi_activity_info = 10011;
ModemActivityInfo modem_activity_info = 10012;
BluetoothActivityInfo bluetooth_activity_info = 10007;
ProcessMemoryState process_memory_state = 10013;
@@ -224,30 +228,27 @@ message UidProcessStateChanged {
* frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java
*/
message ProcessLifeCycleStateChanged {
- // TODO: should be a string tagged w/ uid annotation
optional int32 uid = 1 [(is_uid) = true];
// The process name (usually same as the app name).
- optional string name = 2;
+ optional string process_name = 2;
// What lifecycle state the process changed to.
// This enum is specific to atoms.proto.
- enum Event {
- PROCESS_FINISHED = 0;
- PROCESS_STARTED = 1;
- PROCESS_CRASHED = 2;
- PROCESS_ANRED = 3;
+ enum State {
+ FINISHED = 0;
+ STARTED = 1;
+ CRASHED = 2;
}
- optional Event event = 3;
+ optional State state = 3;
}
/**
* Logs when the ble scan state changes.
*
* Logged from:
- * frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
+ * packages/apps/Bluetooth/src/com/android/bluetooth/gatt/AppScanStats.java
*/
-// TODO: Consider changing to tracking per-scanner-id (log from AppScanStats).
message BleScanStateChanged {
repeated AttributionNode attribution_node = 1;
@@ -278,7 +279,7 @@ message BleScanResultReceived {
repeated AttributionNode attribution_node = 1;
// Number of ble scan results returned.
- optional int32 num_of_results = 2;
+ optional int32 num_results = 2;
}
/**
@@ -290,7 +291,6 @@ message BleScanResultReceived {
message SensorStateChanged {
repeated AttributionNode attribution_node = 1;
- // TODO: Is there a way to get the actual name of the sensor?
// The id (int) of the sensor.
optional int32 sensor_id = 2;
@@ -329,7 +329,7 @@ message SyncStateChanged {
repeated AttributionNode attribution_node = 1;
// Name of the sync (as named in the app). Can be chosen at run-time.
- optional string name = 2;
+ optional string sync_name = 2;
enum State {
OFF = 0;
@@ -348,7 +348,7 @@ message ScheduledJobStateChanged {
repeated AttributionNode attribution_node = 1;
// Name of the job (as named in the app)
- optional string name = 2;
+ optional string job_name = 2;
enum State {
FINISHED = 0;
@@ -387,7 +387,7 @@ message AudioStateChanged {
* Logged from:
* frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java
*/
-message MediaCodecActivityChanged {
+message MediaCodecStateChanged {
repeated AttributionNode attribution_node = 1;
enum State {
@@ -561,22 +561,6 @@ message PluggedStateChanged {
optional android.os.BatteryPluggedStateEnum state = 1;
}
-// TODO: Define this more precisely.
-// TODO: Log the ON state somewhere. It isn't currently logged anywhere.
-/**
- * Logs when the device turns off or on.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
- */
-message DeviceOnStatusChanged {
- enum State {
- OFF = 0;
- ON = 1;
- }
- optional State state = 1;
-}
-
/**
* Logs when an app's wakeup alarm fires.
*
@@ -598,8 +582,7 @@ message WakeupAlarmOccurred {
* frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
*/
message MobileRadioPowerStateChanged {
- // TODO: Add attribution instead of uid?
- optional int32 uid = 1 [(is_uid) = true];
+ repeated AttributionNode attribution_node = 1;
// Power state, from frameworks/base/core/proto/android/telephony/enums.proto.
optional android.telephony.DataConnectionPowerStateEnum state = 2;
@@ -613,8 +596,7 @@ message MobileRadioPowerStateChanged {
* frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
*/
message WifiRadioPowerStateChanged {
- // TODO: Add attribution instead of uid?
- optional int32 uid = 1 [(is_uid) = true];
+ repeated AttributionNode attribution_node = 1;
// Power state, from frameworks/base/core/proto/android/telephony/enums.proto.
optional android.telephony.DataConnectionPowerStateEnum state = 2;
@@ -1154,7 +1136,6 @@ message ChargeCyclesReported {
message DaveyOccurred {
// The UID that logged this atom.
optional int32 uid = 1 [(is_uid) = true];
- ;
// Amount of time it took to render the frame. Should be >=700ms.
optional int64 jank_duration_millis = 2;
@@ -1221,42 +1202,70 @@ message ActivityForegroundStateChanged {
optional string pkg_name = 2;
optional string class_name = 3;
- enum Activity {
- MOVE_TO_BACKGROUND = 0;
- MOVE_TO_FOREGROUND = 1;
+ enum State {
+ BACKGROUND = 0;
+ FOREGROUND = 1;
}
- optional Activity activity = 4;
+ optional State state = 4;
}
/**
- * Logs when an error is written to dropbox.
+ * Logs when an app crashes.
* Logged from:
* frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
*/
-message DropboxErrorChanged {
- // The uid if available. -1 means not available.
+message AppCrashOccurred {
+ optional int32 uid = 1 [(is_uid) = true];
+
+ optional string event_type = 2;
+
+ // The name of the process.
+ // system_server if it is not by an app
+ optional string process_name = 3;
+
+ // The pid if available. -1 means not available.
+ optional sint32 pid = 4;
+}
+
+/**
+ * Logs when a WTF (What a Terrible Failure) happened.
+ * Logged from:
+ * frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
+ */
+message WTFOccurred {
optional int32 uid = 1 [(is_uid) = true];
- // Tag used when recording this error to dropbox. Contains data_ or system_ prefix.
optional string tag = 2;
// The name of the process.
+ // system_server if it is not by an app
optional string process_name = 3;
// The pid if available. -1 means not available.
optional sint32 pid = 4;
+}
- // 1 indicates is instant app. -1 indicates Not applicable.
- optional sint32 is_instant_app = 5;
+/**
+ * Logs when system server reports low memory.
+ * Logged from:
+ * frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
+ */
+message LowMemReported {
+}
+
+/**
+ * Logs when an app ANR (App Not Responding) occurs.
+ * Logged from:
+ * frameworks/base/services/core/java/com/android/server/am/AppErrors.java
+ */
+message ANROccurred {
+ optional int32 uid = 1 [(is_uid) = true];
- // The activity name if available.
- optional string activity_name = 6;
+ optional string process_name = 2;
- // The package name if available.
- optional string package_name = 7;
+ optional string short_component_name = 3;
- // 1 indicates in foreground. -1 indicates not available.
- optional sint32 is_foreground = 8;
+ optional string reason = 4;
}
/*
@@ -1299,7 +1308,7 @@ message AnomalyDetected {
optional int64 alert_id = 3;
}
-message AppStartChanged {
+message AppStartOccurred {
// The uid if available. -1 means not available.
optional int32 uid = 1 [(is_uid) = true];
@@ -1307,7 +1316,7 @@ message AppStartChanged {
optional string pkg_name = 2;
enum TransitionType {
- APP_START_TRANSITION_TYPE_UNKNOWN = 0;
+ UNKNOWN = 0;
WARM = 1;
HOT = 2;
COLD = 3;
@@ -1346,7 +1355,7 @@ message AppStartChanged {
optional int32 package_optimization_compilation_reason = 15;
}
-message AppStartCancelChanged {
+message AppStartCanceled {
// The uid if available. -1 means not available.
optional int32 uid = 1 [(is_uid) = true];
@@ -1354,7 +1363,7 @@ message AppStartCancelChanged {
optional string pkg_name = 2;
enum TransitionType {
- APP_START_TRANSITION_TYPE_UNKNOWN = 0;
+ UNKNOWN = 0;
WARM = 1;
HOT = 2;
COLD = 3;
@@ -1366,7 +1375,7 @@ message AppStartCancelChanged {
optional string activity_name = 4;
}
-message AppStartFullyDrawnChanged {
+message AppStartFullyDrawn {
// The uid if available. -1 means not available.
optional int32 uid = 1 [(is_uid) = true];
@@ -1374,7 +1383,7 @@ message AppStartFullyDrawnChanged {
optional string pkg_name = 2;
enum TransitionType {
- APP_START_TRANSITION_TYPE_UNKNOWN = 0;
+ UNKNOWN = 0;
WITH_BUNDLE = 1;
WITHOUT_BUNDLE = 2;
}
@@ -1459,8 +1468,8 @@ message ForegroundServiceStateChanged {
* frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
*/
message IsolatedUidChanged {
- // NOTE: DO NOT annotate uid field in this atom. This atom is specially handled in statsd.
// The host UID. Generally, we should attribute metrics from the isolated uid to the host uid.
+ // NOTE: DO NOT annotate uid field in this atom. This atom is specially handled in statsd.
optional int32 parent_uid = 1;
optional int32 isolated_uid = 2;
@@ -1621,9 +1630,8 @@ message WifiBytesTransfer {
message WifiBytesTransferByFgBg {
optional int32 uid = 1 [(is_uid) = true];
- // 1 denotes foreground and 0 denotes background. This is called Set in
- // NetworkStats.
- optional int32 is_foreground = 2;
+ // 1 denotes foreground and 0 denotes background. This is called Set in NetworkStats.
+ optional bool is_foreground = 2;
optional int64 rx_bytes = 3;
@@ -1663,7 +1671,7 @@ message MobileBytesTransferByFgBg {
// 1 denotes foreground and 0 denotes background. This is called Set in
// NetworkStats.
- optional int32 is_foreground = 2;
+ optional bool is_foreground = 2;
optional int64 rx_bytes = 3;
@@ -1760,7 +1768,7 @@ message CpuTimePerUidFreq {
/**
* Pulls Wifi Controller Activity Energy Info
*/
-message WifiActivityEnergyInfo {
+message WifiActivityInfo {
// timestamp(wall clock) of record creation
optional uint64 timestamp_millis = 1;
// stack reported state
diff --git a/cmds/statsd/src/external/StatsPuller.cpp b/cmds/statsd/src/external/StatsPuller.cpp
index 3b0cd349168dc6e14bb29a6972707c51e1e99102..b29e979b5236682e47b8e16c99d9944c84261031 100644
--- a/cmds/statsd/src/external/StatsPuller.cpp
+++ b/cmds/statsd/src/external/StatsPuller.cpp
@@ -35,27 +35,32 @@ void StatsPuller::SetUidMap(const sp& uidMap) { mUidMap = uidMap; }
// ValueMetric has a minimum bucket size of 10min so that we don't pull too frequently
StatsPuller::StatsPuller(const int tagId)
: mTagId(tagId) {
- mCoolDownSec = StatsPullerManagerImpl::kAllPullAtomInfo.find(tagId)->second.coolDownSec;
- VLOG("Puller for tag %d created. Cooldown set to %ld", mTagId, mCoolDownSec);
+ mCoolDownNs = StatsPullerManagerImpl::kAllPullAtomInfo.find(tagId)->second.coolDownNs;
+ VLOG("Puller for tag %d created. Cooldown set to %lld", mTagId, (long long)mCoolDownNs);
}
-bool StatsPuller::Pull(std::vector>* data) {
+bool StatsPuller::Pull(const int64_t elapsedTimeNs, std::vector>* data) {
lock_guard lock(mLock);
+ int64_t wallClockTimeNs = getWallClockNs();
StatsdStats::getInstance().notePull(mTagId);
- long curTime = getElapsedRealtimeSec();
- if (curTime - mLastPullTimeSec < mCoolDownSec) {
+ if (elapsedTimeNs - mLastPullTimeNs < mCoolDownNs) {
(*data) = mCachedData;
StatsdStats::getInstance().notePullFromCache(mTagId);
return true;
}
- if (mMinPullIntervalSec > curTime - mLastPullTimeSec) {
- mMinPullIntervalSec = curTime - mLastPullTimeSec;
- StatsdStats::getInstance().updateMinPullIntervalSec(mTagId, mMinPullIntervalSec);
+ if (mMinPullIntervalNs > elapsedTimeNs - mLastPullTimeNs) {
+ mMinPullIntervalNs = elapsedTimeNs - mLastPullTimeNs;
+ StatsdStats::getInstance().updateMinPullIntervalSec(mTagId,
+ mMinPullIntervalNs / NS_PER_SEC);
}
mCachedData.clear();
- mLastPullTimeSec = curTime;
+ mLastPullTimeNs = elapsedTimeNs;
bool ret = PullInternal(&mCachedData);
- if (ret) {
+ for (const shared_ptr& data : mCachedData) {
+ data->setElapsedTimestampNs(elapsedTimeNs);
+ data->setLogdWallClockTimestampNs(wallClockTimeNs);
+ }
+ if (ret && mCachedData.size() > 0) {
mergeIsolatedUidsToHostUid(mCachedData, mUidMap, mTagId);
(*data) = mCachedData;
}
@@ -70,12 +75,12 @@ int StatsPuller::clearCache() {
lock_guard lock(mLock);
int ret = mCachedData.size();
mCachedData.clear();
- mLastPullTimeSec = 0;
+ mLastPullTimeNs = 0;
return ret;
}
-int StatsPuller::ClearCacheIfNecessary(long timestampSec) {
- if (timestampSec - mLastPullTimeSec > mCoolDownSec) {
+int StatsPuller::ClearCacheIfNecessary(int64_t timestampNs) {
+ if (timestampNs - mLastPullTimeNs > mCoolDownNs) {
return clearCache();
} else {
return 0;
diff --git a/cmds/statsd/src/external/StatsPuller.h b/cmds/statsd/src/external/StatsPuller.h
index 936c47e92f2ca08636ade12d664274d1d9ca85a0..caac677ee215c4f26fa9cdf95c3ea6e5228ab334 100644
--- a/cmds/statsd/src/external/StatsPuller.h
+++ b/cmds/statsd/src/external/StatsPuller.h
@@ -37,13 +37,13 @@ public:
virtual ~StatsPuller() {}
- bool Pull(std::vector>* data);
+ bool Pull(const int64_t timeNs, std::vector>* data);
// Clear cache immediately
int ForceClearCache();
// Clear cache if elapsed time is more than cooldown time
- int ClearCacheIfNecessary(long timestampSec);
+ int ClearCacheIfNecessary(int64_t timestampNs);
static void SetUidMap(const sp& uidMap);
@@ -59,9 +59,9 @@ private:
// If a pull request comes before cooldown, a cached version from purevious pull
// will be returned.
// The actual value should be determined by individual pullers.
- long mCoolDownSec;
+ int64_t mCoolDownNs;
// For puller stats
- long mMinPullIntervalSec = LONG_MAX;
+ int64_t mMinPullIntervalNs = LONG_MAX;
virtual bool PullInternal(std::vector>* data) = 0;
@@ -69,7 +69,7 @@ private:
// cached data will be returned.
std::vector> mCachedData;
- long mLastPullTimeSec;
+ int64_t mLastPullTimeNs;
int clearCache();
diff --git a/cmds/statsd/src/external/StatsPullerManager.h b/cmds/statsd/src/external/StatsPullerManager.h
index 2717d5c2de9c16ddcf152af6cf5a2b779629346f..83d59c0a5830c9e9de16f301cecda5df9b2f74cd 100644
--- a/cmds/statsd/src/external/StatsPullerManager.h
+++ b/cmds/statsd/src/external/StatsPullerManager.h
@@ -26,10 +26,9 @@ class StatsPullerManager {
public:
virtual ~StatsPullerManager() {}
- virtual void RegisterReceiver(int tagId,
- wp receiver,
- long intervalMs) {
- mPullerManager.RegisterReceiver(tagId, receiver, intervalMs);
+ virtual void RegisterReceiver(int tagId, wp receiver, int64_t nextPullTimeNs,
+ int64_t intervalNs) {
+ mPullerManager.RegisterReceiver(tagId, receiver, nextPullTimeNs, intervalNs);
};
virtual void UnRegisterReceiver(int tagId, wp receiver) {
@@ -45,13 +44,9 @@ class StatsPullerManager {
mPullerManager.OnAlarmFired();
}
- virtual bool
- Pull(const int tagId, vector>* data) {
- return mPullerManager.Pull(tagId, data);
- }
-
- void SetTimeBaseSec(const long timeBaseSec) {
- mPullerManager.SetTimeBaseSec(timeBaseSec);
+ virtual bool Pull(const int tagId, const int64_t timesNs,
+ vector>* data) {
+ return mPullerManager.Pull(tagId, timesNs, data);
}
int ForceClearPullerCache() {
@@ -62,8 +57,8 @@ class StatsPullerManager {
mPullerManager.SetStatsCompanionService(statsCompanionService);
}
- int ClearPullerCacheIfNecessary(long timestampSec) {
- return mPullerManager.ClearPullerCacheIfNecessary(timestampSec);
+ int ClearPullerCacheIfNecessary(int64_t timestampNs) {
+ return mPullerManager.ClearPullerCacheIfNecessary(timestampNs);
}
private:
diff --git a/cmds/statsd/src/external/StatsPullerManagerImpl.cpp b/cmds/statsd/src/external/StatsPullerManagerImpl.cpp
index dd6406bb90ca103192437340dd217c50cade7402..2f0e88595d45efe6350d00fa199de4f1ce6c3b31 100644
--- a/cmds/statsd/src/external/StatsPullerManagerImpl.cpp
+++ b/cmds/statsd/src/external/StatsPullerManagerImpl.cpp
@@ -19,15 +19,17 @@
#include
#include
+#include
#include
#include
+#include "../StatsService.h"
#include "../logd/LogEvent.h"
#include "../stats_log_util.h"
#include "../statscompanion_util.h"
#include "ResourceHealthManagerPuller.h"
#include "ResourceThermalManagerPuller.h"
#include "StatsCompanionServicePuller.h"
-#include "StatsService.h"
+#include "StatsPullerManagerImpl.h"
#include "SubsystemSleepStatePuller.h"
#include "statslog.h"
@@ -47,89 +49,136 @@ namespace statsd {
const std::map StatsPullerManagerImpl::kAllPullAtomInfo = {
// wifi_bytes_transfer
{android::util::WIFI_BYTES_TRANSFER,
- {{2, 3, 4, 5}, {}, 1,
+ {{2, 3, 4, 5},
+ {},
+ 1 * NS_PER_SEC,
new StatsCompanionServicePuller(android::util::WIFI_BYTES_TRANSFER)}},
// wifi_bytes_transfer_by_fg_bg
{android::util::WIFI_BYTES_TRANSFER_BY_FG_BG,
- {{3, 4, 5, 6}, {2}, 1,
+ {{3, 4, 5, 6},
+ {2},
+ 1 * NS_PER_SEC,
new StatsCompanionServicePuller(android::util::WIFI_BYTES_TRANSFER_BY_FG_BG)}},
// mobile_bytes_transfer
{android::util::MOBILE_BYTES_TRANSFER,
- {{2, 3, 4, 5}, {}, 1,
+ {{2, 3, 4, 5},
+ {},
+ 1 * NS_PER_SEC,
new StatsCompanionServicePuller(android::util::MOBILE_BYTES_TRANSFER)}},
// mobile_bytes_transfer_by_fg_bg
{android::util::MOBILE_BYTES_TRANSFER_BY_FG_BG,
- {{3, 4, 5, 6}, {2}, 1,
+ {{3, 4, 5, 6},
+ {2},
+ 1 * NS_PER_SEC,
new StatsCompanionServicePuller(android::util::MOBILE_BYTES_TRANSFER_BY_FG_BG)}},
// bluetooth_bytes_transfer
{android::util::BLUETOOTH_BYTES_TRANSFER,
- {{2, 3}, {}, 1, new StatsCompanionServicePuller(android::util::BLUETOOTH_BYTES_TRANSFER)}},
+ {{2, 3},
+ {},
+ 1 * NS_PER_SEC,
+ new StatsCompanionServicePuller(android::util::BLUETOOTH_BYTES_TRANSFER)}},
// kernel_wakelock
{android::util::KERNEL_WAKELOCK,
- {{}, {}, 1, new StatsCompanionServicePuller(android::util::KERNEL_WAKELOCK)}},
+ {{}, {}, 1 * NS_PER_SEC, new StatsCompanionServicePuller(android::util::KERNEL_WAKELOCK)}},
// subsystem_sleep_state
{android::util::SUBSYSTEM_SLEEP_STATE,
- {{}, {}, 1, new SubsystemSleepStatePuller()}},
+ {{}, {}, 1 * NS_PER_SEC, new SubsystemSleepStatePuller()}},
// cpu_time_per_freq
{android::util::CPU_TIME_PER_FREQ,
- {{3}, {2}, 1, new StatsCompanionServicePuller(android::util::CPU_TIME_PER_FREQ)}},
+ {{3},
+ {2},
+ 1 * NS_PER_SEC,
+ new StatsCompanionServicePuller(android::util::CPU_TIME_PER_FREQ)}},
// cpu_time_per_uid
{android::util::CPU_TIME_PER_UID,
- {{2, 3}, {}, 1, new StatsCompanionServicePuller(android::util::CPU_TIME_PER_UID)}},
+ {{2, 3},
+ {},
+ 1 * NS_PER_SEC,
+ new StatsCompanionServicePuller(android::util::CPU_TIME_PER_UID)}},
// cpu_time_per_uid_freq
- // the throttling is 3sec, handled in frameworks/base/core/java/com/android/internal/os/KernelCpuProcReader
+ // the throttling is 3sec, handled in
+ // frameworks/base/core/java/com/android/internal/os/KernelCpuProcReader
{android::util::CPU_TIME_PER_UID_FREQ,
- {{4}, {2,3}, 0, new StatsCompanionServicePuller(android::util::CPU_TIME_PER_UID_FREQ)}},
+ {{4},
+ {2, 3},
+ 1 * NS_PER_SEC,
+ new StatsCompanionServicePuller(android::util::CPU_TIME_PER_UID_FREQ)}},
// cpu_active_time
- // the throttling is 3sec, handled in frameworks/base/core/java/com/android/internal/os/KernelCpuProcReader
+ // the throttling is 3sec, handled in
+ // frameworks/base/core/java/com/android/internal/os/KernelCpuProcReader
{android::util::CPU_ACTIVE_TIME,
- {{2}, {}, 0, new StatsCompanionServicePuller(android::util::CPU_ACTIVE_TIME)}},
+ {{2},
+ {},
+ 1 * NS_PER_SEC,
+ new StatsCompanionServicePuller(android::util::CPU_ACTIVE_TIME)}},
// cpu_cluster_time
- // the throttling is 3sec, handled in frameworks/base/core/java/com/android/internal/os/KernelCpuProcReader
+ // the throttling is 3sec, handled in
+ // frameworks/base/core/java/com/android/internal/os/KernelCpuProcReader
{android::util::CPU_CLUSTER_TIME,
- {{3}, {2}, 0, new StatsCompanionServicePuller(android::util::CPU_CLUSTER_TIME)}},
+ {{3},
+ {2},
+ 1 * NS_PER_SEC,
+ new StatsCompanionServicePuller(android::util::CPU_CLUSTER_TIME)}},
// wifi_activity_energy_info
- {android::util::WIFI_ACTIVITY_ENERGY_INFO,
- {{}, {}, 1, new StatsCompanionServicePuller(android::util::WIFI_ACTIVITY_ENERGY_INFO)}},
+ {android::util::WIFI_ACTIVITY_INFO,
+ {{},
+ {},
+ 1 * NS_PER_SEC,
+ new StatsCompanionServicePuller(android::util::WIFI_ACTIVITY_INFO)}},
// modem_activity_info
{android::util::MODEM_ACTIVITY_INFO,
- {{}, {}, 1, new StatsCompanionServicePuller(android::util::MODEM_ACTIVITY_INFO)}},
+ {{},
+ {},
+ 1 * NS_PER_SEC,
+ new StatsCompanionServicePuller(android::util::MODEM_ACTIVITY_INFO)}},
// bluetooth_activity_info
{android::util::BLUETOOTH_ACTIVITY_INFO,
- {{}, {}, 1, new StatsCompanionServicePuller(android::util::BLUETOOTH_ACTIVITY_INFO)}},
+ {{},
+ {},
+ 1 * NS_PER_SEC,
+ new StatsCompanionServicePuller(android::util::BLUETOOTH_ACTIVITY_INFO)}},
// system_elapsed_realtime
{android::util::SYSTEM_ELAPSED_REALTIME,
- {{}, {}, 1, new StatsCompanionServicePuller(android::util::SYSTEM_ELAPSED_REALTIME)}},
+ {{},
+ {},
+ 1 * NS_PER_SEC,
+ new StatsCompanionServicePuller(android::util::SYSTEM_ELAPSED_REALTIME)}},
// system_uptime
{android::util::SYSTEM_UPTIME,
- {{}, {}, 1, new StatsCompanionServicePuller(android::util::SYSTEM_UPTIME)}},
+ {{}, {}, 1 * NS_PER_SEC, new StatsCompanionServicePuller(android::util::SYSTEM_UPTIME)}},
// disk_space
{android::util::DISK_SPACE,
- {{}, {}, 1, new StatsCompanionServicePuller(android::util::DISK_SPACE)}},
+ {{}, {}, 1 * NS_PER_SEC, new StatsCompanionServicePuller(android::util::DISK_SPACE)}},
// remaining_battery_capacity
{android::util::REMAINING_BATTERY_CAPACITY,
- {{}, {}, 1, new ResourceHealthManagerPuller(android::util::REMAINING_BATTERY_CAPACITY)}},
+ {{},
+ {},
+ 1 * NS_PER_SEC,
+ new ResourceHealthManagerPuller(android::util::REMAINING_BATTERY_CAPACITY)}},
// full_battery_capacity
{android::util::FULL_BATTERY_CAPACITY,
- {{}, {}, 1, new ResourceHealthManagerPuller(android::util::FULL_BATTERY_CAPACITY)}},
+ {{},
+ {},
+ 1 * NS_PER_SEC,
+ new ResourceHealthManagerPuller(android::util::FULL_BATTERY_CAPACITY)}},
// process_memory_state
{android::util::PROCESS_MEMORY_STATE,
- {{4,5,6,7,8},
- {2,3},
- 0,
+ {{4, 5, 6, 7, 8},
+ {2, 3},
+ 1 * NS_PER_SEC,
new StatsCompanionServicePuller(android::util::PROCESS_MEMORY_STATE)}},
// temperature
{android::util::TEMPERATURE, {{}, {}, 1, new ResourceThermalManagerPuller()}}};
-StatsPullerManagerImpl::StatsPullerManagerImpl()
- : mCurrentPullingInterval(LONG_MAX) {
+StatsPullerManagerImpl::StatsPullerManagerImpl() : mNextPullTimeNs(LONG_MAX) {
}
-bool StatsPullerManagerImpl::Pull(int tagId, vector>* data) {
+bool StatsPullerManagerImpl::Pull(const int tagId, const int64_t timeNs,
+ vector>* data) {
VLOG("Initiating pulling %d", tagId);
if (kAllPullAtomInfo.find(tagId) != kAllPullAtomInfo.end()) {
- bool ret = kAllPullAtomInfo.find(tagId)->second.puller->Pull(data);
+ bool ret = kAllPullAtomInfo.find(tagId)->second.puller->Pull(timeNs, data);
VLOG("pulled %d items", (int)data->size());
return ret;
} else {
@@ -148,12 +197,14 @@ bool StatsPullerManagerImpl::PullerForMatcherExists(int tagId) const {
}
void StatsPullerManagerImpl::updateAlarmLocked() {
- long currentTimeMs = getElapsedRealtimeMillis();
- long nextAlarmTimeMs = currentTimeMs + mCurrentPullingInterval -
- (currentTimeMs - mTimeBaseSec * 1000) % mCurrentPullingInterval;
+ if (mNextPullTimeNs == LONG_MAX) {
+ VLOG("No need to set alarms. Skipping");
+ return;
+ }
+
sp statsCompanionServiceCopy = mStatsCompanionService;
if (statsCompanionServiceCopy != nullptr) {
- statsCompanionServiceCopy->setPullingAlarms(nextAlarmTimeMs, mCurrentPullingInterval);
+ statsCompanionServiceCopy->setPullingAlarm(mNextPullTimeNs / 1000000);
} else {
VLOG("StatsCompanionService not available. Alarm not set.");
}
@@ -174,7 +225,7 @@ void StatsPullerManagerImpl::SetStatsCompanionService(
}
void StatsPullerManagerImpl::RegisterReceiver(int tagId, wp receiver,
- long intervalMs) {
+ int64_t nextPullTimeNs, int64_t intervalNs) {
AutoMutex _l(mLock);
auto& receivers = mReceivers[tagId];
for (auto it = receivers.begin(); it != receivers.end(); it++) {
@@ -185,21 +236,24 @@ void StatsPullerManagerImpl::RegisterReceiver(int tagId, wp re
}
ReceiverInfo receiverInfo;
receiverInfo.receiver = receiver;
- receiverInfo.timeInfo.first = intervalMs;
- receivers.push_back(receiverInfo);
// Round it to the nearest minutes. This is the limit of alarm manager.
- // In practice, we should limit it higher.
- long roundedIntervalMs = intervalMs/1000/60 * 1000 * 60;
+ // In practice, we should always have larger buckets.
+ int64_t roundedIntervalNs = intervalNs / NS_PER_SEC / 60 * NS_PER_SEC * 60;
// Scheduled pulling should be at least 1 min apart.
// This can be lower in cts tests, in which case we round it to 1 min.
- if (roundedIntervalMs < 60 * 1000) {
- roundedIntervalMs = 60 * 1000;
+ if (roundedIntervalNs < 60 * (int64_t)NS_PER_SEC) {
+ roundedIntervalNs = 60 * (int64_t)NS_PER_SEC;
}
+
+ receiverInfo.intervalNs = roundedIntervalNs;
+ receiverInfo.nextPullTimeNs = nextPullTimeNs;
+ receivers.push_back(receiverInfo);
+
// There is only one alarm for all pulled events. So only set it to the smallest denom.
- if (roundedIntervalMs < mCurrentPullingInterval) {
- VLOG("Updating pulling interval %ld", intervalMs);
- mCurrentPullingInterval = roundedIntervalMs;
+ if (nextPullTimeNs < mNextPullTimeNs) {
+ VLOG("Updating next pull time %lld", (long long)mNextPullTimeNs);
+ mNextPullTimeNs = nextPullTimeNs;
updateAlarmLocked();
}
VLOG("Puller for tagId %d registered of %d", tagId, (int)receivers.size());
@@ -224,16 +278,22 @@ void StatsPullerManagerImpl::UnRegisterReceiver(int tagId, wp
void StatsPullerManagerImpl::OnAlarmFired() {
AutoMutex _l(mLock);
- uint64_t currentTimeMs = getElapsedRealtimeMillis();
+ int64_t currentTimeNs = getElapsedRealtimeNs();
+
+ int64_t minNextPullTimeNs = LONG_MAX;
vector>> needToPull =
vector>>();
for (auto& pair : mReceivers) {
vector receivers = vector();
if (pair.second.size() != 0) {
- for (auto& receiverInfo : pair.second) {
- if (receiverInfo.timeInfo.first + receiverInfo.timeInfo.second > currentTimeMs) {
+ for (ReceiverInfo& receiverInfo : pair.second) {
+ if (receiverInfo.nextPullTimeNs < currentTimeNs) {
receivers.push_back(&receiverInfo);
+ } else {
+ if (receiverInfo.nextPullTimeNs < minNextPullTimeNs) {
+ minNextPullTimeNs = receiverInfo.nextPullTimeNs;
+ }
}
}
if (receivers.size() > 0) {
@@ -244,18 +304,29 @@ void StatsPullerManagerImpl::OnAlarmFired() {
for (const auto& pullInfo : needToPull) {
vector> data;
- if (Pull(pullInfo.first, &data)) {
+ if (Pull(pullInfo.first, currentTimeNs, &data)) {
for (const auto& receiverInfo : pullInfo.second) {
sp receiverPtr = receiverInfo->receiver.promote();
if (receiverPtr != nullptr) {
receiverPtr->onDataPulled(data);
- receiverInfo->timeInfo.second = currentTimeMs;
+ // we may have just come out of a coma, compute next pull time
+ receiverInfo->nextPullTimeNs =
+ ceil((double_t)(currentTimeNs - receiverInfo->nextPullTimeNs) /
+ receiverInfo->intervalNs) *
+ receiverInfo->intervalNs +
+ receiverInfo->nextPullTimeNs;
+ if (receiverInfo->nextPullTimeNs < minNextPullTimeNs) {
+ minNextPullTimeNs = receiverInfo->nextPullTimeNs;
+ }
} else {
VLOG("receiver already gone.");
}
}
}
}
+
+ mNextPullTimeNs = minNextPullTimeNs;
+ updateAlarmLocked();
}
int StatsPullerManagerImpl::ForceClearPullerCache() {
@@ -266,10 +337,10 @@ int StatsPullerManagerImpl::ForceClearPullerCache() {
return totalCleared;
}
-int StatsPullerManagerImpl::ClearPullerCacheIfNecessary(long timestampSec) {
+int StatsPullerManagerImpl::ClearPullerCacheIfNecessary(int64_t timestampNs) {
int totalCleared = 0;
for (const auto& pulledAtom : kAllPullAtomInfo) {
- totalCleared += pulledAtom.second.puller->ClearCacheIfNecessary(timestampSec);
+ totalCleared += pulledAtom.second.puller->ClearCacheIfNecessary(timestampNs);
}
return totalCleared;
}
diff --git a/cmds/statsd/src/external/StatsPullerManagerImpl.h b/cmds/statsd/src/external/StatsPullerManagerImpl.h
index 682ad33a8749a13322a825765dc22219ec97ed38..8c771f31fdc5bfa7a85f7729da9be3936ba22f94 100644
--- a/cmds/statsd/src/external/StatsPullerManagerImpl.h
+++ b/cmds/statsd/src/external/StatsPullerManagerImpl.h
@@ -41,7 +41,7 @@ typedef struct {
std::vector nonAdditiveFields;
// How long should the puller wait before doing an actual pull again. Default
// 1 sec. Set this to 0 if this is handled elsewhere.
- long coolDownSec = 1;
+ int64_t coolDownNs = 1 * NS_PER_SEC;
// The actual puller
sp puller;
} PullAtomInfo;
@@ -50,7 +50,8 @@ class StatsPullerManagerImpl : public virtual RefBase {
public:
static StatsPullerManagerImpl& GetInstance();
- void RegisterReceiver(int tagId, wp receiver, long intervalMs);
+ void RegisterReceiver(int tagId, wp receiver, int64_t nextPullTimeNs,
+ int64_t intervalNs);
void UnRegisterReceiver(int tagId, wp receiver);
@@ -59,13 +60,11 @@ public:
void OnAlarmFired();
- bool Pull(const int tagId, vector>* data);
-
- void SetTimeBaseSec(long timeBaseSec) {mTimeBaseSec = timeBaseSec;};
+ bool Pull(const int tagId, const int64_t timeNs, vector>* data);
int ForceClearPullerCache();
- int ClearPullerCacheIfNecessary(long timestampSec);
+ int ClearPullerCacheIfNecessary(int64_t timestampNs);
void SetStatsCompanionService(sp statsCompanionService);
@@ -77,8 +76,8 @@ public:
sp mStatsCompanionService = nullptr;
typedef struct {
- // pull_interval_sec : last_pull_time_sec
- std::pair timeInfo;
+ int64_t nextPullTimeNs;
+ int64_t intervalNs;
wp receiver;
} ReceiverInfo;
@@ -90,12 +89,7 @@ public:
void updateAlarmLocked();
- long mCurrentPullingInterval;
-
- // for pulled metrics, it is important for the buckets to be aligned to multiple of smallest
- // bucket size. All pulled metrics start pulling based on this time, so that they can be
- // correctly attributed to the correct buckets.
- long mTimeBaseSec;
+ int64_t mNextPullTimeNs;
};
} // namespace statsd
diff --git a/cmds/statsd/src/guardrail/StatsdStats.cpp b/cmds/statsd/src/guardrail/StatsdStats.cpp
index ef637df68ed304874783897d5a5b789ccfedcb3b..22ff9428c83a1a49e1b1e1373d35efc5dbbba8b8 100644
--- a/cmds/statsd/src/guardrail/StatsdStats.cpp
+++ b/cmds/statsd/src/guardrail/StatsdStats.cpp
@@ -76,6 +76,7 @@ const int FIELD_ID_CONFIG_STATS_MATCHER_STATS = 13;
const int FIELD_ID_CONFIG_STATS_CONDITION_STATS = 14;
const int FIELD_ID_CONFIG_STATS_METRIC_STATS = 15;
const int FIELD_ID_CONFIG_STATS_ALERT_STATS = 16;
+const int FIELD_ID_CONFIG_STATS_METRIC_DIMENSION_IN_CONDITION_STATS = 17;
const int FIELD_ID_MATCHER_STATS_ID = 1;
const int FIELD_ID_MATCHER_STATS_COUNT = 2;
@@ -255,6 +256,20 @@ void StatsdStats::noteMetricDimensionSize(const ConfigKey& key, const int64_t& i
}
}
+void StatsdStats::noteMetricDimensionInConditionSize(
+ const ConfigKey& key, const int64_t& id, int size) {
+ lock_guard lock(mLock);
+ // if name doesn't exist before, it will create the key with count 0.
+ auto statsIt = mConfigStats.find(key);
+ if (statsIt == mConfigStats.end()) {
+ return;
+ }
+ auto& metricsDimensionMap = statsIt->second->metric_dimension_in_condition_stats;
+ if (size > metricsDimensionMap[id]) {
+ metricsDimensionMap[id] = size;
+ }
+}
+
void StatsdStats::noteMatcherMatched(const ConfigKey& key, const int64_t& id) {
lock_guard lock(mLock);
@@ -339,6 +354,7 @@ void StatsdStats::resetInternalLocked() {
config.second->matcher_stats.clear();
config.second->condition_stats.clear();
config.second->metric_stats.clear();
+ config.second->metric_dimension_in_condition_stats.clear();
config.second->alert_stats.clear();
}
}
@@ -504,6 +520,13 @@ void addConfigStatsToProto(const ConfigStats& configStats, ProtoOutputStream* pr
proto->write(FIELD_TYPE_INT32 | FIELD_ID_METRIC_STATS_COUNT, pair.second);
proto->end(tmpToken);
}
+ for (const auto& pair : configStats.metric_dimension_in_condition_stats) {
+ uint64_t tmpToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
+ FIELD_ID_CONFIG_STATS_METRIC_DIMENSION_IN_CONDITION_STATS);
+ proto->write(FIELD_TYPE_INT64 | FIELD_ID_METRIC_STATS_ID, (long long)pair.first);
+ proto->write(FIELD_TYPE_INT32 | FIELD_ID_METRIC_STATS_COUNT, pair.second);
+ proto->end(tmpToken);
+ }
for (const auto& pair : configStats.alert_stats) {
uint64_t tmpToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
diff --git a/cmds/statsd/src/guardrail/StatsdStats.h b/cmds/statsd/src/guardrail/StatsdStats.h
index 7f8755b8c1e064f95a4c1fd07a4bf8dea1d58cd5..bd395c4c232b7dfbafa833996e9903ac63ceef4b 100644
--- a/cmds/statsd/src/guardrail/StatsdStats.h
+++ b/cmds/statsd/src/guardrail/StatsdStats.h
@@ -57,6 +57,12 @@ struct ConfigStats {
// it means some data has been dropped. The map size is capped by kMaxConfigCount.
std::map metric_stats;
+ // Stores the max number of output tuple of dimensions in condition across dimensions in what
+ // when it's bigger than kDimensionKeySizeSoftLimit. When you see the number is
+ // kDimensionKeySizeHardLimit +1, it means some data has been dropped. The map size is capped by
+ // kMaxConfigCount.
+ std::map metric_dimension_in_condition_stats;
+
// Stores the number of times an anomaly detection alert has been declared.
// The map size is capped by kMaxConfigCount.
std::map alert_stats;
@@ -183,6 +189,19 @@ public:
*/
void noteMetricDimensionSize(const ConfigKey& key, const int64_t& id, int size);
+
+ /**
+ * Report the max size of output tuple of dimension in condition across dimensions in what.
+ *
+ * Note: only report when the metric has an output dimension in condition, and the max tuple
+ * count > kDimensionKeySizeSoftLimit.
+ *
+ * [key]: The config key that this metric belongs to.
+ * [id]: The id of the metric.
+ * [size]: The output tuple size.
+ */
+ void noteMetricDimensionInConditionSize(const ConfigKey& key, const int64_t& id, int size);
+
/**
* Report a matcher has been matched.
*
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.cpp b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
index c28bb8800e20af11ea616ed47778a4f9c57570d7..f02f30756b2d16506d8d2d20ecd42ac361e84946 100644
--- a/cmds/statsd/src/metrics/DurationMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
@@ -308,11 +308,14 @@ void DurationMetricProducer::onSlicedConditionMayChangeLocked_opt2(bool conditio
if (mMetric2ConditionLinks.size() == 0 ||
trueDim.contains(linkedConditionDimensionKey)) {
if (!whatIt.second.empty()) {
+ auto newEventKey = MetricDimensionKey(whatIt.first, trueDim);
+ if (hitGuardRailLocked(newEventKey)) {
+ continue;
+ }
unique_ptr newTracker =
whatIt.second.begin()->second->clone(eventTime);
if (newTracker != nullptr) {
- newTracker->setEventKey(
- MetricDimensionKey(whatIt.first, trueDim));
+ newTracker->setEventKey(newEventKey);
newTracker->onConditionChanged(true, eventTime);
whatIt.second[trueDim] = std::move(newTracker);
}
@@ -370,11 +373,14 @@ void DurationMetricProducer::onSlicedConditionMayChangeLocked(bool overallCondit
for (const auto& conditionDimension : conditionDimensionsKeySet) {
for (auto& whatIt : mCurrentSlicedDurationTrackerMap) {
if (!whatIt.second.empty()) {
+ auto newEventKey = MetricDimensionKey(whatIt.first, conditionDimension);
+ if (hitGuardRailLocked(newEventKey)) {
+ continue;
+ }
unique_ptr newTracker =
whatIt.second.begin()->second->clone(eventTime);
if (newTracker != nullptr) {
- newTracker->setEventKey(MetricDimensionKey(
- whatIt.first, conditionDimension));
+ newTracker->setEventKey(MetricDimensionKey(newEventKey));
newTracker->onSlicedConditionMayChange(overallCondition, eventTime);
whatIt.second[conditionDimension] = std::move(newTracker);
}
@@ -397,10 +403,13 @@ void DurationMetricProducer::onSlicedConditionMayChangeLocked(bool overallCondit
for (const auto& conditionDimension : conditionDimensionsKeys) {
if (!whatIt.second.empty() &&
whatIt.second.find(conditionDimension) == whatIt.second.end()) {
+ auto newEventKey = MetricDimensionKey(whatIt.first, conditionDimension);
+ if (hitGuardRailLocked(newEventKey)) {
+ continue;
+ }
auto newTracker = whatIt.second.begin()->second->clone(eventTime);
if (newTracker != nullptr) {
- newTracker->setEventKey(
- MetricDimensionKey(whatIt.first, conditionDimension));
+ newTracker->setEventKey(newEventKey);
newTracker->onSlicedConditionMayChange(overallCondition, eventTime);
whatIt.second[conditionDimension] = std::move(newTracker);
}
@@ -552,15 +561,35 @@ void DurationMetricProducer::dumpStatesLocked(FILE* out, bool verbose) const {
}
bool DurationMetricProducer::hitGuardRailLocked(const MetricDimensionKey& newKey) {
- // 1. Report the tuple count if the tuple count > soft limit
- if (mCurrentSlicedDurationTrackerMap.size() > StatsdStats::kDimensionKeySizeSoftLimit - 1) {
- size_t newTupleCount = mCurrentSlicedDurationTrackerMap.size() + 1;
- StatsdStats::getInstance().noteMetricDimensionSize(mConfigKey, mMetricId, newTupleCount);
- // 2. Don't add more tuples, we are above the allowed threshold. Drop the data.
- if (newTupleCount > StatsdStats::kDimensionKeySizeHardLimit) {
- ALOGE("DurationMetric %lld dropping data for dimension key %s",
- (long long)mMetricId, newKey.toString().c_str());
- return true;
+ auto whatIt = mCurrentSlicedDurationTrackerMap.find(newKey.getDimensionKeyInWhat());
+ if (whatIt != mCurrentSlicedDurationTrackerMap.end()) {
+ auto condIt = whatIt->second.find(newKey.getDimensionKeyInCondition());
+ if (condIt != whatIt->second.end()) {
+ return false;
+ }
+ if (whatIt->second.size() > StatsdStats::kDimensionKeySizeSoftLimit - 1) {
+ size_t newTupleCount = whatIt->second.size() + 1;
+ StatsdStats::getInstance().noteMetricDimensionInConditionSize(
+ mConfigKey, mMetricId, newTupleCount);
+ // 2. Don't add more tuples, we are above the allowed threshold. Drop the data.
+ if (newTupleCount > StatsdStats::kDimensionKeySizeHardLimit) {
+ ALOGE("DurationMetric %lld dropping data for condition dimension key %s",
+ (long long)mMetricId, newKey.getDimensionKeyInCondition().toString().c_str());
+ return true;
+ }
+ }
+ } else {
+ // 1. Report the tuple count if the tuple count > soft limit
+ if (mCurrentSlicedDurationTrackerMap.size() > StatsdStats::kDimensionKeySizeSoftLimit - 1) {
+ size_t newTupleCount = mCurrentSlicedDurationTrackerMap.size() + 1;
+ StatsdStats::getInstance().noteMetricDimensionSize(
+ mConfigKey, mMetricId, newTupleCount);
+ // 2. Don't add more tuples, we are above the allowed threshold. Drop the data.
+ if (newTupleCount > StatsdStats::kDimensionKeySizeHardLimit) {
+ ALOGE("DurationMetric %lld dropping data for what dimension key %s",
+ (long long)mMetricId, newKey.getDimensionKeyInWhat().toString().c_str());
+ return true;
+ }
}
}
return false;
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
index f0e0df18693a41624bb2834efd7ba6d65055dead..b13c3e7a0487dd780e6a1c1b3e63b85064c3a9dd 100644
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
@@ -112,7 +112,8 @@ GaugeMetricProducer::GaugeMetricProducer(const ConfigKey& key, const GaugeMetric
// Kicks off the puller immediately.
if (mPullTagId != -1 && mSamplingType == GaugeMetric::RANDOM_ONE_SAMPLE) {
- mStatsPullerManager->RegisterReceiver(mPullTagId, this, bucketSizeMills);
+ mStatsPullerManager->RegisterReceiver(
+ mPullTagId, this, mCurrentBucketStartTimeNs + mBucketSizeNs, mBucketSizeNs);
}
VLOG("Gauge metric %lld created. bucket size %lld start_time: %lld sliced %d",
@@ -255,7 +256,7 @@ void GaugeMetricProducer::pullLocked() {
}
vector> allData;
- if (!mStatsPullerManager->Pull(mPullTagId, &allData)) {
+ if (!mStatsPullerManager->Pull(mPullTagId, getElapsedRealtimeNs(), &allData)) {
ALOGE("Gauge Stats puller failed for tag: %d", mPullTagId);
return;
}
diff --git a/cmds/statsd/src/metrics/MetricsManager.cpp b/cmds/statsd/src/metrics/MetricsManager.cpp
index 1be082a692cc49fb2e9b5f084d10614166fc5b99..00188e8da0fb4a125d03c78e5204a9c9d596f89c 100644
--- a/cmds/statsd/src/metrics/MetricsManager.cpp
+++ b/cmds/statsd/src/metrics/MetricsManager.cpp
@@ -351,7 +351,7 @@ void MetricsManager::onLogEvent(const LogEvent& event) {
}
void MetricsManager::onAnomalyAlarmFired(
- const uint64_t timestampNs,
+ const uint64_t& timestampNs,
unordered_set, SpHash>& alarmSet) {
for (const auto& itr : mAllAnomalyTrackers) {
itr->informAlarmsFired(timestampNs, alarmSet);
@@ -359,7 +359,7 @@ void MetricsManager::onAnomalyAlarmFired(
}
void MetricsManager::onPeriodicAlarmFired(
- const uint64_t timestampNs,
+ const uint64_t& timestampNs,
unordered_set, SpHash>& alarmSet) {
for (const auto& itr : mAllPeriodicAlarmTrackers) {
itr->informAlarmsFired(timestampNs, alarmSet);
diff --git a/cmds/statsd/src/metrics/MetricsManager.h b/cmds/statsd/src/metrics/MetricsManager.h
index 05ce84d7ea8f93447ba31e26ec821bc627bfde8d..da0cd4a29d3b8251cb1d04ed9972eea62956fdcf 100644
--- a/cmds/statsd/src/metrics/MetricsManager.h
+++ b/cmds/statsd/src/metrics/MetricsManager.h
@@ -48,11 +48,11 @@ public:
void onLogEvent(const LogEvent& event);
void onAnomalyAlarmFired(
- const uint64_t timestampNs,
+ const uint64_t& timestampNs,
unordered_set, SpHash>& alarmSet);
void onPeriodicAlarmFired(
- const uint64_t timestampNs,
+ const uint64_t& timestampNs,
unordered_set, SpHash>& alarmSet);
void notifyAppUpgrade(const uint64_t& eventTimeNs, const string& apk, const int uid,
@@ -184,6 +184,7 @@ private:
FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_multiple_buckets);
FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_long_refractory_period);
+ FRIEND_TEST(AlarmE2eTest, TestMultipleAlarms);
};
} // namespace statsd
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.cpp b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
index e19e2368f75185d1b3ff016fcff44c976d61573a..d0f510df2aa215eb93c6f98cf7c723d877fc7c2a 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
@@ -110,10 +110,12 @@ ValueMetricProducer::ValueMetricProducer(const ConfigKey& key, const ValueMetric
}
mConditionSliced = (metric.links().size() > 0) || (mDimensionsInCondition.size() > 0);
- if (!metric.has_condition() && mPullTagId != -1) {
- VLOG("Setting up periodic pulling for %d", mPullTagId);
- mStatsPullerManager->RegisterReceiver(mPullTagId, this, bucketSizeMills);
+ // Kicks off the puller immediately.
+ if (mPullTagId != -1) {
+ mStatsPullerManager->RegisterReceiver(
+ mPullTagId, this, mCurrentBucketStartTimeNs + mBucketSizeNs, mBucketSizeNs);
}
+
VLOG("value metric %lld created. bucket size %lld start_time: %lld",
(long long)metric.id(), (long long)mBucketSizeNs, (long long)mStartTimeNs);
}
@@ -194,26 +196,21 @@ void ValueMetricProducer::onDumpReportLocked(const uint64_t dumpTimeNs,
// TODO: Clear mDimensionKeyMap once the report is dumped.
}
-void ValueMetricProducer::onConditionChangedLocked(const bool condition, const uint64_t eventTime) {
+void ValueMetricProducer::onConditionChangedLocked(const bool condition,
+ const uint64_t eventTimeNs) {
mCondition = condition;
- if (eventTime < mCurrentBucketStartTimeNs) {
- VLOG("Skip event due to late arrival: %lld vs %lld", (long long)eventTime,
+ if (eventTimeNs < mCurrentBucketStartTimeNs) {
+ VLOG("Skip event due to late arrival: %lld vs %lld", (long long)eventTimeNs,
(long long)mCurrentBucketStartTimeNs);
return;
}
- flushIfNeededLocked(eventTime);
+ flushIfNeededLocked(eventTimeNs);
if (mPullTagId != -1) {
- if (mCondition == true) {
- mStatsPullerManager->RegisterReceiver(mPullTagId, this, mBucketSizeNs / 1000 / 1000);
- } else if (mCondition == false) {
- mStatsPullerManager->UnRegisterReceiver(mPullTagId, this);
- }
-
vector> allData;
- if (mStatsPullerManager->Pull(mPullTagId, &allData)) {
+ if (mStatsPullerManager->Pull(mPullTagId, eventTimeNs, &allData)) {
if (allData.size() == 0) {
return;
}
@@ -315,8 +312,13 @@ void ValueMetricProducer::onMatchedLogEventInternalLocked(
if (mPullTagId != -1) { // for pulled events
if (mCondition == true) {
- interval.start = value;
- interval.startUpdated = true;
+ if (!interval.startUpdated) {
+ interval.start = value;
+ interval.startUpdated = true;
+ } else {
+ // skip it if there is already value recorded for the start
+ VLOG("Already recorded value for this dimension %s", eventKey.toString().c_str());
+ }
} else {
// Generally we expect value to be monotonically increasing.
// If not, there was a reset event. We take the absolute value as
@@ -385,6 +387,7 @@ void ValueMetricProducer::flushCurrentBucketLocked(const uint64_t& eventTimeNs)
int tainted = 0;
for (const auto& slice : mCurrentSlicedBucket) {
tainted += slice.second.tainted;
+ tainted += slice.second.startUpdated;
info.mValue = slice.second.sum;
// it will auto create new vector of ValuebucketInfo if the key is not found.
auto& bucketList = mPastBuckets[slice.first];
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.h b/cmds/statsd/src/metrics/ValueMetricProducer.h
index 796e83af4f1d381cf0b385e97b8d5a9d2bf4e547..45d95316e8e1c2063b21aa0191ab5c8a9aba5d16 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.h
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.h
@@ -53,7 +53,7 @@ public:
if (mPullTagId != -1) {
vector> allData;
- mStatsPullerManager->Pull(mPullTagId, &allData);
+ mStatsPullerManager->Pull(mPullTagId, eventTimeNs, &allData);
if (allData.size() == 0) {
// This shouldn't happen since this valuemetric is not useful now.
}
@@ -159,6 +159,10 @@ private:
FRIEND_TEST(ValueMetricProducerTest, TestPulledValueWithUpgrade);
FRIEND_TEST(ValueMetricProducerTest, TestPushedEventsWithoutCondition);
FRIEND_TEST(ValueMetricProducerTest, TestAnomalyDetection);
+ FRIEND_TEST(ValueMetricProducerTest, TestBucketBoundaryNoCondition);
+ FRIEND_TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition);
+ FRIEND_TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition2);
+ FRIEND_TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition3);
};
} // namespace statsd
diff --git a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp b/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp
index 15d9619f02203a36b38a51e0fede5291f6c94d89..5c1e9c0cd65e8a202818f990aa8a986d711ae01c 100644
--- a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp
+++ b/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp
@@ -327,8 +327,9 @@ int64_t MaxDurationTracker::predictAnomalyTimestampNs(const DurationAnomalyTrack
}
}
}
- int64_t threshold = anomalyTracker.getAnomalyThreshold();
- return currentTimestamp + threshold - maxElapsed;
+ int64_t anomalyTimeNs = currentTimestamp + anomalyTracker.getAnomalyThreshold() - maxElapsed;
+ int64_t refractoryEndNs = anomalyTracker.getRefractoryPeriodEndsSec(mEventKey) * NS_PER_SEC;
+ return std::max(anomalyTimeNs, refractoryEndNs);
}
void MaxDurationTracker::dumpStates(FILE* out, bool verbose) const {
diff --git a/cmds/statsd/src/stats_log.proto b/cmds/statsd/src/stats_log.proto
index dd3b37c8c2d77a6cb5bb8fe2a5d27cd2de035c57..a25df3fc4c0918d02d0086cd99ab56ff125c1af5 100644
--- a/cmds/statsd/src/stats_log.proto
+++ b/cmds/statsd/src/stats_log.proto
@@ -241,6 +241,7 @@ message StatsdStatsReport {
repeated ConditionStats condition_stats = 14;
repeated MetricStats metric_stats = 15;
repeated AlertStats alert_stats = 16;
+ repeated MetricStats metric_dimension_in_condition_stats = 17;
}
repeated ConfigStats config_stats = 3;
diff --git a/cmds/statsd/src/stats_log_util.cpp b/cmds/statsd/src/stats_log_util.cpp
index cab61e9787c6559e465d8c19a69d02c5a1ee7d07..efd810f0114045f7834ef833014381c4287b903e 100644
--- a/cmds/statsd/src/stats_log_util.cpp
+++ b/cmds/statsd/src/stats_log_util.cpp
@@ -221,7 +221,8 @@ void writeFieldValueTreeToStream(int tagId, const std::vector& value
int64_t TimeUnitToBucketSizeInMillisGuardrailed(int uid, TimeUnit unit) {
int64_t bucketSizeMillis = TimeUnitToBucketSizeInMillis(unit);
- if (bucketSizeMillis > 1000 && bucketSizeMillis < 5 * 60 * 1000LL && uid != AID_SHELL) {
+ if (bucketSizeMillis > 1000 && bucketSizeMillis < 5 * 60 * 1000LL && uid != AID_SHELL &&
+ uid != AID_ROOT) {
bucketSizeMillis = 5 * 60 * 1000LL;
}
return bucketSizeMillis;
diff --git a/cmds/statsd/statsd.rc b/cmds/statsd/statsd.rc
index 920273b5dfaa72379a33e3ad2582c8fceae9768c..3a0c22425e5ccdf6d873d9d4d9bd21a453ae122b 100644
--- a/cmds/statsd/statsd.rc
+++ b/cmds/statsd/statsd.rc
@@ -20,5 +20,5 @@ service statsd /system/bin/statsd
on post-fs-data
# Create directory for statsd
- mkdir /data/misc/stats-data/ 0770 statsd statsd
- mkdir /data/misc/stats-service/ 0770 statsd statsd
+ mkdir /data/misc/stats-data/ 0770 statsd system
+ mkdir /data/misc/stats-service/ 0770 statsd system
diff --git a/cmds/statsd/tests/FieldValue_test.cpp b/cmds/statsd/tests/FieldValue_test.cpp
index 73e7c44dc3da02fde407f711599fab0b43f02474..5a6aba624d7d5c3626a35d63924ba50fbe7f6755 100644
--- a/cmds/statsd/tests/FieldValue_test.cpp
+++ b/cmds/statsd/tests/FieldValue_test.cpp
@@ -356,7 +356,7 @@ TEST(AtomMatcherTest, TestWriteAtomToProto) {
EXPECT_EQ("location1", atom.attribution_node(0).tag());
EXPECT_EQ(2222, atom.attribution_node(1).uid());
EXPECT_EQ("location2", atom.attribution_node(1).tag());
- EXPECT_EQ(999, atom.num_of_results());
+ EXPECT_EQ(999, atom.num_results());
}
diff --git a/cmds/statsd/tests/e2e/Alarm_e2e_test.cpp b/cmds/statsd/tests/e2e/Alarm_e2e_test.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..73c4e7b859ded0ee561816879a4edfb19a290114
--- /dev/null
+++ b/cmds/statsd/tests/e2e/Alarm_e2e_test.cpp
@@ -0,0 +1,92 @@
+// Copyright (C) 2017 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.
+
+#include
+
+#include "src/StatsLogProcessor.h"
+#include "src/stats_log_util.h"
+#include "tests/statsd_test_util.h"
+
+#include
+
+namespace android {
+namespace os {
+namespace statsd {
+
+#ifdef __ANDROID__
+
+namespace {
+
+StatsdConfig CreateStatsdConfig() {
+ StatsdConfig config;
+ config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
+
+ auto alarm = config.add_alarm();
+ alarm->set_id(123456);
+ alarm->set_offset_millis(TimeUnitToBucketSizeInMillis(TEN_MINUTES));
+ alarm->set_period_millis(TimeUnitToBucketSizeInMillis(ONE_HOUR));
+
+ alarm = config.add_alarm();
+ alarm->set_id(654321);
+ alarm->set_offset_millis(TimeUnitToBucketSizeInMillis(FIVE_MINUTES));
+ alarm->set_period_millis(TimeUnitToBucketSizeInMillis(THIRTY_MINUTES));
+ return config;
+}
+
+} // namespace
+
+TEST(AlarmE2eTest, TestMultipleAlarms) {
+ auto config = CreateStatsdConfig();
+ int64_t bucketStartTimeNs = 10000000000;
+
+ ConfigKey cfgKey;
+ auto processor = CreateStatsLogProcessor(bucketStartTimeNs / NS_PER_SEC, config, cfgKey);
+ EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+ EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
+ EXPECT_EQ(2u, processor->mMetricsManagers.begin()->second->mAllPeriodicAlarmTrackers.size());
+
+ auto alarmTracker1 = processor->mMetricsManagers.begin()->second->mAllPeriodicAlarmTrackers[0];
+ auto alarmTracker2 = processor->mMetricsManagers.begin()->second->mAllPeriodicAlarmTrackers[1];
+
+ int64_t alarmTimestampSec0 = bucketStartTimeNs / NS_PER_SEC + 10 * 60;
+ int64_t alarmTimestampSec1 = bucketStartTimeNs / NS_PER_SEC + 5 * 60;
+ EXPECT_EQ(alarmTimestampSec0, alarmTracker1->getAlarmTimestampSec());
+ EXPECT_EQ(alarmTimestampSec1, alarmTracker2->getAlarmTimestampSec());
+
+ // Alarm fired.
+ const int64_t alarmFiredTimestampSec0 = alarmTimestampSec1 + 5;
+ auto alarmSet = processor->getPeriodicAlarmMonitor()->popSoonerThan(
+ static_cast(alarmFiredTimestampSec0));
+ EXPECT_EQ(1u, alarmSet.size());
+ processor->onPeriodicAlarmFired(alarmFiredTimestampSec0 * NS_PER_SEC, alarmSet);
+ EXPECT_EQ(alarmTimestampSec0, alarmTracker1->getAlarmTimestampSec());
+ EXPECT_EQ(alarmTimestampSec1 + 30 * 60, alarmTracker2->getAlarmTimestampSec());
+
+ // Alarms fired very late.
+ const int64_t alarmFiredTimestampSec1 = alarmTimestampSec0 + 2 * 60 * 60 + 125;
+ alarmSet = processor->getPeriodicAlarmMonitor()->popSoonerThan(
+ static_cast(alarmFiredTimestampSec1));
+ EXPECT_EQ(2u, alarmSet.size());
+ processor->onPeriodicAlarmFired(alarmFiredTimestampSec1 * NS_PER_SEC, alarmSet);
+ EXPECT_EQ(alarmTimestampSec0 + 60 * 60 * 3, alarmTracker1->getAlarmTimestampSec());
+ EXPECT_EQ(alarmTimestampSec1 + 30 * 60 * 5, alarmTracker2->getAlarmTimestampSec());
+}
+
+#else
+GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
+
+} // namespace statsd
+} // namespace os
+} // namespace android
diff --git a/cmds/statsd/tests/e2e/GaugeMetric_e2e_push_test.cpp b/cmds/statsd/tests/e2e/GaugeMetric_e2e_push_test.cpp
index 2e6a0f05a3412f782172ecd1a4bd527b58698eb4..2b91324a9d193766a253a0bbbe441f4529b8c9c7 100644
--- a/cmds/statsd/tests/e2e/GaugeMetric_e2e_push_test.cpp
+++ b/cmds/statsd/tests/e2e/GaugeMetric_e2e_push_test.cpp
@@ -34,7 +34,7 @@ StatsdConfig CreateStatsdConfigForPushedEvent(const GaugeMetric::SamplingType sa
*config.add_atom_matcher() = CreateMoveToBackgroundAtomMatcher();
*config.add_atom_matcher() = CreateMoveToForegroundAtomMatcher();
- auto atomMatcher = CreateSimpleAtomMatcher("", android::util::APP_START_CHANGED);
+ auto atomMatcher = CreateSimpleAtomMatcher("", android::util::APP_START_OCCURRED);
*config.add_atom_matcher() = atomMatcher;
auto isInBackgroundPredicate = CreateIsInBackgroundPredicate();
@@ -49,18 +49,18 @@ StatsdConfig CreateStatsdConfigForPushedEvent(const GaugeMetric::SamplingType sa
gaugeMetric->mutable_gauge_fields_filter()->set_include_all(false);
gaugeMetric->set_sampling_type(sampling_type);
auto fieldMatcher = gaugeMetric->mutable_gauge_fields_filter()->mutable_fields();
- fieldMatcher->set_field(android::util::APP_START_CHANGED);
+ fieldMatcher->set_field(android::util::APP_START_OCCURRED);
fieldMatcher->add_child()->set_field(3); // type (enum)
fieldMatcher->add_child()->set_field(4); // activity_name(str)
fieldMatcher->add_child()->set_field(7); // activity_start_msec(int64)
*gaugeMetric->mutable_dimensions_in_what() =
- CreateDimensions(android::util::APP_START_CHANGED, {1 /* uid field */ });
+ CreateDimensions(android::util::APP_START_OCCURRED, {1 /* uid field */ });
gaugeMetric->set_bucket(FIVE_MINUTES);
auto links = gaugeMetric->add_links();
links->set_condition(isInBackgroundPredicate.id());
auto dimensionWhat = links->mutable_fields_in_what();
- dimensionWhat->set_field(android::util::APP_START_CHANGED);
+ dimensionWhat->set_field(android::util::APP_START_OCCURRED);
dimensionWhat->add_child()->set_field(1); // uid field.
auto dimensionCondition = links->mutable_fields_in_condition();
dimensionCondition->set_field(android::util::ACTIVITY_FOREGROUND_STATE_CHANGED);
@@ -68,12 +68,12 @@ StatsdConfig CreateStatsdConfigForPushedEvent(const GaugeMetric::SamplingType sa
return config;
}
-std::unique_ptr CreateAppStartChangedEvent(
- const int uid, const string& pkg_name, AppStartChanged::TransitionType type,
+std::unique_ptr CreateAppStartOccurredEvent(
+ const int uid, const string& pkg_name, AppStartOccurred::TransitionType type,
const string& activity_name, const string& calling_pkg_name, const bool is_instant_app,
int64_t activity_start_msec, uint64_t timestampNs) {
auto logEvent = std::make_unique(
- android::util::APP_START_CHANGED, timestampNs);
+ android::util::APP_START_OCCURRED, timestampNs);
logEvent->write(uid);
logEvent->write(pkg_name);
logEvent->write(type);
@@ -112,32 +112,32 @@ TEST(GaugeMetricE2eTest, TestMultipleFieldsForPushedEvent) {
appUid1, bucketStartTimeNs + 2 * bucketSizeNs + 100));
- events.push_back(CreateAppStartChangedEvent(
- appUid1, "app1", AppStartChanged::WARM, "activity_name1", "calling_pkg_name1",
+ events.push_back(CreateAppStartOccurredEvent(
+ appUid1, "app1", AppStartOccurred::WARM, "activity_name1", "calling_pkg_name1",
true /*is_instant_app*/, 101 /*activity_start_msec*/, bucketStartTimeNs + 10));
- events.push_back(CreateAppStartChangedEvent(
- appUid1, "app1", AppStartChanged::HOT, "activity_name2", "calling_pkg_name2",
+ events.push_back(CreateAppStartOccurredEvent(
+ appUid1, "app1", AppStartOccurred::HOT, "activity_name2", "calling_pkg_name2",
true /*is_instant_app*/, 102 /*activity_start_msec*/, bucketStartTimeNs + 20));
- events.push_back(CreateAppStartChangedEvent(
- appUid1, "app1", AppStartChanged::COLD, "activity_name3", "calling_pkg_name3",
+ events.push_back(CreateAppStartOccurredEvent(
+ appUid1, "app1", AppStartOccurred::COLD, "activity_name3", "calling_pkg_name3",
true /*is_instant_app*/, 103 /*activity_start_msec*/, bucketStartTimeNs + 30));
- events.push_back(CreateAppStartChangedEvent(
- appUid1, "app1", AppStartChanged::WARM, "activity_name4", "calling_pkg_name4",
+ events.push_back(CreateAppStartOccurredEvent(
+ appUid1, "app1", AppStartOccurred::WARM, "activity_name4", "calling_pkg_name4",
true /*is_instant_app*/, 104 /*activity_start_msec*/,
bucketStartTimeNs + bucketSizeNs + 30));
- events.push_back(CreateAppStartChangedEvent(
- appUid1, "app1", AppStartChanged::COLD, "activity_name5", "calling_pkg_name5",
+ events.push_back(CreateAppStartOccurredEvent(
+ appUid1, "app1", AppStartOccurred::COLD, "activity_name5", "calling_pkg_name5",
true /*is_instant_app*/, 105 /*activity_start_msec*/,
bucketStartTimeNs + 2 * bucketSizeNs));
- events.push_back(CreateAppStartChangedEvent(
- appUid1, "app1", AppStartChanged::HOT, "activity_name6", "calling_pkg_name6",
+ events.push_back(CreateAppStartOccurredEvent(
+ appUid1, "app1", AppStartOccurred::HOT, "activity_name6", "calling_pkg_name6",
false /*is_instant_app*/, 106 /*activity_start_msec*/,
bucketStartTimeNs + 2 * bucketSizeNs + 10));
events.push_back(CreateMoveToBackgroundEvent(
appUid2, bucketStartTimeNs + bucketSizeNs + 10));
- events.push_back(CreateAppStartChangedEvent(
- appUid2, "app2", AppStartChanged::COLD, "activity_name7", "calling_pkg_name7",
+ events.push_back(CreateAppStartOccurredEvent(
+ appUid2, "app2", AppStartOccurred::COLD, "activity_name7", "calling_pkg_name7",
true /*is_instant_app*/, 201 /*activity_start_msec*/,
bucketStartTimeNs + 2 * bucketSizeNs + 10));
@@ -159,7 +159,7 @@ TEST(GaugeMetricE2eTest, TestMultipleFieldsForPushedEvent) {
EXPECT_EQ(2, gaugeMetrics.data_size());
auto data = gaugeMetrics.data(0);
- EXPECT_EQ(android::util::APP_START_CHANGED, data.dimensions_in_what().field());
+ EXPECT_EQ(android::util::APP_START_OCCURRED, data.dimensions_in_what().field());
EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
EXPECT_EQ(1 /* uid field */,
data.dimensions_in_what().value_tuple().dimensions_value(0).field());
@@ -171,29 +171,29 @@ TEST(GaugeMetricE2eTest, TestMultipleFieldsForPushedEvent) {
EXPECT_EQ(2, data.bucket_info(0).wall_clock_timestamp_nanos_size());
EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_nanos());
EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_nanos());
- EXPECT_EQ(AppStartChanged::HOT, data.bucket_info(0).atom(0).app_start_changed().type());
+ EXPECT_EQ(AppStartOccurred::HOT, data.bucket_info(0).atom(0).app_start_occurred().type());
EXPECT_EQ("activity_name2",
- data.bucket_info(0).atom(0).app_start_changed().activity_name());
+ data.bucket_info(0).atom(0).app_start_occurred().activity_name());
EXPECT_EQ(102L,
- data.bucket_info(0).atom(0).app_start_changed().activity_start_millis());
- EXPECT_EQ(AppStartChanged::COLD,
- data.bucket_info(0).atom(1).app_start_changed().type());
+ data.bucket_info(0).atom(0).app_start_occurred().activity_start_millis());
+ EXPECT_EQ(AppStartOccurred::COLD,
+ data.bucket_info(0).atom(1).app_start_occurred().type());
EXPECT_EQ("activity_name3",
- data.bucket_info(0).atom(1).app_start_changed().activity_name());
+ data.bucket_info(0).atom(1).app_start_occurred().activity_name());
EXPECT_EQ(103L,
- data.bucket_info(0).atom(1).app_start_changed().activity_start_millis());
+ data.bucket_info(0).atom(1).app_start_occurred().activity_start_millis());
EXPECT_EQ(1, data.bucket_info(1).atom_size());
EXPECT_EQ(1, data.bucket_info(1).elapsed_timestamp_nanos_size());
EXPECT_EQ(1, data.bucket_info(1).wall_clock_timestamp_nanos_size());
EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(1).start_bucket_nanos());
EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, data.bucket_info(1).end_bucket_nanos());
- EXPECT_EQ(AppStartChanged::WARM,
- data.bucket_info(1).atom(0).app_start_changed().type());
+ EXPECT_EQ(AppStartOccurred::WARM,
+ data.bucket_info(1).atom(0).app_start_occurred().type());
EXPECT_EQ("activity_name4",
- data.bucket_info(1).atom(0).app_start_changed().activity_name());
+ data.bucket_info(1).atom(0).app_start_occurred().activity_name());
EXPECT_EQ(104L,
- data.bucket_info(1).atom(0).app_start_changed().activity_start_millis());
+ data.bucket_info(1).atom(0).app_start_occurred().activity_start_millis());
EXPECT_EQ(2, data.bucket_info(2).atom_size());
EXPECT_EQ(2, data.bucket_info(2).elapsed_timestamp_nanos_size());
@@ -202,41 +202,41 @@ TEST(GaugeMetricE2eTest, TestMultipleFieldsForPushedEvent) {
data.bucket_info(2).start_bucket_nanos());
EXPECT_EQ(bucketStartTimeNs + 3 * bucketSizeNs,
data.bucket_info(2).end_bucket_nanos());
- EXPECT_EQ(AppStartChanged::COLD,
- data.bucket_info(2).atom(0).app_start_changed().type());
+ EXPECT_EQ(AppStartOccurred::COLD,
+ data.bucket_info(2).atom(0).app_start_occurred().type());
EXPECT_EQ("activity_name5",
- data.bucket_info(2).atom(0).app_start_changed().activity_name());
+ data.bucket_info(2).atom(0).app_start_occurred().activity_name());
EXPECT_EQ(105L,
- data.bucket_info(2).atom(0).app_start_changed().activity_start_millis());
- EXPECT_EQ(AppStartChanged::HOT,
- data.bucket_info(2).atom(1).app_start_changed().type());
+ data.bucket_info(2).atom(0).app_start_occurred().activity_start_millis());
+ EXPECT_EQ(AppStartOccurred::HOT,
+ data.bucket_info(2).atom(1).app_start_occurred().type());
EXPECT_EQ("activity_name6",
- data.bucket_info(2).atom(1).app_start_changed().activity_name());
+ data.bucket_info(2).atom(1).app_start_occurred().activity_name());
EXPECT_EQ(106L,
- data.bucket_info(2).atom(1).app_start_changed().activity_start_millis());
+ data.bucket_info(2).atom(1).app_start_occurred().activity_start_millis());
} else {
EXPECT_EQ(1, data.bucket_info(0).atom_size());
EXPECT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size());
EXPECT_EQ(1, data.bucket_info(0).wall_clock_timestamp_nanos_size());
EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_nanos());
EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_nanos());
- EXPECT_EQ(AppStartChanged::HOT, data.bucket_info(0).atom(0).app_start_changed().type());
+ EXPECT_EQ(AppStartOccurred::HOT, data.bucket_info(0).atom(0).app_start_occurred().type());
EXPECT_EQ("activity_name2",
- data.bucket_info(0).atom(0).app_start_changed().activity_name());
+ data.bucket_info(0).atom(0).app_start_occurred().activity_name());
EXPECT_EQ(102L,
- data.bucket_info(0).atom(0).app_start_changed().activity_start_millis());
+ data.bucket_info(0).atom(0).app_start_occurred().activity_start_millis());
EXPECT_EQ(1, data.bucket_info(1).atom_size());
EXPECT_EQ(1, data.bucket_info(1).elapsed_timestamp_nanos_size());
EXPECT_EQ(1, data.bucket_info(1).wall_clock_timestamp_nanos_size());
EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(1).start_bucket_nanos());
EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, data.bucket_info(1).end_bucket_nanos());
- EXPECT_EQ(AppStartChanged::WARM,
- data.bucket_info(1).atom(0).app_start_changed().type());
+ EXPECT_EQ(AppStartOccurred::WARM,
+ data.bucket_info(1).atom(0).app_start_occurred().type());
EXPECT_EQ("activity_name4",
- data.bucket_info(1).atom(0).app_start_changed().activity_name());
+ data.bucket_info(1).atom(0).app_start_occurred().activity_name());
EXPECT_EQ(104L,
- data.bucket_info(1).atom(0).app_start_changed().activity_start_millis());
+ data.bucket_info(1).atom(0).app_start_occurred().activity_start_millis());
EXPECT_EQ(1, data.bucket_info(2).atom_size());
EXPECT_EQ(1, data.bucket_info(2).elapsed_timestamp_nanos_size());
@@ -245,17 +245,17 @@ TEST(GaugeMetricE2eTest, TestMultipleFieldsForPushedEvent) {
data.bucket_info(2).start_bucket_nanos());
EXPECT_EQ(bucketStartTimeNs + 3 * bucketSizeNs,
data.bucket_info(2).end_bucket_nanos());
- EXPECT_EQ(AppStartChanged::COLD,
- data.bucket_info(2).atom(0).app_start_changed().type());
+ EXPECT_EQ(AppStartOccurred::COLD,
+ data.bucket_info(2).atom(0).app_start_occurred().type());
EXPECT_EQ("activity_name5",
- data.bucket_info(2).atom(0).app_start_changed().activity_name());
+ data.bucket_info(2).atom(0).app_start_occurred().activity_name());
EXPECT_EQ(105L,
- data.bucket_info(2).atom(0).app_start_changed().activity_start_millis());
+ data.bucket_info(2).atom(0).app_start_occurred().activity_start_millis());
}
data = gaugeMetrics.data(1);
- EXPECT_EQ(data.dimensions_in_what().field(), android::util::APP_START_CHANGED);
+ EXPECT_EQ(data.dimensions_in_what().field(), android::util::APP_START_OCCURRED);
EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1);
EXPECT_EQ(1 /* uid field */,
data.dimensions_in_what().value_tuple().dimensions_value(0).field());
@@ -266,10 +266,10 @@ TEST(GaugeMetricE2eTest, TestMultipleFieldsForPushedEvent) {
EXPECT_EQ(1, data.bucket_info(0).wall_clock_timestamp_nanos_size());
EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, data.bucket_info(0).start_bucket_nanos());
EXPECT_EQ(bucketStartTimeNs + 3 * bucketSizeNs, data.bucket_info(0).end_bucket_nanos());
- EXPECT_EQ(AppStartChanged::COLD, data.bucket_info(0).atom(0).app_start_changed().type());
+ EXPECT_EQ(AppStartOccurred::COLD, data.bucket_info(0).atom(0).app_start_occurred().type());
EXPECT_EQ("activity_name7",
- data.bucket_info(0).atom(0).app_start_changed().activity_name());
- EXPECT_EQ(201L, data.bucket_info(0).atom(0).app_start_changed().activity_start_millis());
+ data.bucket_info(0).atom(0).app_start_occurred().activity_name());
+ EXPECT_EQ(201L, data.bucket_info(0).atom(0).app_start_occurred().activity_start_millis());
}
}
diff --git a/cmds/statsd/tests/guardrail/StatsdStats_test.cpp b/cmds/statsd/tests/guardrail/StatsdStats_test.cpp
index 5c4eda8348d104c46c7f4d8d0842152f895e55ff..04ce73a76d3b2a90b8d33d21f019e62ecec600e8 100644
--- a/cmds/statsd/tests/guardrail/StatsdStats_test.cpp
+++ b/cmds/statsd/tests/guardrail/StatsdStats_test.cpp
@@ -210,7 +210,7 @@ TEST(StatsdStatsTest, TestAtomLog) {
stats.noteAtomLogged(android::util::SENSOR_STATE_CHANGED, now + 1);
stats.noteAtomLogged(android::util::SENSOR_STATE_CHANGED, now + 2);
- stats.noteAtomLogged(android::util::DROPBOX_ERROR_CHANGED, now + 3);
+ stats.noteAtomLogged(android::util::APP_CRASH_OCCURRED, now + 3);
// pulled event, should ignore
stats.noteAtomLogged(android::util::WIFI_BYTES_TRANSFER, now + 4);
@@ -228,7 +228,7 @@ TEST(StatsdStatsTest, TestAtomLog) {
if (atomStats.tag() == android::util::SENSOR_STATE_CHANGED && atomStats.count() == 3) {
sensorAtomGood = true;
}
- if (atomStats.tag() == android::util::DROPBOX_ERROR_CHANGED && atomStats.count() == 1) {
+ if (atomStats.tag() == android::util::APP_CRASH_OCCURRED && atomStats.count() == 1) {
dropboxAtomGood = true;
}
}
diff --git a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp b/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
index 2583c95b2016979e3d30a13592862ab5241e6e2e..7ca66fd361c204cb700240abf3a731f78e3eee62 100644
--- a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
@@ -63,7 +63,7 @@ TEST(GaugeMetricProducerTest, TestNoCondition) {
// For now we still need this so that it doesn't do real pulling.
shared_ptr pullerManager =
make_shared>();
- EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _)).WillOnce(Return());
+ EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
@@ -213,10 +213,11 @@ TEST(GaugeMetricProducerTest, TestPulledWithUpgrade) {
shared_ptr pullerManager =
make_shared>();
- EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _)).WillOnce(Return());
+ EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, Pull(tagId, _))
- .WillOnce(Invoke([](int tagId, vector>* data) {
+ EXPECT_CALL(*pullerManager, Pull(tagId, _, _))
+ .WillOnce(Invoke([](int tagId, int64_t timeNs,
+ vector>* data) {
data->clear();
shared_ptr event = make_shared(tagId, eventUpgradeTimeNs);
event->write("some value");
@@ -281,10 +282,11 @@ TEST(GaugeMetricProducerTest, TestWithCondition) {
shared_ptr pullerManager =
make_shared>();
- EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _)).WillOnce(Return());
+ EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, Pull(tagId, _))
- .WillOnce(Invoke([](int tagId, vector>* data) {
+ EXPECT_CALL(*pullerManager, Pull(tagId, _, _))
+ .WillOnce(Invoke([](int tagId, int64_t timeNs,
+ vector>* data) {
data->clear();
shared_ptr event = make_shared(tagId, bucketStartTimeNs + 10);
event->write("some value");
@@ -372,10 +374,11 @@ TEST(GaugeMetricProducerTest, TestWithSlicedCondition) {
shared_ptr pullerManager =
make_shared>();
- EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _)).WillOnce(Return());
+ EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, Pull(tagId, _))
- .WillOnce(Invoke([](int tagId, vector>* data) {
+ EXPECT_CALL(*pullerManager, Pull(tagId, _, _))
+ .WillOnce(Invoke([](int tagId, int64_t timeNs,
+ vector>* data) {
data->clear();
shared_ptr event = make_shared(tagId, bucketStartTimeNs + 10);
event->write(1000);
@@ -420,7 +423,7 @@ TEST(GaugeMetricProducerTest, TestAnomalyDetection) {
shared_ptr pullerManager =
make_shared>();
- EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _)).WillOnce(Return());
+ EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
GaugeMetric metric;
diff --git a/cmds/statsd/tests/metrics/MaxDurationTracker_test.cpp b/cmds/statsd/tests/metrics/MaxDurationTracker_test.cpp
index 57a8925a122e3db3ef488e80a7d5faaf73c4500c..a0f1c00b7b48697615a30d4c9e6ea2e940b496c5 100644
--- a/cmds/statsd/tests/metrics/MaxDurationTracker_test.cpp
+++ b/cmds/statsd/tests/metrics/MaxDurationTracker_test.cpp
@@ -344,8 +344,37 @@ TEST(MaxDurationTrackerTest, TestAnomalyPredictedTimestamp) {
tracker.noteConditionChanged(key1, true, conditionStarts2);
EXPECT_EQ(1U, anomalyTracker->mAlarms.size());
auto alarm = anomalyTracker->mAlarms.begin()->second;
+ uint64_t anomalyFireTimeSec = alarm->timestampSec;
EXPECT_EQ(conditionStarts2 + 36 * NS_PER_SEC,
- (unsigned long long)(alarm->timestampSec * NS_PER_SEC));
+ (unsigned long long)anomalyFireTimeSec * NS_PER_SEC);
+
+ // Now we test the calculation now that there's a refractory period.
+ // At the correct time, declare the anomaly. This will set a refractory period. Make sure it
+ // gets correctly taken into account in future predictAnomalyTimestampNs calculations.
+ std::unordered_set, SpHash> firedAlarms({alarm});
+ anomalyTracker->informAlarmsFired(anomalyFireTimeSec * NS_PER_SEC, firedAlarms);
+ EXPECT_EQ(0u, anomalyTracker->mAlarms.size());
+ uint64_t refractoryPeriodEndsSec = anomalyFireTimeSec + refPeriodSec;
+ EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(eventKey), refractoryPeriodEndsSec);
+
+ // Now stop and start again. Make sure the new predictAnomalyTimestampNs takes into account
+ // the refractory period correctly.
+ uint64_t eventStopTimeNs = anomalyFireTimeSec * NS_PER_SEC + 10;
+ tracker.noteStop(key1, eventStopTimeNs, false);
+ tracker.noteStop(key2, eventStopTimeNs, false);
+ tracker.noteStart(key1, true, eventStopTimeNs + 1000000, conditionKey1);
+ // Anomaly is ongoing, but we're still in the refractory period.
+ EXPECT_EQ(1U, anomalyTracker->mAlarms.size());
+ alarm = anomalyTracker->mAlarms.begin()->second;
+ EXPECT_EQ(refractoryPeriodEndsSec, (unsigned long long)(alarm->timestampSec));
+
+ // Makes sure it is correct after the refractory period is over.
+ tracker.noteStop(key1, eventStopTimeNs + 2000000, false);
+ uint64_t justBeforeRefPeriodNs = (refractoryPeriodEndsSec - 2) * NS_PER_SEC;
+ tracker.noteStart(key1, true, justBeforeRefPeriodNs, conditionKey1);
+ alarm = anomalyTracker->mAlarms.begin()->second;
+ EXPECT_EQ(justBeforeRefPeriodNs + 40 * NS_PER_SEC,
+ (unsigned long long)(alarm->timestampSec * NS_PER_SEC));
}
// Suppose that within one tracker there are two dimensions A and B.
diff --git a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
index a8eb27037ebf0294a005a0ab39a12f6e98b87d2e..c650a06fdbe1d59ec26921196a4d8b4bf98ba535 100644
--- a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
@@ -45,6 +45,8 @@ const int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000L
const int64_t bucket2StartTimeNs = bucketStartTimeNs + bucketSizeNs;
const int64_t bucket3StartTimeNs = bucketStartTimeNs + 2 * bucketSizeNs;
const int64_t bucket4StartTimeNs = bucketStartTimeNs + 3 * bucketSizeNs;
+const int64_t bucket5StartTimeNs = bucketStartTimeNs + 4 * bucketSizeNs;
+const int64_t bucket6StartTimeNs = bucketStartTimeNs + 5 * bucketSizeNs;
const int64_t eventUpgradeTimeNs = bucketStartTimeNs + 15 * NS_PER_SEC;
/*
@@ -62,7 +64,7 @@ TEST(ValueMetricProducerTest, TestNonDimensionalEvents) {
// For now we still need this so that it doesn't do real pulling.
shared_ptr pullerManager =
make_shared>();
- EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _)).WillOnce(Return());
+ EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
@@ -141,11 +143,12 @@ TEST(ValueMetricProducerTest, TestEventsWithNonSlicedCondition) {
sp wizard = new NaggyMock();
shared_ptr pullerManager =
make_shared>();
- EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _)).WillOnce(Return());
+ EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
- EXPECT_CALL(*pullerManager, Pull(tagId, _))
- .WillOnce(Invoke([](int tagId, vector>* data) {
+ EXPECT_CALL(*pullerManager, Pull(tagId, _, _))
+ .WillOnce(Invoke([](int tagId, int64_t timeNs,
+ vector>* data) {
data->clear();
shared_ptr event = make_shared(tagId, bucketStartTimeNs + 10);
event->write(tagId);
@@ -154,7 +157,8 @@ TEST(ValueMetricProducerTest, TestEventsWithNonSlicedCondition) {
data->push_back(event);
return true;
}))
- .WillOnce(Invoke([](int tagId, vector>* data) {
+ .WillOnce(Invoke([](int tagId, int64_t timeNs,
+ vector>* data) {
data->clear();
shared_ptr event = make_shared(tagId, bucket2StartTimeNs + 10);
event->write(tagId);
@@ -260,10 +264,11 @@ TEST(ValueMetricProducerTest, TestPulledValueWithUpgrade) {
sp wizard = new NaggyMock();
shared_ptr pullerManager =
make_shared>();
- EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _)).WillOnce(Return());
+ EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, Pull(tagId, _))
- .WillOnce(Invoke([](int tagId, vector>* data) {
+ EXPECT_CALL(*pullerManager, Pull(tagId, _, _))
+ .WillOnce(Invoke([](int tagId, int64_t timeNs,
+ vector>* data) {
data->clear();
shared_ptr event = make_shared(tagId, bucketStartTimeNs + 10);
event->write(tagId);
@@ -428,6 +433,376 @@ TEST(ValueMetricProducerTest, TestAnomalyDetection) {
std::ceil(1.0 * event6->GetElapsedTimestampNs() / NS_PER_SEC + refPeriodSec));
}
+// Test value metric no condition, the pull on bucket boundary come in time and too late
+TEST(ValueMetricProducerTest, TestBucketBoundaryNoCondition) {
+ ValueMetric metric;
+ metric.set_id(metricId);
+ metric.set_bucket(ONE_MINUTE);
+ metric.mutable_value_field()->set_field(tagId);
+ metric.mutable_value_field()->add_child()->set_field(2);
+
+ sp wizard = new NaggyMock();
+ shared_ptr pullerManager =
+ make_shared>();
+ EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
+ EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
+
+ ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
+ tagId, bucketStartTimeNs, pullerManager);
+ valueProducer.setBucketSize(60 * NS_PER_SEC);
+
+ vector> allData;
+ // pull 1
+ allData.clear();
+ shared_ptr event = make_shared(tagId, bucket2StartTimeNs + 1);
+ event->write(tagId);
+ event->write(11);
+ event->init();
+ allData.push_back(event);
+
+ valueProducer.onDataPulled(allData);
+ // has one slice
+ EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+ ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+ valueProducer.setBucketSize(60 * NS_PER_SEC);
+
+ // startUpdated:true tainted:0 sum:0 start:11
+ EXPECT_EQ(true, curInterval.startUpdated);
+ EXPECT_EQ(0, curInterval.tainted);
+ EXPECT_EQ(0, curInterval.sum);
+ EXPECT_EQ(11, curInterval.start);
+ EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
+ EXPECT_EQ(0, valueProducer.mPastBuckets.begin()->second.back().mValue);
+
+ // pull 2 at correct time
+ allData.clear();
+ event = make_shared(tagId, bucket3StartTimeNs + 1);
+ event->write(tagId);
+ event->write(23);
+ event->init();
+ allData.push_back(event);
+ valueProducer.onDataPulled(allData);
+ // has one slice
+ EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+ // tartUpdated:false tainted:0 sum:12
+ EXPECT_EQ(true, curInterval.startUpdated);
+ EXPECT_EQ(0, curInterval.tainted);
+ EXPECT_EQ(0, curInterval.sum);
+ EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
+ EXPECT_EQ(2UL, valueProducer.mPastBuckets.begin()->second.size());
+ EXPECT_EQ(12, valueProducer.mPastBuckets.begin()->second.back().mValue);
+
+ // pull 3 come late.
+ // The previous bucket gets closed with error. (Has start value 23, no ending)
+ // Another bucket gets closed with error. (No start, but ending with 36)
+ // The new bucket is back to normal.
+ allData.clear();
+ event = make_shared(tagId, bucket6StartTimeNs + 1);
+ event->write(tagId);
+ event->write(36);
+ event->init();
+ allData.push_back(event);
+ valueProducer.onDataPulled(allData);
+ EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+ // startUpdated:false tainted:0 sum:12
+ EXPECT_EQ(true, curInterval.startUpdated);
+ EXPECT_EQ(0, curInterval.tainted);
+ EXPECT_EQ(36, curInterval.start);
+ EXPECT_EQ(0, curInterval.sum);
+ EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
+ EXPECT_EQ(4UL, valueProducer.mPastBuckets.begin()->second.size());
+ EXPECT_EQ(0, valueProducer.mPastBuckets.begin()->second[0].mValue);
+ EXPECT_EQ(12, valueProducer.mPastBuckets.begin()->second[1].mValue);
+ EXPECT_EQ(0, valueProducer.mPastBuckets.begin()->second[2].mValue);
+ EXPECT_EQ(0, valueProducer.mPastBuckets.begin()->second[3].mValue);
+}
+
+/*
+ * Test pulled event with non sliced condition. The pull on boundary come late because the alarm
+ * was delivered late.
+ */
+TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition) {
+ ValueMetric metric;
+ metric.set_id(metricId);
+ metric.set_bucket(ONE_MINUTE);
+ metric.mutable_value_field()->set_field(tagId);
+ metric.mutable_value_field()->add_child()->set_field(2);
+ metric.set_condition(StringToId("SCREEN_ON"));
+
+ sp wizard = new NaggyMock();
+ shared_ptr pullerManager =
+ make_shared>();
+ EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
+ EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
+
+ EXPECT_CALL(*pullerManager, Pull(tagId, _, _))
+ // condition becomes true
+ .WillOnce(Invoke([](int tagId, int64_t timeNs,
+ vector>* data) {
+ data->clear();
+ shared_ptr event = make_shared(tagId, bucketStartTimeNs + 10);
+ event->write(tagId);
+ event->write(100);
+ event->init();
+ data->push_back(event);
+ return true;
+ }))
+ // condition becomes false
+ .WillOnce(Invoke([](int tagId, int64_t timeNs,
+ vector>* data) {
+ data->clear();
+ shared_ptr event = make_shared(tagId, bucket2StartTimeNs + 20);
+ event->write(tagId);
+ event->write(120);
+ event->init();
+ data->push_back(event);
+ return true;
+ }));
+
+ ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, tagId, bucketStartTimeNs,
+ pullerManager);
+ valueProducer.setBucketSize(60 * NS_PER_SEC);
+ valueProducer.onConditionChanged(true, bucketStartTimeNs + 8);
+
+ // has one slice
+ EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+ ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+ // startUpdated:false tainted:0 sum:0 start:100
+ EXPECT_EQ(100, curInterval.start);
+ EXPECT_EQ(true, curInterval.startUpdated);
+ EXPECT_EQ(0, curInterval.tainted);
+ EXPECT_EQ(0, curInterval.sum);
+ EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
+
+ // pull on bucket boundary come late, condition change happens before it
+ valueProducer.onConditionChanged(false, bucket2StartTimeNs + 1);
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+ EXPECT_EQ(false, curInterval.startUpdated);
+ EXPECT_EQ(1, curInterval.tainted);
+ EXPECT_EQ(0, curInterval.sum);
+ EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
+ EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
+ EXPECT_EQ(0, valueProducer.mPastBuckets.begin()->second[0].mValue);
+
+ // Now the alarm is delivered.
+ // since the condition turned to off before this pull finish, it has no effect
+ vector> allData;
+ allData.clear();
+ shared_ptr event = make_shared(tagId, bucket2StartTimeNs + 30);
+ event->write(1);
+ event->write(110);
+ event->init();
+ allData.push_back(event);
+ valueProducer.onDataPulled(allData);
+
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+ EXPECT_EQ(false, curInterval.startUpdated);
+ EXPECT_EQ(1, curInterval.tainted);
+ EXPECT_EQ(0, curInterval.sum);
+ EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
+ EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
+ EXPECT_EQ(0, valueProducer.mPastBuckets.begin()->second[0].mValue);
+}
+
+/*
+ * Test pulled event with non sliced condition. The pull on boundary come late, after the condition
+ * change to false, and then true again. This is due to alarm delivered late.
+ */
+TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition2) {
+ ValueMetric metric;
+ metric.set_id(metricId);
+ metric.set_bucket(ONE_MINUTE);
+ metric.mutable_value_field()->set_field(tagId);
+ metric.mutable_value_field()->add_child()->set_field(2);
+ metric.set_condition(StringToId("SCREEN_ON"));
+
+ sp wizard = new NaggyMock();
+ shared_ptr pullerManager =
+ make_shared>();
+ EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillRepeatedly(Return());
+ EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
+
+ EXPECT_CALL(*pullerManager, Pull(tagId, _, _))
+ // condition becomes true
+ .WillOnce(Invoke([](int tagId, int64_t timeNs,
+ vector>* data) {
+ data->clear();
+ shared_ptr event = make_shared(tagId, bucketStartTimeNs + 10);
+ event->write(tagId);
+ event->write(100);
+ event->init();
+ data->push_back(event);
+ return true;
+ }))
+ // condition becomes false
+ .WillOnce(Invoke([](int tagId, int64_t timeNs,
+ vector>* data) {
+ data->clear();
+ shared_ptr event = make_shared(tagId, bucket2StartTimeNs + 20);
+ event->write(tagId);
+ event->write(120);
+ event->init();
+ data->push_back(event);
+ return true;
+ }))
+ // condition becomes true again
+ .WillOnce(Invoke([](int tagId, int64_t timeNs,
+ vector>* data) {
+ data->clear();
+ shared_ptr event = make_shared(tagId, bucket2StartTimeNs + 30);
+ event->write(tagId);
+ event->write(130);
+ event->init();
+ data->push_back(event);
+ return true;
+ }));
+
+ ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, tagId, bucketStartTimeNs,
+ pullerManager);
+ valueProducer.setBucketSize(60 * NS_PER_SEC);
+ valueProducer.onConditionChanged(true, bucketStartTimeNs + 8);
+
+ // has one slice
+ EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+ ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+ // startUpdated:false tainted:0 sum:0 start:100
+ EXPECT_EQ(100, curInterval.start);
+ EXPECT_EQ(true, curInterval.startUpdated);
+ EXPECT_EQ(0, curInterval.tainted);
+ EXPECT_EQ(0, curInterval.sum);
+ EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
+
+ // pull on bucket boundary come late, condition change happens before it
+ valueProducer.onConditionChanged(false, bucket2StartTimeNs + 1);
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+ EXPECT_EQ(false, curInterval.startUpdated);
+ EXPECT_EQ(1, curInterval.tainted);
+ EXPECT_EQ(0, curInterval.sum);
+ EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
+ EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
+ EXPECT_EQ(0, valueProducer.mPastBuckets.begin()->second[0].mValue);
+
+ // condition changed to true again, before the pull alarm is delivered
+ valueProducer.onConditionChanged(true, bucket2StartTimeNs + 25);
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+ EXPECT_EQ(true, curInterval.startUpdated);
+ EXPECT_EQ(130, curInterval.start);
+ EXPECT_EQ(1, curInterval.tainted);
+ EXPECT_EQ(0, curInterval.sum);
+ EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
+ EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
+ EXPECT_EQ(0, valueProducer.mPastBuckets.begin()->second[0].mValue);
+
+ // Now the alarm is delivered, but it is considered late, it has no effect
+ vector> allData;
+ allData.clear();
+ shared_ptr event = make_shared(tagId, bucket2StartTimeNs + 50);
+ event->write(1);
+ event->write(110);
+ event->init();
+ allData.push_back(event);
+ valueProducer.onDataPulled(allData);
+
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+ EXPECT_EQ(true, curInterval.startUpdated);
+ EXPECT_EQ(130, curInterval.start);
+ EXPECT_EQ(1, curInterval.tainted);
+ EXPECT_EQ(0, curInterval.sum);
+ EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
+ EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
+ EXPECT_EQ(0, valueProducer.mPastBuckets.begin()->second[0].mValue);
+}
+
+/*
+ * Test pulled event with non sliced condition. The pull on boundary come late because the puller is
+ * very slow.
+ */
+TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition3) {
+ ValueMetric metric;
+ metric.set_id(metricId);
+ metric.set_bucket(ONE_MINUTE);
+ metric.mutable_value_field()->set_field(tagId);
+ metric.mutable_value_field()->add_child()->set_field(2);
+ metric.set_condition(StringToId("SCREEN_ON"));
+
+ sp wizard = new NaggyMock();
+ shared_ptr pullerManager =
+ make_shared>();
+ EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
+ EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
+
+ EXPECT_CALL(*pullerManager, Pull(tagId, _, _))
+ // condition becomes true
+ .WillOnce(Invoke([](int tagId, int64_t timeNs,
+ vector>* data) {
+ data->clear();
+ shared_ptr event = make_shared(tagId, bucketStartTimeNs + 10);
+ event->write(tagId);
+ event->write(100);
+ event->init();
+ data->push_back(event);
+ return true;
+ }))
+ // condition becomes false
+ .WillOnce(Invoke([](int tagId, int64_t timeNs,
+ vector>* data) {
+ data->clear();
+ shared_ptr event = make_shared(tagId, bucket3StartTimeNs + 20);
+ event->write(tagId);
+ event->write(120);
+ event->init();
+ data->push_back(event);
+ return true;
+ }));
+
+ ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, tagId, bucketStartTimeNs,
+ pullerManager);
+ valueProducer.setBucketSize(60 * NS_PER_SEC);
+ valueProducer.onConditionChanged(true, bucketStartTimeNs + 8);
+
+ // has one slice
+ EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+ ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+ // startUpdated:false tainted:0 sum:0 start:100
+ EXPECT_EQ(100, curInterval.start);
+ EXPECT_EQ(true, curInterval.startUpdated);
+ EXPECT_EQ(0, curInterval.tainted);
+ EXPECT_EQ(0, curInterval.sum);
+ EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
+
+ // pull on bucket boundary come late, condition change happens before it.
+ // But puller is very slow in this one, so the data come after bucket finish
+ valueProducer.onConditionChanged(false, bucket2StartTimeNs + 1);
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+ EXPECT_EQ(false, curInterval.startUpdated);
+ EXPECT_EQ(1, curInterval.tainted);
+ EXPECT_EQ(0, curInterval.sum);
+ EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
+ EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
+ EXPECT_EQ(0, valueProducer.mPastBuckets.begin()->second[0].mValue);
+
+ // Alarm is delivered in time, but the pull is very slow, and pullers are called in order,
+ // so this one comes even later
+ vector> allData;
+ allData.clear();
+ shared_ptr event = make_shared(tagId, bucket3StartTimeNs + 30);
+ event->write(1);
+ event->write(110);
+ event->init();
+ allData.push_back(event);
+ valueProducer.onDataPulled(allData);
+
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+ EXPECT_EQ(false, curInterval.startUpdated);
+ EXPECT_EQ(1, curInterval.tainted);
+ EXPECT_EQ(0, curInterval.sum);
+ EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
+ EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
+ EXPECT_EQ(0, valueProducer.mPastBuckets.begin()->second[0].mValue);
+}
+
} // namespace statsd
} // namespace os
} // namespace android
diff --git a/cmds/statsd/tests/metrics/metrics_test_helper.h b/cmds/statsd/tests/metrics/metrics_test_helper.h
index f040bf9f37aea819cf7fa321f1c74af4cb9d668d..5afaba6671fabf9959a8f0d31183a782aa360342 100644
--- a/cmds/statsd/tests/metrics/metrics_test_helper.h
+++ b/cmds/statsd/tests/metrics/metrics_test_helper.h
@@ -35,9 +35,11 @@ public:
class MockStatsPullerManager : public StatsPullerManager {
public:
- MOCK_METHOD3(RegisterReceiver, void(int tagId, wp receiver, long intervalMs));
+ MOCK_METHOD4(RegisterReceiver, void(int tagId, wp receiver,
+ int64_t nextPulltimeNs, int64_t intervalNs));
MOCK_METHOD2(UnRegisterReceiver, void(int tagId, wp receiver));
- MOCK_METHOD2(Pull, bool(const int pullCode, vector>* data));
+ MOCK_METHOD3(Pull, bool(const int pullCode, const int64_t timeNs,
+ vector>* data));
};
class MockUidMap : public UidMap {
diff --git a/cmds/statsd/tests/statsd_test_util.cpp b/cmds/statsd/tests/statsd_test_util.cpp
index ce44a35cbf21292ceaa4c35e135af8a74a206f74..d0840f050723744a4aa9562a95fa916545457b06 100644
--- a/cmds/statsd/tests/statsd_test_util.cpp
+++ b/cmds/statsd/tests/statsd_test_util.cpp
@@ -152,42 +152,42 @@ AtomMatcher CreateSyncEndAtomMatcher() {
}
AtomMatcher CreateActivityForegroundStateChangedAtomMatcher(
- const string& name, ActivityForegroundStateChanged::Activity activity) {
+ const string& name, ActivityForegroundStateChanged::State state) {
AtomMatcher atom_matcher;
atom_matcher.set_id(StringToId(name));
auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
simple_atom_matcher->set_atom_id(android::util::ACTIVITY_FOREGROUND_STATE_CHANGED);
auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
field_value_matcher->set_field(4); // Activity field.
- field_value_matcher->set_eq_int(activity);
+ field_value_matcher->set_eq_int(state);
return atom_matcher;
}
AtomMatcher CreateMoveToBackgroundAtomMatcher() {
return CreateActivityForegroundStateChangedAtomMatcher(
- "MoveToBackground", ActivityForegroundStateChanged::MOVE_TO_BACKGROUND);
+ "Background", ActivityForegroundStateChanged::BACKGROUND);
}
AtomMatcher CreateMoveToForegroundAtomMatcher() {
return CreateActivityForegroundStateChangedAtomMatcher(
- "MoveToForeground", ActivityForegroundStateChanged::MOVE_TO_FOREGROUND);
+ "Foreground", ActivityForegroundStateChanged::FOREGROUND);
}
AtomMatcher CreateProcessLifeCycleStateChangedAtomMatcher(
- const string& name, ProcessLifeCycleStateChanged::Event event) {
+ const string& name, ProcessLifeCycleStateChanged::State state) {
AtomMatcher atom_matcher;
atom_matcher.set_id(StringToId(name));
auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
simple_atom_matcher->set_atom_id(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
field_value_matcher->set_field(3); // Process state field.
- field_value_matcher->set_eq_int(event);
+ field_value_matcher->set_eq_int(state);
return atom_matcher;
}
AtomMatcher CreateProcessCrashAtomMatcher() {
return CreateProcessLifeCycleStateChangedAtomMatcher(
- "ProcessCrashed", ProcessLifeCycleStateChanged::PROCESS_CRASHED);
+ "Crashed", ProcessLifeCycleStateChanged::CRASHED);
}
Predicate CreateScheduledJobPredicate() {
@@ -241,8 +241,8 @@ Predicate CreateIsSyncingPredicate() {
Predicate CreateIsInBackgroundPredicate() {
Predicate predicate;
predicate.set_id(StringToId("IsInBackground"));
- predicate.mutable_simple_predicate()->set_start(StringToId("MoveToBackground"));
- predicate.mutable_simple_predicate()->set_stop(StringToId("MoveToForeground"));
+ predicate.mutable_simple_predicate()->set_start(StringToId("Background"));
+ predicate.mutable_simple_predicate()->set_stop(StringToId("Foreground"));
return predicate;
}
@@ -373,25 +373,25 @@ std::unique_ptr CreateReleaseWakelockEvent(
}
std::unique_ptr CreateActivityForegroundStateChangedEvent(
- const int uid, const ActivityForegroundStateChanged::Activity activity, uint64_t timestampNs) {
+ const int uid, const ActivityForegroundStateChanged::State state, uint64_t timestampNs) {
auto event = std::make_unique(
android::util::ACTIVITY_FOREGROUND_STATE_CHANGED, timestampNs);
event->write(uid);
event->write("pkg_name");
event->write("class_name");
- event->write(activity);
+ event->write(state);
event->init();
return event;
}
std::unique_ptr CreateMoveToBackgroundEvent(const int uid, uint64_t timestampNs) {
return CreateActivityForegroundStateChangedEvent(
- uid, ActivityForegroundStateChanged::MOVE_TO_BACKGROUND, timestampNs);
+ uid, ActivityForegroundStateChanged::BACKGROUND, timestampNs);
}
std::unique_ptr CreateMoveToForegroundEvent(const int uid, uint64_t timestampNs) {
return CreateActivityForegroundStateChangedEvent(
- uid, ActivityForegroundStateChanged::MOVE_TO_FOREGROUND, timestampNs);
+ uid, ActivityForegroundStateChanged::FOREGROUND, timestampNs);
}
std::unique_ptr CreateSyncStateChangedEvent(
@@ -418,19 +418,19 @@ std::unique_ptr CreateSyncEndEvent(
}
std::unique_ptr CreateProcessLifeCycleStateChangedEvent(
- const int uid, const ProcessLifeCycleStateChanged::Event event, uint64_t timestampNs) {
+ const int uid, const ProcessLifeCycleStateChanged::State state, uint64_t timestampNs) {
auto logEvent = std::make_unique(
android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED, timestampNs);
logEvent->write(uid);
logEvent->write("");
- logEvent->write(event);
+ logEvent->write(state);
logEvent->init();
return logEvent;
}
std::unique_ptr CreateAppCrashEvent(const int uid, uint64_t timestampNs) {
return CreateProcessLifeCycleStateChangedEvent(
- uid, ProcessLifeCycleStateChanged::PROCESS_CRASHED, timestampNs);
+ uid, ProcessLifeCycleStateChanged::CRASHED, timestampNs);
}
std::unique_ptr CreateIsolatedUidChangedEvent(
@@ -450,7 +450,9 @@ sp CreateStatsLogProcessor(const long timeBaseSec, const Stat
sp anomalyAlarmMonitor =
new AlarmMonitor(1, [](const sp&, int64_t){},
[](const sp&){});
- sp periodicAlarmMonitor;
+ sp periodicAlarmMonitor =
+ new AlarmMonitor(1, [](const sp&, int64_t){},
+ [](const sp&){});
sp