diff options
20 files changed, 1103 insertions, 390 deletions
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto index 22166337cb42..052358bb8397 100644 --- a/cmds/statsd/src/atoms.proto +++ b/cmds/statsd/src/atoms.proto @@ -450,13 +450,28 @@ message Atom { TvCasSessionOpenStatus tv_cas_session_open_status = 280 [(module) = "framework"]; AssistantInvocationReported assistant_invocation_reported = 281 [(module) = "framework"]; + DisplayWakeReported display_wake_reported = 282 [(module) = "framework"]; + CarUserHalModifyUserRequestReported car_user_hal_modify_user_request_reported = + 283 [(module) = "car"]; + CarUserHalModifyUserResponseReported car_user_hal_modify_user_response_reported = + 284 [(module) = "car"]; + CarUserHalPostSwitchResponseReported car_user_hal_post_switch_response_reported = + 285 [(module) = "car"]; + CarUserHalInitialUserInfoRequestReported car_user_hal_initial_user_info_request_reported = + 286 [(module) = "car"]; + CarUserHalInitialUserInfoResponseReported car_user_hal_initial_user_info_response_reported = + 287 [(module) = "car"]; + CarUserHalUserAssociationRequestReported car_user_hal_user_association_request_reported = + 288 [(module) = "car"]; + CarUserHalSetUserAssociationResponseReported car_user_hal_set_user_association_response_reported = + 289 [(module) = "car"]; // StatsdStats tracks platform atoms with ids upto 500. // Update StatsdStats::kMaxPushedAtomId when atom ids here approach that value. } // Pulled events will start at field 10000. - // Next: 10084 + // Next: 10081 oneof pulled { WifiBytesTransfer wifi_bytes_transfer = 10000 [(module) = "framework"]; WifiBytesTransferByFgBg wifi_bytes_transfer_by_fg_bg = 10001 [(module) = "framework"]; @@ -547,7 +562,7 @@ message Atom { SimSlotState sim_slot_state = 10078 [(module) = "telephony"]; SupportedRadioAccessFamily supported_radio_access_family = 10079 [(module) = "telephony"]; SettingSnapshot setting_snapshot = 10080 [(module) = "framework"]; - DisplayWakeReason display_wake_reason = 10081 [(module) = "framework"]; + //10081 free for use DataUsageBytesTransfer data_usage_bytes_transfer = 10082 [(module) = "framework"]; BytesTransferByTagAndMetered bytes_transfer_by_tag_and_metered = 10083 [(module) = "framework"]; @@ -8001,6 +8016,245 @@ message CarPowerStateChanged { } /** + * Logs when Car User Hal is requested to switch/create/remove user. + * + * Logged from: + * packages/services/Car/service/src/com/android/car/hal/UserHalService.java + */ +message CarUserHalModifyUserRequestReported { + // Request id for the request. + optional int32 request_id = 1; + // Request type. + enum RequestType { + UNKNOWN = 0; + // Car user manager requested user switch. + SWITCH_REQUEST_ANDROID = 1; + // OEM requested User switch. + SWITCH_REQUEST_OEM = 2; + // Hal switch requested after android switch using activity manager. + SWITCH_REQUEST_LEGACY = 3; + // Create User + CREATE_REQUEST = 4; + // Remove User + REMOVE_REQUEST = 5; + } + optional RequestType request_type = 2; + // Android User id of the current user which can only be 0, 10, 11 and so on. + // -1 if not available. + optional int32 user_id = 3; + // VHAL flags of the current user. (-1 if not available) + optional int32 user_flags = 4; + // Android User id of the target user for switch/create/remove. It can only + // be 0, 10, 11 and so on. -1 if not available. + optional int32 target_user_id = 5; + // VHAL flags of the target user for switch/create/remove. (-1 if not available) + optional int32 target_user_flags = 6; + // Request timeout Milliseconds (-1 if not available) + optional int32 timeout_millis = 7; +} + +/** + * Logs when Car User Hal responds to switch/create user request. + * + * Logged from: + * packages/services/Car/service/src/com/android/car/hal/UserHalService.java + */ +message CarUserHalModifyUserResponseReported { + // Request id of the request associated with the response. + optional int32 request_id = 1; + // Car user hal callback status. + enum CallbackStatus { + UNKNOWN = 0; + // Hal response was invalid. + INVALID = 1; + // Hal response was ok. + OK = 2; + // Hal timeout during set call. + HAL_SET_TIMEOUT = 3; + // Hal response timeout. + HAL_RESPONSE_TIMEOUT = 4; + // Hal responded with wrong info. + WRONG_HAL_RESPONSE = 5; + // Hal is processing multiple requests simultaneously. + CONCURRENT_OPERATION = 6; + } + optional CallbackStatus callback_status = 2; + + // Hal request status for user switch/create/remove. + enum HalRequestStatus { + UNSPECIFIED = 0; + // Hal request for user switch/create is successful. + SUCCESS = 1; + // Hal request for user switch/create failed. + FAILURE = 2; + } + optional HalRequestStatus request_status = 3; +} + +/** + * Logs when post switch response is posted to Car User Hal. + * + * Logged from: + * packages/services/Car/service/src/com/android/car/hal/UserHalService.java + */ +message CarUserHalPostSwitchResponseReported { + // Request id. + optional int32 request_id = 1; + + // Android user switch status. + enum UserSwitchStatus { + UNKNOWN = 0; + // Android user switch is successful. + SUCCESS = 1; + // Android user switch failed. + FAILURE = 2; + } + optional UserSwitchStatus switch_status = 2; +} + +/** + * Logs when initial user information is requested from Car User Hal. + * + * Logged from: + * packages/services/Car/service/src/com/android/car/hal/UserHalService.java + */ +message CarUserHalInitialUserInfoRequestReported { + // Request id for the request. + optional int32 request_id = 1; + + // Request type for initial user information. + enum InitialUserInfoRequestType { + UNKNOWN = 0; + // At the first time Android was booted (or after a factory reset). + FIRST_BOOT = 1; + // At the first time Android was booted after the system was updated. + FIRST_BOOT_AFTER_OTA = 2; + // When Android was booted "from scratch". + COLD_BOOT = 3; + // When Android was resumed after the system was suspended to memory. + RESUME = 4; + } + optional InitialUserInfoRequestType request_type = 2; + // Request timeout Milliseconds (-1 if not available) + optional int32 timeout_millis = 3; +} + +/** + * Logs when Car User Hal responds to initial user information requests. + * + * Logged from: + * packages/services/Car/service/src/com/android/car/hal/UserHalService.java + */ +message CarUserHalInitialUserInfoResponseReported { + // Request id of the request associated with the response. + optional int32 request_id = 1; + // Car user hal callback status. + enum CallbackStatus { + UNKNOWN = 0; + // Hal response was invalid. + INVALID = 1; + // Hal response was ok. + OK = 2; + // Hal timeout during set call. + HAL_SET_TIMEOUT = 3; + // Hal response timeout. + HAL_RESPONSE_TIMEOUT = 4; + // Hal responded with wrong info. + WRONG_HAL_RESPONSE = 5; + // Hal is processing multiple requests simultaneously. + CONCURRENT_OPERATION = 6; + } + optional CallbackStatus callback_status = 2; + // Response for initial user information request. + enum InitialUserInfoResponseAction { + UNSPECIFIED = 0; + // Let the Android System decide what to do. + DEFAULT = 1; + // Switch to an existing Android user. + SWITCH = 2; + // Create a new Android user (and switch to it). + CREATE = 3; + } + optional InitialUserInfoResponseAction response_action = 3; + // Android User id of the target user which can only be 0, 10, 11 and so on. + // -1 if not available. + optional int32 target_user = 4; + // VHAL flags of the current user. (-1 if not available) + optional int32 target_user_flags = 5; + // User locales + optional string user_locales = 6; +} + +/** + * Logs when set user association is requested from Car User Hal. + * + * Logged from: + * packages/services/Car/service/src/com/android/car/hal/UserHalService.java + */ +message CarUserHalUserAssociationRequestReported { + // Request id for the request. + optional int32 request_id = 1; + // Request type. + enum RequestType { + UNKNOWN = 0; + // For setting user association information. + SET = 1; + // For getting user association information. + GET = 2; + } + optional RequestType request_type = 2; + // Android User id of the current user which can only be 0, 10, 11 and so on. + // -1 if not available. + optional int32 current_user_id = 3; + // VHAL flags of the current user. (-1 if not available) + optional int32 current_user_flags = 4; + // Number of the set associations requested. + optional int32 number_associations = 5; + // Concatenated string for the types from set associations request. + // This is a string converted from an array of integers. + optional string user_identification_association_types = 6; + // Concatenated string for the values from set associations request. + // This is a string converted from an array of integers. + optional string user_identification_association_values = 7; +} + +/** + * Logs when Car User Hal responds to set user association requests. + * + * Logged from: + * packages/services/Car/service/src/com/android/car/hal/UserHalService.java + */ +message CarUserHalSetUserAssociationResponseReported { + // Request id of the request associated with the response. + optional int32 request_id = 1; + // Car user hal callback status. + enum CallbackStatus { + UNKNOWN = 0; + // Hal response was invalid. + INVALID = 1; + // Hal response was ok. + OK = 2; + // Hal timeout during set call. + HAL_SET_TIMEOUT = 3; + // Hal response timeout. + HAL_RESPONSE_TIMEOUT = 4; + // Hal responded with wrong info. + WRONG_HAL_RESPONSE = 5; + // Hal is processing multiple requests simultaneously. + CONCURRENT_OPERATION = 6; + } + optional CallbackStatus callback_status = 2; + // Number of the set associations in the response. + optional int32 number_associations = 3; + // Concatenated string for the types from set associations request. + // This is a string converted from an array of integers. + optional string user_identification_association_types = 4; + // Concatenated string for the values from set associations request. + // This is a string converted from an array of integers. + optional string user_identification_association_values = 5; +} + +/** * Logs whether GarageMode is entered. * * Logged from: @@ -9817,15 +10071,20 @@ message AccessibilityServiceReported { optional android.stats.accessibility.ServiceStatus service_status = 2; } -message DisplayWakeReason { +/** + * Logs when display wake up. + * + * Logged from: + * services/core/java/com/android/server/power/Notifier.java + */ + +message DisplayWakeReported { // Wake_up_reason code // If LOWORD(wake_up_reason) = 0 // reference to HIWORD(wake_up_reason) PowerManager.WAKE_REASON_XXX // else reference wake_up_reason to - // frameworks/base/services/core/java/com/android/server/power/Notifier.java#DispWakeupReason + // services/core/java/com/android/server/power/Notifier.java#onWakeUp optional int32 wake_up_reason = 1; - // Count of wake up by reason - optional int32 wake_times = 2; } /** diff --git a/core/java/android/app/contentsuggestions/ContentSuggestionsManager.java b/core/java/android/app/contentsuggestions/ContentSuggestionsManager.java index bea1bd6e70d6..b3f9e31abaa4 100644 --- a/core/java/android/app/contentsuggestions/ContentSuggestionsManager.java +++ b/core/java/android/app/contentsuggestions/ContentSuggestionsManager.java @@ -95,7 +95,7 @@ public final class ContentSuggestionsManager { try { mService.provideContextBitmap(mUser, bitmap, imageContextRequestExtras); } catch (RemoteException e) { - e.rethrowFromSystemServer(); + throw e.rethrowFromSystemServer(); } } @@ -117,7 +117,7 @@ public final class ContentSuggestionsManager { try { mService.provideContextImage(mUser, taskId, imageContextRequestExtras); } catch (RemoteException e) { - e.rethrowFromSystemServer(); + throw e.rethrowFromSystemServer(); } } @@ -146,7 +146,7 @@ public final class ContentSuggestionsManager { mService.suggestContentSelections( mUser, request, new SelectionsCallbackWrapper(callback, callbackExecutor)); } catch (RemoteException e) { - e.rethrowFromSystemServer(); + throw e.rethrowFromSystemServer(); } } @@ -173,7 +173,7 @@ public final class ContentSuggestionsManager { mService.classifyContentSelections( mUser, request, new ClassificationsCallbackWrapper(callback, callbackExecutor)); } catch (RemoteException e) { - e.rethrowFromSystemServer(); + throw e.rethrowFromSystemServer(); } } @@ -193,7 +193,7 @@ public final class ContentSuggestionsManager { try { mService.notifyInteraction(mUser, requestId, interaction); } catch (RemoteException e) { - e.rethrowFromSystemServer(); + throw e.rethrowFromSystemServer(); } } @@ -213,9 +213,10 @@ public final class ContentSuggestionsManager { mService.isEnabled(mUser, receiver); return receiver.getIntResult() != 0; } catch (RemoteException e) { - e.rethrowFromSystemServer(); + throw e.rethrowFromSystemServer(); + } catch (SyncResultReceiver.TimeoutException e) { + throw new RuntimeException("Fail to get the enable status."); } - return false; } /** diff --git a/core/java/android/telephony/PhoneStateListener.java b/core/java/android/telephony/PhoneStateListener.java index 9b293eb463e5..ef21900dc3e3 100644 --- a/core/java/android/telephony/PhoneStateListener.java +++ b/core/java/android/telephony/PhoneStateListener.java @@ -157,8 +157,8 @@ public class PhoneStateListener { * Listen for changes to the device's cell location. Note that * this will result in frequent callbacks to the listener. * {@more} - * Requires Permission: {@link android.Manifest.permission#ACCESS_COARSE_LOCATION - * ACCESS_COARSE_LOCATION} + * Requires Permission: {@link android.Manifest.permission#ACCESS_FINE_LOCATION + * ACCESS_FINE_LOCATION} * <p> * If you need regular location updates but want more control over * the update interval or location precision, you can set up a listener diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java index eaaaa80f65ed..214da380ccda 100644 --- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java +++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java @@ -635,7 +635,7 @@ public class AccessibilityNodeInfo implements Parcelable { "android.view.accessibility.extra.DATA_TEXT_CHARACTER_LOCATION_ARG_LENGTH"; /** - * Key used to request extra data for accessibility scanning tool's purposes. + * Key used to request extra data for the rendering information. * The key requests that a {@link AccessibilityNodeInfo.ExtraRenderingInfo} be added to this * info. This request is made with {@link #refreshWithExtraData(String, Bundle)} without * argument. @@ -5847,12 +5847,15 @@ public class AccessibilityNodeInfo implements Parcelable { } /** - * Gets the size object containing the height and the width of layout params if the node is - * a {@link ViewGroup} or a {@link TextView}, or null otherwise. Useful for accessibility - * scanning tool to understand whether the text is scalable and fits the view or not. + * Gets the size object containing the height and the width of + * {@link android.view.ViewGroup.LayoutParams} if the node is a {@link ViewGroup} or + * a {@link TextView}, or null otherwise. Useful for some accessibility services to + * understand whether the text is scalable and fits the view or not. * - * @return a {@link Size} stores layout height and layout width of the view, - * or null otherwise. + * @return a {@link Size} stores layout height and layout width of the view, or null + * otherwise. And the size value may be in pixels, + * {@link android.view.ViewGroup.LayoutParams#MATCH_PARENT}, + * or {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT} */ public @Nullable Size getLayoutSize() { return mLayoutSize; @@ -5870,9 +5873,9 @@ public class AccessibilityNodeInfo implements Parcelable { } /** - * Gets the text size if the node is a {@link TextView}, or -1 otherwise. Useful for - * accessibility scanning tool to understand whether the text is scalable and fits the view - * or not. + * Gets the text size if the node is a {@link TextView}, or -1 otherwise. Useful for some + * accessibility services to understand whether the text is scalable and fits the view or + * not. * * @return the text size of a {@code TextView}, or -1 otherwise. */ @@ -5893,7 +5896,7 @@ public class AccessibilityNodeInfo implements Parcelable { /** * Gets the text size unit if the node is a {@link TextView}, or -1 otherwise. * Text size returned from {@link #getTextSizeInPx} in raw pixels may scale by factors and - * convert from other units. Useful for accessibility scanning tool to understand whether + * convert from other units. Useful for some accessibility services to understand whether * the text is scalable and fits the view or not. * * @return the text size unit which type is {@link TypedValue#TYPE_DIMENSION} of a diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java index 3112039c36d8..fbfeda6f0bcc 100644 --- a/core/java/android/view/autofill/AutofillManager.java +++ b/core/java/android/view/autofill/AutofillManager.java @@ -751,6 +751,8 @@ public final class AutofillManager { } } catch (RemoteException e) { Log.e(TAG, "Could not figure out if there was an autofill session", e); + } catch (SyncResultReceiver.TimeoutException e) { + Log.e(TAG, "Fail to get session restore status: " + e); } } } @@ -864,7 +866,9 @@ public final class AutofillManager { mService.getFillEventHistory(receiver); return receiver.getParcelableResult(); } catch (RemoteException e) { - e.rethrowFromSystemServer(); + throw e.rethrowFromSystemServer(); + } catch (SyncResultReceiver.TimeoutException e) { + Log.e(TAG, "Fail to get fill event history: " + e); return null; } } @@ -1477,10 +1481,13 @@ public final class AutofillManager { final SyncResultReceiver receiver = new SyncResultReceiver(SYNC_CALLS_TIMEOUT_MS); try { - mService.isServiceEnabled(mContext.getUserId(), mContext.getPackageName(), receiver); + mService.isServiceEnabled(mContext.getUserId(), mContext.getPackageName(), + receiver); return receiver.getIntResult() == 1; } catch (RemoteException e) { throw e.rethrowFromSystemServer(); + } catch (SyncResultReceiver.TimeoutException e) { + throw new RuntimeException("Fail to get enabled autofill services status."); } } @@ -1498,6 +1505,8 @@ public final class AutofillManager { return receiver.getParcelableResult(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); + } catch (SyncResultReceiver.TimeoutException e) { + throw new RuntimeException("Fail to get autofill services component name."); } } @@ -1522,8 +1531,9 @@ public final class AutofillManager { mService.getUserDataId(receiver); return receiver.getStringResult(); } catch (RemoteException e) { - e.rethrowFromSystemServer(); - return null; + throw e.rethrowFromSystemServer(); + } catch (SyncResultReceiver.TimeoutException e) { + throw new RuntimeException("Fail to get user data id for field classification."); } } @@ -1544,8 +1554,9 @@ public final class AutofillManager { mService.getUserData(receiver); return receiver.getParcelableResult(); } catch (RemoteException e) { - e.rethrowFromSystemServer(); - return null; + throw e.rethrowFromSystemServer(); + } catch (SyncResultReceiver.TimeoutException e) { + throw new RuntimeException("Fail to get user data for field classification."); } } @@ -1561,7 +1572,7 @@ public final class AutofillManager { try { mService.setUserData(userData); } catch (RemoteException e) { - e.rethrowFromSystemServer(); + throw e.rethrowFromSystemServer(); } } @@ -1583,8 +1594,9 @@ public final class AutofillManager { mService.isFieldClassificationEnabled(receiver); return receiver.getIntResult() == 1; } catch (RemoteException e) { - e.rethrowFromSystemServer(); - return false; + throw e.rethrowFromSystemServer(); + } catch (SyncResultReceiver.TimeoutException e) { + throw new RuntimeException("Fail to get field classification enabled status."); } } @@ -1606,8 +1618,9 @@ public final class AutofillManager { mService.getDefaultFieldClassificationAlgorithm(receiver); return receiver.getStringResult(); } catch (RemoteException e) { - e.rethrowFromSystemServer(); - return null; + throw e.rethrowFromSystemServer(); + } catch (SyncResultReceiver.TimeoutException e) { + throw new RuntimeException("Fail to get default field classification algorithm."); } } @@ -1627,8 +1640,9 @@ public final class AutofillManager { final String[] algorithms = receiver.getStringArrayResult(); return algorithms != null ? Arrays.asList(algorithms) : Collections.emptyList(); } catch (RemoteException e) { - e.rethrowFromSystemServer(); - return null; + throw e.rethrowFromSystemServer(); + } catch (SyncResultReceiver.TimeoutException e) { + throw new RuntimeException("Fail to get available field classification algorithms."); } } @@ -1651,6 +1665,8 @@ public final class AutofillManager { return receiver.getIntResult() == 1; } catch (RemoteException e) { throw e.rethrowFromSystemServer(); + } catch (SyncResultReceiver.TimeoutException e) { + throw new RuntimeException("Fail to get autofill supported status."); } } @@ -2040,13 +2056,16 @@ public final class AutofillManager { } final SyncResultReceiver resultReceiver = new SyncResultReceiver(SYNC_CALLS_TIMEOUT_MS); - final int resultCode; + int resultCode; try { mService.setAugmentedAutofillWhitelist(toList(packages), toList(activities), resultReceiver); resultCode = resultReceiver.getIntResult(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); + } catch (SyncResultReceiver.TimeoutException e) { + Log.e(TAG, "Fail to get the result of set AugmentedAutofill whitelist. " + e); + return; } switch (resultCode) { case RESULT_OK: @@ -2283,7 +2302,7 @@ public final class AutofillManager { // In theory, we could ignore this error since it's not a big deal, but // in reality, we rather crash the app anyways, as the failure could be // a consequence of something going wrong on the server side... - e.rethrowFromSystemServer(); + throw e.rethrowFromSystemServer(); } } @@ -2661,7 +2680,7 @@ public final class AutofillManager { try { mService.onPendingSaveUi(operation, token); } catch (RemoteException e) { - e.rethrowFromSystemServer(); + Log.e(TAG, "Error in onPendingSaveUi: ", e); } } } diff --git a/core/java/android/view/contentcapture/ContentCaptureManager.java b/core/java/android/view/contentcapture/ContentCaptureManager.java index 756ff78e5906..484b1c10423c 100644 --- a/core/java/android/view/contentcapture/ContentCaptureManager.java +++ b/core/java/android/view/contentcapture/ContentCaptureManager.java @@ -487,6 +487,8 @@ public final class ContentCaptureManager { return resultReceiver.getParcelableResult(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); + } catch (SyncResultReceiver.TimeoutException e) { + throw new RuntimeException("Fail to get service componentName."); } } @@ -516,6 +518,9 @@ public final class ContentCaptureManager { return resultReceiver.getParcelableResult(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); + } catch (SyncResultReceiver.TimeoutException e) { + Log.e(TAG, "Fail to get service settings componentName: " + e); + return null; } } @@ -567,9 +572,13 @@ public final class ContentCaptureManager { final SyncResultReceiver resultReceiver = syncRun( (r) -> mService.getContentCaptureConditions(mContext.getPackageName(), r)); - final ArrayList<ContentCaptureCondition> result = resultReceiver - .getParcelableListResult(); - return toSet(result); + try { + final ArrayList<ContentCaptureCondition> result = resultReceiver + .getParcelableListResult(); + return toSet(result); + } catch (SyncResultReceiver.TimeoutException e) { + throw new RuntimeException("Fail to get content capture conditions."); + } } /** @@ -639,15 +648,21 @@ public final class ContentCaptureManager { public boolean isContentCaptureFeatureEnabled() { final SyncResultReceiver resultReceiver = syncRun( (r) -> mService.isContentCaptureFeatureEnabled(r)); - final int resultCode = resultReceiver.getIntResult(); - switch (resultCode) { - case RESULT_CODE_TRUE: - return true; - case RESULT_CODE_FALSE: - return false; - default: - Log.wtf(TAG, "received invalid result: " + resultCode); - return false; + + try { + final int resultCode = resultReceiver.getIntResult(); + switch (resultCode) { + case RESULT_CODE_TRUE: + return true; + case RESULT_CODE_FALSE: + return false; + default: + Log.wtf(TAG, "received invalid result: " + resultCode); + return false; + } + } catch (SyncResultReceiver.TimeoutException e) { + Log.e(TAG, "Fail to get content capture feature enable status: " + e); + return false; } } @@ -663,7 +678,7 @@ public final class ContentCaptureManager { try { mService.removeData(request); } catch (RemoteException e) { - e.rethrowFromSystemServer(); + throw e.rethrowFromSystemServer(); } } @@ -691,7 +706,7 @@ public final class ContentCaptureManager { new DataShareAdapterDelegate(executor, dataShareWriteAdapter, mDataShareAdapterResourceManager)); } catch (RemoteException e) { - e.rethrowFromSystemServer(); + throw e.rethrowFromSystemServer(); } } @@ -709,10 +724,12 @@ public final class ContentCaptureManager { if (resultCode == RESULT_CODE_SECURITY_EXCEPTION) { throw new SecurityException(resultReceiver.getStringResult()); } - return resultReceiver; } catch (RemoteException e) { throw e.rethrowFromSystemServer(); + } catch (SyncResultReceiver.TimeoutException e) { + throw new RuntimeException("Fail to get syn run result from SyncResultReceiver."); } + return resultReceiver; } /** @hide */ diff --git a/core/java/android/view/inputmethod/InlineSuggestion.java b/core/java/android/view/inputmethod/InlineSuggestion.java index e4ac5889a3c0..b8893cee834d 100644 --- a/core/java/android/view/inputmethod/InlineSuggestion.java +++ b/core/java/android/view/inputmethod/InlineSuggestion.java @@ -317,8 +317,24 @@ public final class InlineSuggestion implements Parcelable { */ @MainThread private void handleOnSurfacePackage(SurfaceControlViewHost.SurfacePackage surfacePackage) { + if (surfacePackage == null) { + return; + } + if (mSurfacePackage != null || mSurfacePackageConsumer == null) { + // The surface package is not consumed, release it immediately. + surfacePackage.release(); + try { + mInlineContentProvider.onSurfacePackageReleased(); + } catch (RemoteException e) { + Slog.w(TAG, "Error calling onSurfacePackageReleased(): " + e); + } + return; + } mSurfacePackage = surfacePackage; - if (mSurfacePackage != null && mSurfacePackageConsumer != null) { + if (mSurfacePackage == null) { + return; + } + if (mSurfacePackageConsumer != null) { mSurfacePackageConsumer.accept(mSurfacePackage); mSurfacePackageConsumer = null; } @@ -334,6 +350,10 @@ public final class InlineSuggestion implements Parcelable { } mSurfacePackage = null; } + // Clear the pending surface package consumer, if any. This can happen if the IME + // attaches the view to window and then quickly detaches it from the window, before + // the surface package requested upon attaching to window was returned. + mSurfacePackageConsumer = null; } @MainThread diff --git a/core/java/android/widget/inline/InlineContentView.java b/core/java/android/widget/inline/InlineContentView.java index 8657e828a3f6..6a85de5ca757 100644 --- a/core/java/android/widget/inline/InlineContentView.java +++ b/core/java/android/widget/inline/InlineContentView.java @@ -197,7 +197,9 @@ public class InlineContentView extends ViewGroup { mSurfacePackageUpdater.getSurfacePackage( sp -> { if (DEBUG) Log.v(TAG, "Received new SurfacePackage"); - mSurfaceView.setChildSurfacePackage(sp); + if (getViewRootImpl() != null) { + mSurfaceView.setChildSurfacePackage(sp); + } }); } } diff --git a/core/java/com/android/internal/util/SyncResultReceiver.java b/core/java/com/android/internal/util/SyncResultReceiver.java index 00e91017a9eb..6b1358293d02 100644 --- a/core/java/com/android/internal/util/SyncResultReceiver.java +++ b/core/java/com/android/internal/util/SyncResultReceiver.java @@ -182,7 +182,7 @@ public final class SyncResultReceiver extends IResultReceiver.Stub { } /** @hide */ - public static final class TimeoutException extends RuntimeException { + public static final class TimeoutException extends Exception { private TimeoutException(String msg) { super(msg); } diff --git a/data/etc/car/Android.bp b/data/etc/car/Android.bp index 1b1a624cda50..d6542de91e08 100644 --- a/data/etc/car/Android.bp +++ b/data/etc/car/Android.bp @@ -122,6 +122,13 @@ prebuilt_etc { } prebuilt_etc { + name: "privapp_whitelist_com.android.car.bugreport", + sub_dir: "permissions", + src: "com.android.car.bugreport.xml", + filename_from_src: true, +} + +prebuilt_etc { name: "privapp_whitelist_com.google.android.car.kitchensink", sub_dir: "permissions", src: "com.google.android.car.kitchensink.xml", diff --git a/data/etc/car/com.android.car.bugreport.xml b/data/etc/car/com.android.car.bugreport.xml new file mode 100644 index 000000000000..432a838a90e8 --- /dev/null +++ b/data/etc/car/com.android.car.bugreport.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> +<permissions> + <privapp-permissions package="com.android.car.bugreport"> + <permission name="android.permission.DUMP"/> + <permission name="android.permission.INTERACT_ACROSS_USERS"/> + <permission name="android.permission.READ_LOGS"/> + <permission name="android.permission.MANAGE_USERS"/> + </privapp-permissions> + </permissions> diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java index d7dd6f24ceb3..32ef063a55be 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java @@ -22,6 +22,7 @@ import android.text.TextUtils; import android.util.Log; import android.widget.Switch; +import com.android.internal.logging.UiEventLogger; import com.android.systemui.R; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.qs.QSTile; @@ -41,14 +42,16 @@ public class ScreenRecordTile extends QSTileImpl<QSTile.BooleanState> private ActivityStarter mActivityStarter; private long mMillisUntilFinished = 0; private Callback mCallback = new Callback(); + private UiEventLogger mUiEventLogger; @Inject public ScreenRecordTile(QSHost host, RecordingController controller, - ActivityStarter activityStarter) { + ActivityStarter activityStarter, UiEventLogger uiEventLogger) { super(host); mController = controller; mController.observe(this, mCallback); mActivityStarter = activityStarter; + mUiEventLogger = uiEventLogger; } @Override @@ -112,7 +115,6 @@ public class ScreenRecordTile extends QSTileImpl<QSTile.BooleanState> } private void startCountdown() { - Log.d(TAG, "Starting countdown"); // Close QS, otherwise the permission dialog appears beneath it getHost().collapsePanels(); Intent intent = mController.getPromptIntent(); @@ -125,7 +127,6 @@ public class ScreenRecordTile extends QSTileImpl<QSTile.BooleanState> } private void stopRecording() { - Log.d(TAG, "Stopping recording from tile"); mController.stopRecording(); } diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java index baa2dfdcebf3..8a012b8b06f1 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java +++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java @@ -577,10 +577,6 @@ public class OverviewProxyService extends CurrentUserTracker implements // Listen for nav bar mode changes mNavBarMode = navModeController.addListener(this); - // Listen for device provisioned/user setup - updateEnabledState(); - startTracking(); - // Listen for launcher package changes IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED); filter.addDataScheme("package"); @@ -601,6 +597,13 @@ public class OverviewProxyService extends CurrentUserTracker implements .commitUpdate(mContext.getDisplayId()); } }); + + // Listen for user setup + startTracking(); + + // Connect to the service + updateEnabledState(); + startConnectionToCurrentUser(); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/Events.java b/packages/SystemUI/src/com/android/systemui/screenrecord/Events.java new file mode 100644 index 000000000000..9dede4848914 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/screenrecord/Events.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.screenrecord; + +import com.android.internal.logging.UiEvent; +import com.android.internal.logging.UiEventLogger; + +/** + * Events related to the SystemUI screen recorder + */ +public class Events { + + public enum ScreenRecordEvent implements UiEventLogger.UiEventEnum { + @UiEvent(doc = "Screen recording was started") + SCREEN_RECORD_START(299), + @UiEvent(doc = "Screen recording was stopped from the quick settings tile") + SCREEN_RECORD_END_QS_TILE(300), + @UiEvent(doc = "Screen recording was stopped from the notification") + SCREEN_RECORD_END_NOTIFICATION(301); + + private final int mId; + ScreenRecordEvent(int id) { + mId = id; + } + + @Override + public int getId() { + return mId; + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java index 2ddd6aaf4c40..f2e8599536ca 100644 --- a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java +++ b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java @@ -36,6 +36,8 @@ import android.provider.Settings; import android.util.Log; import android.widget.Toast; +import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.logging.UiEventLogger; import com.android.systemui.R; import com.android.systemui.dagger.qualifiers.LongRunning; @@ -63,22 +65,28 @@ public class RecordingService extends Service implements MediaRecorder.OnInfoLis private static final String ACTION_START = "com.android.systemui.screenrecord.START"; private static final String ACTION_STOP = "com.android.systemui.screenrecord.STOP"; + private static final String ACTION_STOP_NOTIF = + "com.android.systemui.screenrecord.STOP_FROM_NOTIF"; private static final String ACTION_SHARE = "com.android.systemui.screenrecord.SHARE"; private static final String ACTION_DELETE = "com.android.systemui.screenrecord.DELETE"; private final RecordingController mController; - private Notification.Builder mRecordingNotificationBuilder; private ScreenRecordingAudioSource mAudioSource; private boolean mShowTaps; private boolean mOriginalShowTaps; private ScreenMediaRecorder mRecorder; private final Executor mLongExecutor; + private final UiEventLogger mUiEventLogger; + private final NotificationManager mNotificationManager; @Inject - public RecordingService(RecordingController controller, @LongRunning Executor executor) { + public RecordingService(RecordingController controller, @LongRunning Executor executor, + UiEventLogger uiEventLogger, NotificationManager notificationManager) { mController = controller; mLongExecutor = executor; + mUiEventLogger = uiEventLogger; + mNotificationManager = notificationManager; } /** @@ -110,9 +118,6 @@ public class RecordingService extends Service implements MediaRecorder.OnInfoLis String action = intent.getAction(); Log.d(TAG, "onStartCommand " + action); - NotificationManager notificationManager = - (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); - switch (action) { case ACTION_START: mAudioSource = ScreenRecordingAudioSource @@ -135,10 +140,16 @@ public class RecordingService extends Service implements MediaRecorder.OnInfoLis startRecording(); break; + case ACTION_STOP_NOTIF: case ACTION_STOP: + // only difference for actions is the log event + if (ACTION_STOP_NOTIF.equals(action)) { + mUiEventLogger.log(Events.ScreenRecordEvent.SCREEN_RECORD_END_NOTIFICATION); + } else { + mUiEventLogger.log(Events.ScreenRecordEvent.SCREEN_RECORD_END_QS_TILE); + } stopRecording(); - notificationManager.cancel(NOTIFICATION_RECORDING_ID); - saveRecording(notificationManager); + mNotificationManager.cancel(NOTIFICATION_RECORDING_ID); stopSelf(); break; @@ -154,7 +165,7 @@ public class RecordingService extends Service implements MediaRecorder.OnInfoLis sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)); // Remove notification - notificationManager.cancel(NOTIFICATION_VIEW_ID); + mNotificationManager.cancel(NOTIFICATION_VIEW_ID); startActivity(Intent.createChooser(shareIntent, shareLabel) .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); @@ -173,7 +184,7 @@ public class RecordingService extends Service implements MediaRecorder.OnInfoLis Toast.LENGTH_LONG).show(); // Remove notification - notificationManager.cancel(NOTIFICATION_VIEW_ID); + mNotificationManager.cancel(NOTIFICATION_VIEW_ID); Log.d(TAG, "Deleted recording " + uri); break; } @@ -190,14 +201,20 @@ public class RecordingService extends Service implements MediaRecorder.OnInfoLis super.onCreate(); } + @VisibleForTesting + protected ScreenMediaRecorder getRecorder() { + return mRecorder; + } + /** * Begin the recording session */ private void startRecording() { try { - mRecorder.start(); + getRecorder().start(); mController.updateState(true); createRecordingNotification(); + mUiEventLogger.log(Events.ScreenRecordEvent.SCREEN_RECORD_START); } catch (IOException | RemoteException e) { Toast.makeText(this, R.string.screenrecord_start_error, Toast.LENGTH_LONG) @@ -206,7 +223,8 @@ public class RecordingService extends Service implements MediaRecorder.OnInfoLis } } - private void createRecordingNotification() { + @VisibleForTesting + protected void createRecordingNotification() { Resources res = getResources(); NotificationChannel channel = new NotificationChannel( CHANNEL_ID, @@ -214,9 +232,7 @@ public class RecordingService extends Service implements MediaRecorder.OnInfoLis NotificationManager.IMPORTANCE_DEFAULT); channel.setDescription(getString(R.string.screenrecord_channel_description)); channel.enableVibration(true); - NotificationManager notificationManager = - (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); - notificationManager.createNotificationChannel(channel); + mNotificationManager.createNotificationChannel(channel); Bundle extras = new Bundle(); extras.putString(Notification.EXTRA_SUBSTITUTE_APP_NAME, @@ -226,7 +242,9 @@ public class RecordingService extends Service implements MediaRecorder.OnInfoLis ? res.getString(R.string.screenrecord_ongoing_screen_only) : res.getString(R.string.screenrecord_ongoing_screen_and_audio); - mRecordingNotificationBuilder = new Notification.Builder(this, CHANNEL_ID) + + Intent stopIntent = getNotificationIntent(this); + Notification.Builder builder = new Notification.Builder(this, CHANNEL_ID) .setSmallIcon(R.drawable.ic_screenrecord) .setContentTitle(notificationTitle) .setContentText(getResources().getString(R.string.screenrecord_stop_text)) @@ -235,17 +253,28 @@ public class RecordingService extends Service implements MediaRecorder.OnInfoLis .setColor(getResources().getColor(R.color.GM2_red_700)) .setOngoing(true) .setContentIntent( - PendingIntent.getService( - this, REQUEST_CODE, getStopIntent(this), + PendingIntent.getService(this, REQUEST_CODE, stopIntent, PendingIntent.FLAG_UPDATE_CURRENT)) .addExtras(extras); - notificationManager.notify(NOTIFICATION_RECORDING_ID, - mRecordingNotificationBuilder.build()); - Notification notification = mRecordingNotificationBuilder.build(); - startForeground(NOTIFICATION_RECORDING_ID, notification); + startForeground(NOTIFICATION_RECORDING_ID, builder.build()); } - private Notification createSaveNotification(ScreenMediaRecorder.SavedRecording recording) { + @VisibleForTesting + protected Notification createProcessingNotification() { + Resources res = getApplicationContext().getResources(); + String notificationTitle = mAudioSource == ScreenRecordingAudioSource.NONE + ? res.getString(R.string.screenrecord_ongoing_screen_only) + : res.getString(R.string.screenrecord_ongoing_screen_and_audio); + Notification.Builder builder = new Notification.Builder(getApplicationContext(), CHANNEL_ID) + .setContentTitle(notificationTitle) + .setContentText( + getResources().getString(R.string.screenrecord_background_processing_label)) + .setSmallIcon(R.drawable.ic_screenrecord); + return builder.build(); + } + + @VisibleForTesting + protected Notification createSaveNotification(ScreenMediaRecorder.SavedRecording recording) { Uri uri = recording.getUri(); Intent viewIntent = new Intent(Intent.ACTION_VIEW) .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_GRANT_READ_URI_PERMISSION) @@ -301,44 +330,39 @@ public class RecordingService extends Service implements MediaRecorder.OnInfoLis private void stopRecording() { setTapsVisible(mOriginalShowTaps); - mRecorder.end(); + if (getRecorder() != null) { + getRecorder().end(); + saveRecording(); + } else { + Log.e(TAG, "stopRecording called, but recorder was null"); + } mController.updateState(false); } - private void saveRecording(NotificationManager notificationManager) { - Resources res = getApplicationContext().getResources(); - String notificationTitle = mAudioSource == ScreenRecordingAudioSource.NONE - ? res.getString(R.string.screenrecord_ongoing_screen_only) - : res.getString(R.string.screenrecord_ongoing_screen_and_audio); - Notification.Builder builder = new Notification.Builder(getApplicationContext(), CHANNEL_ID) - .setContentTitle(notificationTitle) - .setContentText( - getResources().getString(R.string.screenrecord_background_processing_label)) - .setSmallIcon(R.drawable.ic_screenrecord); - notificationManager.notify(NOTIFICATION_PROCESSING_ID, builder.build()); + private void saveRecording() { + mNotificationManager.notify(NOTIFICATION_PROCESSING_ID, createProcessingNotification()); mLongExecutor.execute(() -> { try { Log.d(TAG, "saving recording"); - Notification notification = createSaveNotification(mRecorder.save()); + Notification notification = createSaveNotification(getRecorder().save()); if (!mController.isRecording()) { Log.d(TAG, "showing saved notification"); - notificationManager.notify(NOTIFICATION_VIEW_ID, notification); + mNotificationManager.notify(NOTIFICATION_VIEW_ID, notification); } } catch (IOException e) { Log.e(TAG, "Error saving screen recording: " + e.getMessage()); Toast.makeText(this, R.string.screenrecord_delete_error, Toast.LENGTH_LONG) .show(); } finally { - notificationManager.cancel(NOTIFICATION_PROCESSING_ID); + mNotificationManager.cancel(NOTIFICATION_PROCESSING_ID); } }); } private void setTapsVisible(boolean turnOn) { int value = turnOn ? 1 : 0; - Settings.System.putInt(getApplicationContext().getContentResolver(), - Settings.System.SHOW_TOUCHES, value); + Settings.System.putInt(getContentResolver(), Settings.System.SHOW_TOUCHES, value); } /** @@ -350,6 +374,15 @@ public class RecordingService extends Service implements MediaRecorder.OnInfoLis return new Intent(context, RecordingService.class).setAction(ACTION_STOP); } + /** + * Get the recording notification content intent + * @param context + * @return + */ + protected static Intent getNotificationIntent(Context context) { + return new Intent(context, RecordingService.class).setAction(ACTION_STOP_NOTIF); + } + private static Intent getShareIntent(Context context, String path) { return new Intent(context, RecordingService.class).setAction(ACTION_SHARE) .putExtra(EXTRA_PATH, path); diff --git a/packages/SystemUI/src/com/android/systemui/util/magnetictarget/MagnetizedObject.kt b/packages/SystemUI/src/com/android/systemui/util/magnetictarget/MagnetizedObject.kt index e905e6772074..da7953d27f59 100644 --- a/packages/SystemUI/src/com/android/systemui/util/magnetictarget/MagnetizedObject.kt +++ b/packages/SystemUI/src/com/android/systemui/util/magnetictarget/MagnetizedObject.kt @@ -245,9 +245,6 @@ abstract class MagnetizedObject<T : Any>( */ var hapticsEnabled = true - /** Whether the HAPTIC_FEEDBACK_ENABLED setting is true. */ - private var systemHapticsEnabled = false - /** Default spring configuration to use for animating the object into a target. */ var springConfig = PhysicsAnimator.SpringConfig( SpringForce.STIFFNESS_MEDIUM, SpringForce.DAMPING_RATIO_NO_BOUNCY) @@ -259,24 +256,7 @@ abstract class MagnetizedObject<T : Any>( var flungIntoTargetSpringConfig = springConfig init { - val hapticSettingObserver = - object : ContentObserver(Handler.getMain()) { - override fun onChange(selfChange: Boolean) { - systemHapticsEnabled = - Settings.System.getIntForUser( - context.contentResolver, - Settings.System.HAPTIC_FEEDBACK_ENABLED, - 0, - UserHandle.USER_CURRENT) != 0 - } - } - - context.contentResolver.registerContentObserver( - Settings.System.getUriFor(Settings.System.HAPTIC_FEEDBACK_ENABLED), - true /* notifyForDescendants */, hapticSettingObserver) - - // Trigger the observer once to initialize systemHapticsEnabled. - hapticSettingObserver.onChange(false /* selfChange */) + initHapticSettingObserver(context) } /** @@ -623,6 +603,43 @@ abstract class MagnetizedObject<T : Any>( companion object { /** + * Whether the HAPTIC_FEEDBACK_ENABLED setting is true. + * + * We put it in the companion object because we need to register a settings observer and + * [MagnetizedObject] doesn't have an obvious lifecycle so we don't have a good time to + * remove that observer. Since this settings is shared among all instances we just let all + * instances read from this value. + */ + private var systemHapticsEnabled = false + private var hapticSettingObserverInitialized = false + + private fun initHapticSettingObserver(context: Context) { + if (hapticSettingObserverInitialized) { + return + } + + val hapticSettingObserver = + object : ContentObserver(Handler.getMain()) { + override fun onChange(selfChange: Boolean) { + systemHapticsEnabled = + Settings.System.getIntForUser( + context.contentResolver, + Settings.System.HAPTIC_FEEDBACK_ENABLED, + 0, + UserHandle.USER_CURRENT) != 0 + } + } + + context.contentResolver.registerContentObserver( + Settings.System.getUriFor(Settings.System.HAPTIC_FEEDBACK_ENABLED), + true /* notifyForDescendants */, hapticSettingObserver) + + // Trigger the observer once to initialize systemHapticsEnabled. + hapticSettingObserver.onChange(false /* selfChange */) + hapticSettingObserverInitialized = true + } + + /** * Magnetizes the given view. Magnetized views are attracted to one or more magnetic * targets. Magnetic targets attract objects that are dragged near them, and hold them there * unless they're moved away or released. Releasing objects inside a magnetic target diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java index 8a8d2272d563..e5024595d97e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java @@ -29,6 +29,7 @@ import android.testing.TestableLooper; import androidx.test.filters.SmallTest; +import com.android.internal.logging.UiEventLogger; import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.SysuiTestCase; @@ -53,6 +54,8 @@ public class ScreenRecordTileTest extends SysuiTestCase { private ActivityStarter mActivityStarter; @Mock private QSTileHost mHost; + @Mock + private UiEventLogger mUiEventLogger; private TestableLooper mTestableLooper; private ScreenRecordTile mTile; @@ -68,7 +71,7 @@ public class ScreenRecordTileTest extends SysuiTestCase { when(mHost.getContext()).thenReturn(mContext); - mTile = new ScreenRecordTile(mHost, mController, mActivityStarter); + mTile = new ScreenRecordTile(mHost, mController, mActivityStarter, mUiEventLogger); } // Test that the tile is inactive and labeled correctly when the controller is neither starting diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingServiceTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingServiceTest.java new file mode 100644 index 000000000000..283a47ca3622 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingServiceTest.java @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.screenrecord; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import android.app.Notification; +import android.app.NotificationManager; +import android.content.Intent; +import android.testing.AndroidTestingRunner; + +import androidx.test.filters.SmallTest; + +import com.android.internal.logging.UiEventLogger; +import com.android.systemui.SysuiTestCase; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; + +import java.util.concurrent.Executor; + +@RunWith(AndroidTestingRunner.class) +@SmallTest +public class RecordingServiceTest extends SysuiTestCase { + + @Mock + private UiEventLogger mUiEventLogger; + @Mock + private RecordingController mController; + @Mock + private NotificationManager mNotificationManager; + @Mock + private ScreenMediaRecorder mScreenMediaRecorder; + @Mock + private Notification mNotification; + @Mock + private Executor mExecutor; + + private RecordingService mRecordingService; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + mRecordingService = Mockito.spy(new RecordingService(mController, mExecutor, mUiEventLogger, + mNotificationManager)); + + // Return actual context info + doReturn(mContext).when(mRecordingService).getApplicationContext(); + doReturn(mContext.getUserId()).when(mRecordingService).getUserId(); + doReturn(mContext.getPackageName()).when(mRecordingService).getPackageName(); + doReturn(mContext.getContentResolver()).when(mRecordingService).getContentResolver(); + + // Mock notifications + doNothing().when(mRecordingService).createRecordingNotification(); + doReturn(mNotification).when(mRecordingService).createProcessingNotification(); + doReturn(mNotification).when(mRecordingService).createSaveNotification(any()); + + doNothing().when(mRecordingService).startForeground(anyInt(), any()); + doReturn(mScreenMediaRecorder).when(mRecordingService).getRecorder(); + } + + @Test + public void testLogStartRecording() { + Intent startIntent = RecordingService.getStartIntent(mContext, 0, 0, false); + mRecordingService.onStartCommand(startIntent, 0, 0); + + verify(mUiEventLogger, times(1)).log(Events.ScreenRecordEvent.SCREEN_RECORD_START); + } + + @Test + public void testLogStopFromQsTile() { + Intent stopIntent = RecordingService.getStopIntent(mContext); + mRecordingService.onStartCommand(stopIntent, 0, 0); + + // Verify that we log the correct event + verify(mUiEventLogger, times(1)).log(Events.ScreenRecordEvent.SCREEN_RECORD_END_QS_TILE); + verify(mUiEventLogger, times(0)) + .log(Events.ScreenRecordEvent.SCREEN_RECORD_END_NOTIFICATION); + } + + @Test + public void testLogStopFromNotificationIntent() { + Intent stopIntent = RecordingService.getNotificationIntent(mContext); + mRecordingService.onStartCommand(stopIntent, 0, 0); + + // Verify that we log the correct event + verify(mUiEventLogger, times(1)) + .log(Events.ScreenRecordEvent.SCREEN_RECORD_END_NOTIFICATION); + verify(mUiEventLogger, times(0)).log(Events.ScreenRecordEvent.SCREEN_RECORD_END_QS_TILE); + } +} diff --git a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java index c0c9b3220ae0..cc4505c26aed 100644 --- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java +++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java @@ -191,7 +191,6 @@ import java.util.Random; import java.util.Set; import java.util.UUID; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.Executor; import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.TimeUnit; @@ -257,21 +256,17 @@ public class StatsPullAtomService extends SystemService { @GuardedBy("mNotificationStatsLock") private INotificationManager mNotificationManagerService; - private final Object mProcessStatsLock = new Object(); - @GuardedBy("mProcessStatsLock") + @GuardedBy("mProcStatsLock") private IProcessStats mProcessStatsService; - private final Object mCpuTrackerLock = new Object(); - @GuardedBy("mCpuTrackerLock") + @GuardedBy("mProcessCpuTimeLock") private ProcessCpuTracker mProcessCpuTracker; - private final Object mDebugElapsedClockLock = new Object(); @GuardedBy("mDebugElapsedClockLock") private long mDebugElapsedClockPreviousValue = 0; @GuardedBy("mDebugElapsedClockLock") private long mDebugElapsedClockPullCount = 0; - private final Object mDebugFailingElapsedClockLock = new Object(); @GuardedBy("mDebugFailingElapsedClockLock") private long mDebugFailingElapsedClockPreviousValue = 0; @GuardedBy("mDebugFailingElapsedClockLock") @@ -284,26 +279,40 @@ public class StatsPullAtomService extends SystemService { private TelephonyManager mTelephony; private SubscriptionManager mSubscriptionManager; + @GuardedBy("mKernelWakelockLock") private KernelWakelockReader mKernelWakelockReader; + @GuardedBy("mKernelWakelockLock") private KernelWakelockStats mTmpWakelockStats; + @GuardedBy("mDiskIoLock") private StoragedUidIoStatsReader mStoragedUidIoStatsReader; + @GuardedBy("mCpuTimePerFreqLock") private KernelCpuSpeedReader[] mKernelCpuSpeedReaders; // Disables throttler on CPU time readers. + @GuardedBy("mCpuTimePerUidLock") private KernelCpuUidUserSysTimeReader mCpuUidUserSysTimeReader; + @GuardedBy("mCpuTimePerUidFreqLock") private KernelCpuUidFreqTimeReader mCpuUidFreqTimeReader; + @GuardedBy("mCpuActiveTimeLock") private KernelCpuUidActiveTimeReader mCpuUidActiveTimeReader; + @GuardedBy("mClusterTimeLock") private KernelCpuUidClusterTimeReader mCpuUidClusterTimeReader; + @GuardedBy("mProcStatsLock") private File mBaseDir; + @GuardedBy("mHealthHalLock") private BatteryService.HealthServiceWrapper mHealthService; @Nullable + @GuardedBy("mCpuTimePerThreadFreqLock") private KernelCpuThreadReaderDiff mKernelCpuThreadReader; + private final Object mBatteryStatsHelperLock = new Object(); + @GuardedBy("mBatteryStatsHelperLock") private BatteryStatsHelper mBatteryStatsHelper = null; + @GuardedBy("mBatteryStatsHelperLock") private long mBatteryStatsHelperTimestampMs = -MAX_BATTERY_STATS_HELPER_FREQUENCY_MS; private StatsPullAtomCallbackImpl mStatsCallbackImpl; @@ -311,19 +320,75 @@ public class StatsPullAtomService extends SystemService { private final Object mAppOpsSamplingRateLock = new Object(); @GuardedBy("mAppOpsSamplingRateLock") private int mAppOpsSamplingRate = 0; + private final Object mDangerousAppOpsListLock = new Object(); + @GuardedBy("mDangerousAppOpsListLock") private final ArraySet<Integer> mDangerousAppOpsList = new ArraySet<>(); // Baselines that stores list of NetworkStats right after initializing, with associated - // information. This is used to calculate difference when pulling - // {Mobile|Wifi}BytesTransfer* atoms. Note that this is not thread-safe, and must - // only be accessed on the background thread. + // information. This is used to calculate difference when pulling BytesTransfer atoms. @NonNull - private final List<NetworkStatsExt> mNetworkStatsBaselines = new ArrayList<>(); + @GuardedBy("mDataBytesTransferLock") + private final ArrayList<NetworkStatsExt> mNetworkStatsBaselines = new ArrayList<>(); // Listener for monitoring subscriptions changed event. private StatsSubscriptionsListener mStatsSubscriptionsListener; // List that stores SubInfo of subscriptions that ever appeared since boot. - private final CopyOnWriteArrayList<SubInfo> mHistoricalSubs = new CopyOnWriteArrayList<>(); + @GuardedBy("mDataBytesTransferLock") + private final ArrayList<SubInfo> mHistoricalSubs = new ArrayList<>(); + + // Puller locks + private final Object mDataBytesTransferLock = new Object(); + private final Object mBluetoothBytesTransferLock = new Object(); + private final Object mKernelWakelockLock = new Object(); + private final Object mCpuTimePerFreqLock = new Object(); + private final Object mCpuTimePerUidLock = new Object(); + private final Object mCpuTimePerUidFreqLock = new Object(); + private final Object mCpuActiveTimeLock = new Object(); + private final Object mCpuClusterTimeLock = new Object(); + private final Object mWifiActivityInfoLock = new Object(); + private final Object mModemActivityInfoLock = new Object(); + private final Object mBluetoothActivityInfoLock = new Object(); + private final Object mSystemElapsedRealtimeLock = new Object(); + private final Object mSystemUptimeLock = new Object(); + private final Object mProcessMemoryStateLock = new Object(); + private final Object mProcessMemoryHighWaterMarkLock = new Object(); + private final Object mProcessMemorySnapshotLock = new Object(); + private final Object mSystemIonHeapSizeLock = new Object(); + private final Object mIonHeapSizeLock = new Object(); + private final Object mProcessSystemIonHeapSizeLock = new Object(); + private final Object mTemperatureLock = new Object(); + private final Object mCooldownDeviceLock = new Object(); + private final Object mBinderCallsStatsLock = new Object(); + private final Object mBinderCallsStatsExceptionsLock = new Object(); + private final Object mLooperStatsLock = new Object(); + private final Object mDiskStatsLock = new Object(); + private final Object mDirectoryUsageLock = new Object(); + private final Object mAppSizeLock = new Object(); + private final Object mCategorySizeLock = new Object(); + private final Object mNumBiometricsEnrolledLock = new Object(); + private final Object mProcStatsLock = new Object(); + private final Object mDiskIoLock = new Object(); + private final Object mPowerProfileLock = new Object(); + private final Object mProcessCpuTimeLock = new Object(); + private final Object mCpuTimePerThreadFreqLock = new Object(); + private final Object mDeviceCalculatedPowerUseLock = new Object(); + private final Object mDeviceCalculatedPowerBlameUidLock = new Object(); + private final Object mDeviceCalculatedPowerBlameOtherLock = new Object(); + private final Object mDebugElapsedClockLock = new Object(); + private final Object mDebugFailingElapsedClockLock = new Object(); + private final Object mBuildInformationLock = new Object(); + private final Object mRoleHolderLock = new Object(); + private final Object mTimeZoneDataInfoLock = new Object(); + private final Object mExternalStorageInfoLock = new Object(); + private final Object mAppsOnExternalStorageInfoLock = new Object(); + private final Object mFaceSettingsLock = new Object(); + private final Object mAppOpsLock = new Object(); + private final Object mRuntimeAppOpAccessMessageLock = new Object(); + private final Object mNotificationRemoteViewsLock = new Object(); + private final Object mDangerousPermissionStateLock = new Object(); + private final Object mHealthHalLock = new Object(); + private final Object mAttributedAppOpsLock = new Object(); + private final Object mSettingsStatsLock = new Object(); public StatsPullAtomService(Context context) { super(context); @@ -353,123 +418,229 @@ public class StatsPullAtomService extends SystemService { case FrameworkStatsLog.MOBILE_BYTES_TRANSFER_BY_FG_BG: case FrameworkStatsLog.BYTES_TRANSFER_BY_TAG_AND_METERED: case FrameworkStatsLog.DATA_USAGE_BYTES_TRANSFER: - return pullDataBytesTransfer(atomTag, data); + synchronized (mDataBytesTransferLock) { + return pullDataBytesTransferLocked(atomTag, data); + } case FrameworkStatsLog.BLUETOOTH_BYTES_TRANSFER: - return pullBluetoothBytesTransfer(atomTag, data); + synchronized (mBluetoothBytesTransferLock) { + return pullBluetoothBytesTransferLocked(atomTag, data); + } case FrameworkStatsLog.KERNEL_WAKELOCK: - return pullKernelWakelock(atomTag, data); + synchronized (mKernelWakelockLock) { + return pullKernelWakelockLocked(atomTag, data); + } case FrameworkStatsLog.CPU_TIME_PER_FREQ: - return pullCpuTimePerFreq(atomTag, data); + synchronized (mCpuTimePerFreqLock) { + return pullCpuTimePerFreqLocked(atomTag, data); + } case FrameworkStatsLog.CPU_TIME_PER_UID: - return pullCpuTimePerUid(atomTag, data); + synchronized (mCpuTimePerUidLock) { + return pullCpuTimePerUidLocked(atomTag, data); + } case FrameworkStatsLog.CPU_TIME_PER_UID_FREQ: - return pullCpuTimeperUidFreq(atomTag, data); + synchronized (mCpuTimePerUidFreqLock) { + return pullCpuTimePerUidFreqLocked(atomTag, data); + } case FrameworkStatsLog.CPU_ACTIVE_TIME: - return pullCpuActiveTime(atomTag, data); + synchronized (mCpuActiveTimeLock) { + return pullCpuActiveTimeLocked(atomTag, data); + } case FrameworkStatsLog.CPU_CLUSTER_TIME: - return pullCpuClusterTime(atomTag, data); + synchronized (mCpuClusterTimeLock) { + return pullCpuClusterTimeLocked(atomTag, data); + } case FrameworkStatsLog.WIFI_ACTIVITY_INFO: - return pullWifiActivityInfo(atomTag, data); + synchronized (mWifiActivityInfoLock) { + return pullWifiActivityInfoLocked(atomTag, data); + } case FrameworkStatsLog.MODEM_ACTIVITY_INFO: - return pullModemActivityInfo(atomTag, data); + synchronized (mModemActivityInfoLock) { + return pullModemActivityInfoLocked(atomTag, data); + } case FrameworkStatsLog.BLUETOOTH_ACTIVITY_INFO: - return pullBluetoothActivityInfo(atomTag, data); + synchronized (mBluetoothActivityInfoLock) { + return pullBluetoothActivityInfoLocked(atomTag, data); + } case FrameworkStatsLog.SYSTEM_ELAPSED_REALTIME: - return pullSystemElapsedRealtime(atomTag, data); + synchronized (mSystemElapsedRealtimeLock) { + return pullSystemElapsedRealtimeLocked(atomTag, data); + } case FrameworkStatsLog.SYSTEM_UPTIME: - return pullSystemUptime(atomTag, data); + synchronized (mSystemUptimeLock) { + return pullSystemUptimeLocked(atomTag, data); + } case FrameworkStatsLog.PROCESS_MEMORY_STATE: - return pullProcessMemoryState(atomTag, data); + synchronized (mProcessMemoryStateLock) { + return pullProcessMemoryStateLocked(atomTag, data); + } case FrameworkStatsLog.PROCESS_MEMORY_HIGH_WATER_MARK: - return pullProcessMemoryHighWaterMark(atomTag, data); + synchronized (mProcessMemoryHighWaterMarkLock) { + return pullProcessMemoryHighWaterMarkLocked(atomTag, data); + } case FrameworkStatsLog.PROCESS_MEMORY_SNAPSHOT: - return pullProcessMemorySnapshot(atomTag, data); + synchronized (mProcessMemorySnapshotLock) { + return pullProcessMemorySnapshotLocked(atomTag, data); + } case FrameworkStatsLog.SYSTEM_ION_HEAP_SIZE: - return pullSystemIonHeapSize(atomTag, data); + synchronized (mSystemIonHeapSizeLock) { + return pullSystemIonHeapSizeLocked(atomTag, data); + } case FrameworkStatsLog.ION_HEAP_SIZE: - return pullIonHeapSize(atomTag, data); + synchronized (mIonHeapSizeLock) { + return pullIonHeapSizeLocked(atomTag, data); + } case FrameworkStatsLog.PROCESS_SYSTEM_ION_HEAP_SIZE: - return pullProcessSystemIonHeapSize(atomTag, data); + synchronized (mProcessSystemIonHeapSizeLock) { + return pullProcessSystemIonHeapSizeLocked(atomTag, data); + } case FrameworkStatsLog.TEMPERATURE: - return pullTemperature(atomTag, data); + synchronized (mTemperatureLock) { + return pullTemperatureLocked(atomTag, data); + } case FrameworkStatsLog.COOLING_DEVICE: - return pullCooldownDevice(atomTag, data); + synchronized (mCooldownDeviceLock) { + return pullCooldownDeviceLocked(atomTag, data); + } case FrameworkStatsLog.BINDER_CALLS: - return pullBinderCallsStats(atomTag, data); + synchronized (mBinderCallsStatsLock) { + return pullBinderCallsStatsLocked(atomTag, data); + } case FrameworkStatsLog.BINDER_CALLS_EXCEPTIONS: - return pullBinderCallsStatsExceptions(atomTag, data); + synchronized (mBinderCallsStatsExceptionsLock) { + return pullBinderCallsStatsExceptionsLocked(atomTag, data); + } case FrameworkStatsLog.LOOPER_STATS: - return pullLooperStats(atomTag, data); + synchronized (mLooperStatsLock) { + return pullLooperStatsLocked(atomTag, data); + } case FrameworkStatsLog.DISK_STATS: - return pullDiskStats(atomTag, data); + synchronized (mDiskStatsLock) { + return pullDiskStatsLocked(atomTag, data); + } case FrameworkStatsLog.DIRECTORY_USAGE: - return pullDirectoryUsage(atomTag, data); + synchronized (mDirectoryUsageLock) { + return pullDirectoryUsageLocked(atomTag, data); + } case FrameworkStatsLog.APP_SIZE: - return pullAppSize(atomTag, data); + synchronized (mAppSizeLock) { + return pullAppSizeLocked(atomTag, data); + } case FrameworkStatsLog.CATEGORY_SIZE: - return pullCategorySize(atomTag, data); + synchronized (mCategorySizeLock) { + return pullCategorySizeLocked(atomTag, data); + } case FrameworkStatsLog.NUM_FINGERPRINTS_ENROLLED: - return pullNumBiometricsEnrolled( - BiometricsProtoEnums.MODALITY_FINGERPRINT, atomTag, data); + synchronized (mNumBiometricsEnrolledLock) { + return pullNumBiometricsEnrolledLocked( + BiometricsProtoEnums.MODALITY_FINGERPRINT, atomTag, data); + } case FrameworkStatsLog.NUM_FACES_ENROLLED: - return pullNumBiometricsEnrolled( - BiometricsProtoEnums.MODALITY_FACE, atomTag, data); + synchronized (mNumBiometricsEnrolledLock) { + return pullNumBiometricsEnrolledLocked( + BiometricsProtoEnums.MODALITY_FACE, atomTag, data); + } case FrameworkStatsLog.PROC_STATS: - return pullProcStats(ProcessStats.REPORT_ALL, atomTag, data); + synchronized (mProcStatsLock) { + return pullProcStatsLocked(ProcessStats.REPORT_ALL, atomTag, data); + } case FrameworkStatsLog.PROC_STATS_PKG_PROC: - return pullProcStats(ProcessStats.REPORT_PKG_PROC_STATS, atomTag, data); + synchronized (mProcStatsLock) { + return pullProcStatsLocked(ProcessStats.REPORT_PKG_PROC_STATS, atomTag, + data); + } case FrameworkStatsLog.DISK_IO: - return pullDiskIO(atomTag, data); + synchronized (mDiskIoLock) { + return pullDiskIOLocked(atomTag, data); + } case FrameworkStatsLog.POWER_PROFILE: - return pullPowerProfile(atomTag, data); + synchronized (mPowerProfileLock) { + return pullPowerProfileLocked(atomTag, data); + } case FrameworkStatsLog.PROCESS_CPU_TIME: - return pullProcessCpuTime(atomTag, data); + synchronized (mProcessCpuTimeLock) { + return pullProcessCpuTimeLocked(atomTag, data); + } case FrameworkStatsLog.CPU_TIME_PER_THREAD_FREQ: - return pullCpuTimePerThreadFreq(atomTag, data); + synchronized (mCpuTimePerThreadFreqLock) { + return pullCpuTimePerThreadFreqLocked(atomTag, data); + } case FrameworkStatsLog.DEVICE_CALCULATED_POWER_USE: - return pullDeviceCalculatedPowerUse(atomTag, data); + synchronized (mDeviceCalculatedPowerUseLock) { + return pullDeviceCalculatedPowerUseLocked(atomTag, data); + } case FrameworkStatsLog.DEVICE_CALCULATED_POWER_BLAME_UID: - return pullDeviceCalculatedPowerBlameUid(atomTag, data); + synchronized (mDeviceCalculatedPowerBlameUidLock) { + return pullDeviceCalculatedPowerBlameUidLocked(atomTag, data); + } case FrameworkStatsLog.DEVICE_CALCULATED_POWER_BLAME_OTHER: - return pullDeviceCalculatedPowerBlameOther(atomTag, data); + synchronized (mDeviceCalculatedPowerBlameOtherLock) { + return pullDeviceCalculatedPowerBlameOtherLocked(atomTag, data); + } case FrameworkStatsLog.DEBUG_ELAPSED_CLOCK: - return pullDebugElapsedClock(atomTag, data); + synchronized (mDebugElapsedClockLock) { + return pullDebugElapsedClockLocked(atomTag, data); + } case FrameworkStatsLog.DEBUG_FAILING_ELAPSED_CLOCK: - return pullDebugFailingElapsedClock(atomTag, data); + synchronized (mDebugFailingElapsedClockLock) { + return pullDebugFailingElapsedClockLocked(atomTag, data); + } case FrameworkStatsLog.BUILD_INFORMATION: - return pullBuildInformation(atomTag, data); + synchronized (mBuildInformationLock) { + return pullBuildInformationLocked(atomTag, data); + } case FrameworkStatsLog.ROLE_HOLDER: - return pullRoleHolder(atomTag, data); + synchronized (mRoleHolderLock) { + return pullRoleHolderLocked(atomTag, data); + } case FrameworkStatsLog.DANGEROUS_PERMISSION_STATE: - return pullDangerousPermissionState(atomTag, data); + case FrameworkStatsLog.DANGEROUS_PERMISSION_STATE_SAMPLED: + synchronized (mDangerousPermissionStateLock) { + return pullDangerousPermissionStateLocked(atomTag, data); + } case FrameworkStatsLog.TIME_ZONE_DATA_INFO: - return pullTimeZoneDataInfo(atomTag, data); + synchronized (mTimeZoneDataInfoLock) { + return pullTimeZoneDataInfoLocked(atomTag, data); + } case FrameworkStatsLog.EXTERNAL_STORAGE_INFO: - return pullExternalStorageInfo(atomTag, data); + synchronized (mExternalStorageInfoLock) { + return pullExternalStorageInfoLocked(atomTag, data); + } case FrameworkStatsLog.APPS_ON_EXTERNAL_STORAGE_INFO: - return pullAppsOnExternalStorageInfo(atomTag, data); + synchronized (mAppsOnExternalStorageInfoLock) { + return pullAppsOnExternalStorageInfoLocked(atomTag, data); + } case FrameworkStatsLog.FACE_SETTINGS: - return pullFaceSettings(atomTag, data); + synchronized (mFaceSettingsLock) { + return pullFaceSettingsLocked(atomTag, data); + } case FrameworkStatsLog.APP_OPS: - return pullAppOps(atomTag, data); + synchronized (mAppOpsLock) { + return pullAppOpsLocked(atomTag, data); + } case FrameworkStatsLog.RUNTIME_APP_OP_ACCESS: - return pullRuntimeAppOpAccessMessage(atomTag, data); + synchronized (mRuntimeAppOpAccessMessageLock) { + return pullRuntimeAppOpAccessMessageLocked(atomTag, data); + } case FrameworkStatsLog.NOTIFICATION_REMOTE_VIEWS: - return pullNotificationRemoteViews(atomTag, data); - case FrameworkStatsLog.DANGEROUS_PERMISSION_STATE_SAMPLED: - return pullDangerousPermissionState(atomTag, data); + synchronized (mNotificationRemoteViewsLock) { + return pullNotificationRemoteViewsLocked(atomTag, data); + } case FrameworkStatsLog.BATTERY_LEVEL: case FrameworkStatsLog.REMAINING_BATTERY_CAPACITY: case FrameworkStatsLog.FULL_BATTERY_CAPACITY: case FrameworkStatsLog.BATTERY_VOLTAGE: case FrameworkStatsLog.BATTERY_CYCLE_COUNT: - return pullHealthHal(atomTag, data); + synchronized (mHealthHalLock) { + return pullHealthHalLocked(atomTag, data); + } case FrameworkStatsLog.ATTRIBUTED_APP_OPS: - return pullAttributedAppOps(atomTag, data); + synchronized (mAttributedAppOpsLock) { + return pullAttributedAppOpsLocked(atomTag, data); + } case FrameworkStatsLog.SETTING_SNAPSHOT: - return pullSettingsStats(atomTag, data); - case FrameworkStatsLog.DISPLAY_WAKE_REASON: - return pullDisplayWakeStats(atomTag, data); + synchronized (mSettingsStatsLock) { + return pullSettingsStatsLocked(atomTag, data); + } default: throw new UnsupportedOperationException("Unknown tagId=" + atomTag); } @@ -500,6 +671,8 @@ public class StatsPullAtomService extends SystemService { } } + // We do not hold locks within this function because it is guaranteed to be called before the + // pullers are ever run, as the pullers are not yet registered with statsd. void initializePullersState() { // Get Context Managers mStatsManager = (StatsManager) mContext.getSystemService(Context.STATS_MANAGER); @@ -515,6 +688,7 @@ public class StatsPullAtomService extends SystemService { // Initialize PROC_STATS mBaseDir = new File(SystemServiceManager.ensureSystemDir(), "stats_pull"); + mBaseDir.mkdirs(); // Disables throttler on CPU time readers. mCpuUidUserSysTimeReader = new KernelCpuUidUserSysTimeReader(false); @@ -542,9 +716,6 @@ public class StatsPullAtomService extends SystemService { mKernelCpuThreadReader = KernelCpuThreadReaderSettingsObserver.getSettingsModifiedReader(mContext); - // Used by PROC_STATS and PROC_STATS_PKG_PROC atoms - mBaseDir.mkdirs(); - // Initialize HealthService mHealthService = new BatteryService.HealthServiceWrapper(); try { @@ -656,7 +827,6 @@ public class StatsPullAtomService extends SystemService { registerBatteryVoltage(); registerBatteryCycleCount(); registerSettingsStats(); - registerDisplayWakeStats(); } private void initAndRegisterNetworkStatsPullers() { @@ -783,7 +953,7 @@ public class StatsPullAtomService extends SystemService { } private IProcessStats getIProcessStatsService() { - synchronized (mProcessStatsLock) { + synchronized (mProcStatsLock) { if (mProcessStatsService == null) { mProcessStatsService = IProcessStats.Stub.asInterface( ServiceManager.getService(ProcessStats.SERVICE_NAME)); @@ -791,7 +961,7 @@ public class StatsPullAtomService extends SystemService { if (mProcessStatsService != null) { try { mProcessStatsService.asBinder().linkToDeath(() -> { - synchronized (mProcessStatsLock) { + synchronized (mProcStatsLock) { mProcessStatsService = null; } }, /* flags */ 0); @@ -882,8 +1052,7 @@ public class StatsPullAtomService extends SystemService { return ret; } - private int pullDataBytesTransfer( - int atomTag, @NonNull List<StatsEvent> pulledData) { + private int pullDataBytesTransferLocked(int atomTag, @NonNull List<StatsEvent> pulledData) { final List<NetworkStatsExt> current = collectNetworkStatsSnapshotForAtom(atomTag); if (current == null) { @@ -1237,12 +1406,11 @@ public class StatsPullAtomService extends SystemService { return null; } - private synchronized BluetoothActivityEnergyInfo fetchBluetoothData() { - // TODO: Investigate whether the synchronized keyword is needed. + private BluetoothActivityEnergyInfo fetchBluetoothData() { final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); if (adapter != null) { - SynchronousResultReceiver bluetoothReceiver = new SynchronousResultReceiver( - "bluetooth"); + SynchronousResultReceiver bluetoothReceiver = + new SynchronousResultReceiver("bluetooth"); adapter.requestControllerActivityEnergyInfo(bluetoothReceiver); return awaitControllerInfo(bluetoothReceiver); } else { @@ -1251,7 +1419,7 @@ public class StatsPullAtomService extends SystemService { } } - int pullBluetoothBytesTransfer(int atomTag, List<StatsEvent> pulledData) { + int pullBluetoothBytesTransferLocked(int atomTag, List<StatsEvent> pulledData) { BluetoothActivityEnergyInfo info = fetchBluetoothData(); if (info == null || info.getUidTraffic() == null) { return StatsManager.PULL_SKIP; @@ -1279,7 +1447,7 @@ public class StatsPullAtomService extends SystemService { ); } - int pullKernelWakelock(int atomTag, List<StatsEvent> pulledData) { + int pullKernelWakelockLocked(int atomTag, List<StatsEvent> pulledData) { final KernelWakelockStats wakelockStats = mKernelWakelockReader.readKernelWakelockStats(mTmpWakelockStats); for (Map.Entry<String, KernelWakelockStats.Entry> ent : wakelockStats.entrySet()) { @@ -1310,7 +1478,7 @@ public class StatsPullAtomService extends SystemService { ); } - int pullCpuTimePerFreq(int atomTag, List<StatsEvent> pulledData) { + int pullCpuTimePerFreqLocked(int atomTag, List<StatsEvent> pulledData) { for (int cluster = 0; cluster < mKernelCpuSpeedReaders.length; cluster++) { long[] clusterTimeMs = mKernelCpuSpeedReaders[cluster].readAbsolute(); if (clusterTimeMs != null) { @@ -1341,7 +1509,7 @@ public class StatsPullAtomService extends SystemService { ); } - int pullCpuTimePerUid(int atomTag, List<StatsEvent> pulledData) { + int pullCpuTimePerUidLocked(int atomTag, List<StatsEvent> pulledData) { mCpuUidUserSysTimeReader.readAbsolute((uid, timesUs) -> { long userTimeUs = timesUs[0], systemTimeUs = timesUs[1]; StatsEvent e = StatsEvent.newBuilder() @@ -1371,7 +1539,7 @@ public class StatsPullAtomService extends SystemService { ); } - int pullCpuTimeperUidFreq(int atomTag, List<StatsEvent> pulledData) { + int pullCpuTimePerUidFreqLocked(int atomTag, List<StatsEvent> pulledData) { mCpuUidFreqTimeReader.readAbsolute((uid, cpuFreqTimeMs) -> { for (int freqIndex = 0; freqIndex < cpuFreqTimeMs.length; ++freqIndex) { if (cpuFreqTimeMs[freqIndex] != 0) { @@ -1404,7 +1572,7 @@ public class StatsPullAtomService extends SystemService { ); } - int pullCpuActiveTime(int atomTag, List<StatsEvent> pulledData) { + int pullCpuActiveTimeLocked(int atomTag, List<StatsEvent> pulledData) { mCpuUidActiveTimeReader.readAbsolute((uid, cpuActiveTimesMs) -> { StatsEvent e = StatsEvent.newBuilder() .setAtomId(atomTag) @@ -1432,7 +1600,7 @@ public class StatsPullAtomService extends SystemService { ); } - int pullCpuClusterTime(int atomTag, List<StatsEvent> pulledData) { + int pullCpuClusterTimeLocked(int atomTag, List<StatsEvent> pulledData) { mCpuUidClusterTimeReader.readAbsolute((uid, cpuClusterTimesMs) -> { for (int i = 0; i < cpuClusterTimesMs.length; i++) { StatsEvent e = StatsEvent.newBuilder() @@ -1458,7 +1626,7 @@ public class StatsPullAtomService extends SystemService { ); } - int pullWifiActivityInfo(int atomTag, List<StatsEvent> pulledData) { + int pullWifiActivityInfoLocked(int atomTag, List<StatsEvent> pulledData) { long token = Binder.clearCallingIdentity(); try { SynchronousResultReceiver wifiReceiver = new SynchronousResultReceiver("wifi"); @@ -1510,7 +1678,7 @@ public class StatsPullAtomService extends SystemService { ); } - int pullModemActivityInfo(int atomTag, List<StatsEvent> pulledData) { + int pullModemActivityInfoLocked(int atomTag, List<StatsEvent> pulledData) { long token = Binder.clearCallingIdentity(); try { SynchronousResultReceiver modemReceiver = new SynchronousResultReceiver("telephony"); @@ -1548,7 +1716,7 @@ public class StatsPullAtomService extends SystemService { ); } - int pullBluetoothActivityInfo(int atomTag, List<StatsEvent> pulledData) { + int pullBluetoothActivityInfoLocked(int atomTag, List<StatsEvent> pulledData) { BluetoothActivityEnergyInfo info = fetchBluetoothData(); if (info == null) { return StatsManager.PULL_SKIP; @@ -1580,7 +1748,7 @@ public class StatsPullAtomService extends SystemService { ); } - int pullSystemElapsedRealtime(int atomTag, List<StatsEvent> pulledData) { + int pullSystemElapsedRealtimeLocked(int atomTag, List<StatsEvent> pulledData) { StatsEvent e = StatsEvent.newBuilder() .setAtomId(atomTag) .writeLong(SystemClock.elapsedRealtime()) @@ -1599,7 +1767,7 @@ public class StatsPullAtomService extends SystemService { ); } - int pullSystemUptime(int atomTag, List<StatsEvent> pulledData) { + int pullSystemUptimeLocked(int atomTag, List<StatsEvent> pulledData) { StatsEvent e = StatsEvent.newBuilder() .setAtomId(atomTag) .writeLong(SystemClock.uptimeMillis()) @@ -1621,7 +1789,7 @@ public class StatsPullAtomService extends SystemService { ); } - int pullProcessMemoryState(int atomTag, List<StatsEvent> pulledData) { + int pullProcessMemoryStateLocked(int atomTag, List<StatsEvent> pulledData) { List<ProcessMemoryState> processMemoryStates = LocalServices.getService(ActivityManagerInternal.class) .getMemoryStateForProcesses(); @@ -1665,7 +1833,7 @@ public class StatsPullAtomService extends SystemService { ); } - int pullProcessMemoryHighWaterMark(int atomTag, List<StatsEvent> pulledData) { + int pullProcessMemoryHighWaterMarkLocked(int atomTag, List<StatsEvent> pulledData) { List<ProcessMemoryState> managedProcessList = LocalServices.getService(ActivityManagerInternal.class) .getMemoryStateForProcesses(); @@ -1720,7 +1888,7 @@ public class StatsPullAtomService extends SystemService { ); } - int pullProcessMemorySnapshot(int atomTag, List<StatsEvent> pulledData) { + int pullProcessMemorySnapshotLocked(int atomTag, List<StatsEvent> pulledData) { List<ProcessMemoryState> managedProcessList = LocalServices.getService(ActivityManagerInternal.class) .getMemoryStateForProcesses(); @@ -1782,7 +1950,7 @@ public class StatsPullAtomService extends SystemService { ); } - int pullSystemIonHeapSize(int atomTag, List<StatsEvent> pulledData) { + int pullSystemIonHeapSizeLocked(int atomTag, List<StatsEvent> pulledData) { final long systemIonHeapSizeInBytes = readSystemIonHeapSizeFromDebugfs(); StatsEvent e = StatsEvent.newBuilder() .setAtomId(atomTag) @@ -1805,7 +1973,7 @@ public class StatsPullAtomService extends SystemService { ); } - int pullIonHeapSize(int atomTag, List<StatsEvent> pulledData) { + int pullIonHeapSizeLocked(int atomTag, List<StatsEvent> pulledData) { int ionHeapSizeInKilobytes = (int) getIonHeapsSizeKb(); StatsEvent e = StatsEvent.newBuilder() .setAtomId(atomTag) @@ -1825,7 +1993,7 @@ public class StatsPullAtomService extends SystemService { ); } - int pullProcessSystemIonHeapSize(int atomTag, List<StatsEvent> pulledData) { + int pullProcessSystemIonHeapSizeLocked(int atomTag, List<StatsEvent> pulledData) { List<IonAllocations> result = readProcessSystemIonHeapSizesFromDebugfs(); for (IonAllocations allocations : result) { StatsEvent e = StatsEvent.newBuilder() @@ -1852,7 +2020,7 @@ public class StatsPullAtomService extends SystemService { ); } - int pullTemperature(int atomTag, List<StatsEvent> pulledData) { + int pullTemperatureLocked(int atomTag, List<StatsEvent> pulledData) { IThermalService thermalService = getIThermalService(); if (thermalService == null) { return StatsManager.PULL_SKIP; @@ -1890,7 +2058,7 @@ public class StatsPullAtomService extends SystemService { ); } - int pullCooldownDevice(int atomTag, List<StatsEvent> pulledData) { + int pullCooldownDeviceLocked(int atomTag, List<StatsEvent> pulledData) { IThermalService thermalService = getIThermalService(); if (thermalService == null) { return StatsManager.PULL_SKIP; @@ -1930,7 +2098,7 @@ public class StatsPullAtomService extends SystemService { ); } - int pullBinderCallsStats(int atomTag, List<StatsEvent> pulledData) { + int pullBinderCallsStatsLocked(int atomTag, List<StatsEvent> pulledData) { BinderCallsStatsService.Internal binderStats = LocalServices.getService(BinderCallsStatsService.Internal.class); if (binderStats == null) { @@ -1974,7 +2142,7 @@ public class StatsPullAtomService extends SystemService { ); } - int pullBinderCallsStatsExceptions(int atomTag, List<StatsEvent> pulledData) { + int pullBinderCallsStatsExceptionsLocked(int atomTag, List<StatsEvent> pulledData) { BinderCallsStatsService.Internal binderStats = LocalServices.getService(BinderCallsStatsService.Internal.class); if (binderStats == null) { @@ -2009,7 +2177,7 @@ public class StatsPullAtomService extends SystemService { ); } - int pullLooperStats(int atomTag, List<StatsEvent> pulledData) { + int pullLooperStatsLocked(int atomTag, List<StatsEvent> pulledData) { LooperStats looperStats = LocalServices.getService(LooperStats.class); if (looperStats == null) { return StatsManager.PULL_SKIP; @@ -2052,7 +2220,7 @@ public class StatsPullAtomService extends SystemService { ); } - int pullDiskStats(int atomTag, List<StatsEvent> pulledData) { + int pullDiskStatsLocked(int atomTag, List<StatsEvent> pulledData) { // Run a quick-and-dirty performance test: write 512 bytes byte[] junk = new byte[512]; for (int i = 0; i < junk.length; i++) junk[i] = (byte) i; // Write nonzero bytes @@ -2118,7 +2286,7 @@ public class StatsPullAtomService extends SystemService { ); } - int pullDirectoryUsage(int atomTag, List<StatsEvent> pulledData) { + int pullDirectoryUsageLocked(int atomTag, List<StatsEvent> pulledData) { StatFs statFsData = new StatFs(Environment.getDataDirectory().getAbsolutePath()); StatFs statFsSystem = new StatFs(Environment.getRootDirectory().getAbsolutePath()); StatFs statFsCache = new StatFs(Environment.getDownloadCacheDirectory().getAbsolutePath()); @@ -2159,7 +2327,7 @@ public class StatsPullAtomService extends SystemService { ); } - int pullAppSize(int atomTag, List<StatsEvent> pulledData) { + int pullAppSizeLocked(int atomTag, List<StatsEvent> pulledData) { try { String jsonStr = IoUtils.readFileAsString(DiskStatsLoggingService.DUMPSYS_CACHE_PATH); JSONObject json = new JSONObject(jsonStr); @@ -2203,7 +2371,7 @@ public class StatsPullAtomService extends SystemService { ); } - int pullCategorySize(int atomTag, List<StatsEvent> pulledData) { + int pullCategorySizeLocked(int atomTag, List<StatsEvent> pulledData) { try { String jsonStr = IoUtils.readFileAsString(DiskStatsLoggingService.DUMPSYS_CACHE_PATH); JSONObject json = new JSONObject(jsonStr); @@ -2317,7 +2485,8 @@ public class StatsPullAtomService extends SystemService { ); } - private int pullNumBiometricsEnrolled(int modality, int atomTag, List<StatsEvent> pulledData) { + private int pullNumBiometricsEnrolledLocked(int modality, int atomTag, + List<StatsEvent> pulledData) { final PackageManager pm = mContext.getPackageManager(); FingerprintManager fingerprintManager = null; FaceManager faceManager = null; @@ -2385,43 +2554,41 @@ public class StatsPullAtomService extends SystemService { ); } - private int pullProcStats(int section, int atomTag, List<StatsEvent> pulledData) { + private int pullProcStatsLocked(int section, int atomTag, List<StatsEvent> pulledData) { IProcessStats processStatsService = getIProcessStatsService(); if (processStatsService == null) { return StatsManager.PULL_SKIP; } - synchronized (mProcessStatsLock) { - final long token = Binder.clearCallingIdentity(); - try { - // force procstats to flush & combine old files into one store - long lastHighWaterMark = readProcStatsHighWaterMark(section); - List<ParcelFileDescriptor> statsFiles = new ArrayList<>(); + final long token = Binder.clearCallingIdentity(); + try { + // force procstats to flush & combine old files into one store + long lastHighWaterMark = readProcStatsHighWaterMark(section); + List<ParcelFileDescriptor> statsFiles = new ArrayList<>(); - ProcessStats procStats = new ProcessStats(false); - long highWaterMark = processStatsService.getCommittedStatsMerged( - lastHighWaterMark, section, true, statsFiles, procStats); + ProcessStats procStats = new ProcessStats(false); + long highWaterMark = processStatsService.getCommittedStatsMerged( + lastHighWaterMark, section, true, statsFiles, procStats); - // aggregate the data together for westworld consumption - ProtoOutputStream proto = new ProtoOutputStream(); - procStats.dumpAggregatedProtoForStatsd(proto); + // aggregate the data together for westworld consumption + ProtoOutputStream proto = new ProtoOutputStream(); + procStats.dumpAggregatedProtoForStatsd(proto); - StatsEvent e = StatsEvent.newBuilder() - .setAtomId(atomTag) - .writeByteArray(proto.getBytes()) - .build(); - pulledData.add(e); + StatsEvent e = StatsEvent.newBuilder() + .setAtomId(atomTag) + .writeByteArray(proto.getBytes()) + .build(); + pulledData.add(e); - new File(mBaseDir.getAbsolutePath() + "/" + section + "_" + lastHighWaterMark) - .delete(); - new File(mBaseDir.getAbsolutePath() + "/" + section + "_" + highWaterMark) - .createNewFile(); - } catch (RemoteException | IOException e) { - Slog.e(TAG, "Getting procstats failed: ", e); - return StatsManager.PULL_SKIP; - } finally { - Binder.restoreCallingIdentity(token); - } + new File(mBaseDir.getAbsolutePath() + "/" + section + "_" + lastHighWaterMark) + .delete(); + new File(mBaseDir.getAbsolutePath() + "/" + section + "_" + highWaterMark) + .createNewFile(); + } catch (RemoteException | IOException e) { + Slog.e(TAG, "Getting procstats failed: ", e); + return StatsManager.PULL_SKIP; + } finally { + Binder.restoreCallingIdentity(token); } return StatsManager.PULL_SUCCESS; } @@ -2461,7 +2628,7 @@ public class StatsPullAtomService extends SystemService { ); } - int pullDiskIO(int atomTag, List<StatsEvent> pulledData) { + int pullDiskIOLocked(int atomTag, List<StatsEvent> pulledData) { mStoragedUidIoStatsReader.readAbsolute((uid, fgCharsRead, fgCharsWrite, fgBytesRead, fgBytesWrite, bgCharsRead, bgCharsWrite, bgBytesRead, bgBytesWrite, fgFsync, bgFsync) -> { @@ -2495,7 +2662,7 @@ public class StatsPullAtomService extends SystemService { ); } - int pullPowerProfile(int atomTag, List<StatsEvent> pulledData) { + int pullPowerProfileLocked(int atomTag, List<StatsEvent> pulledData) { PowerProfile powerProfile = new PowerProfile(mContext); ProtoOutputStream proto = new ProtoOutputStream(); powerProfile.dumpDebug(proto); @@ -2522,25 +2689,23 @@ public class StatsPullAtomService extends SystemService { ); } - int pullProcessCpuTime(int atomTag, List<StatsEvent> pulledData) { - synchronized (mCpuTrackerLock) { - if (mProcessCpuTracker == null) { - mProcessCpuTracker = new ProcessCpuTracker(false); - mProcessCpuTracker.init(); - } - mProcessCpuTracker.update(); - for (int i = 0; i < mProcessCpuTracker.countStats(); i++) { - ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); - StatsEvent e = StatsEvent.newBuilder() - .setAtomId(atomTag) - .writeInt(st.uid) - .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true) - .writeString(st.name) - .writeLong(st.base_utime) - .writeLong(st.base_stime) - .build(); - pulledData.add(e); - } + int pullProcessCpuTimeLocked(int atomTag, List<StatsEvent> pulledData) { + if (mProcessCpuTracker == null) { + mProcessCpuTracker = new ProcessCpuTracker(false); + mProcessCpuTracker.init(); + } + mProcessCpuTracker.update(); + for (int i = 0; i < mProcessCpuTracker.countStats(); i++) { + ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); + StatsEvent e = StatsEvent.newBuilder() + .setAtomId(atomTag) + .writeInt(st.uid) + .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true) + .writeString(st.name) + .writeLong(st.base_utime) + .writeLong(st.base_stime) + .build(); + pulledData.add(e); } return StatsManager.PULL_SUCCESS; } @@ -2558,7 +2723,7 @@ public class StatsPullAtomService extends SystemService { ); } - int pullCpuTimePerThreadFreq(int atomTag, List<StatsEvent> pulledData) { + int pullCpuTimePerThreadFreqLocked(int atomTag, List<StatsEvent> pulledData) { if (this.mKernelCpuThreadReader == null) { Slog.e(TAG, "mKernelCpuThreadReader is null"); return StatsManager.PULL_SKIP; @@ -2617,23 +2782,27 @@ public class StatsPullAtomService extends SystemService { } private BatteryStatsHelper getBatteryStatsHelper() { - if (mBatteryStatsHelper == null) { - final long callingToken = Binder.clearCallingIdentity(); - try { - // clearCallingIdentity required for BatteryStatsHelper.checkWifiOnly(). - mBatteryStatsHelper = new BatteryStatsHelper(mContext, false); - } finally { - Binder.restoreCallingIdentity(callingToken); + synchronized (mBatteryStatsHelperLock) { + if (mBatteryStatsHelper == null) { + final long callingToken = Binder.clearCallingIdentity(); + try { + // clearCallingIdentity required for BatteryStatsHelper.checkWifiOnly(). + mBatteryStatsHelper = new BatteryStatsHelper(mContext, false); + } finally { + Binder.restoreCallingIdentity(callingToken); + } + mBatteryStatsHelper.create((Bundle) null); + } + long currentTime = SystemClock.elapsedRealtime(); + if (currentTime - mBatteryStatsHelperTimestampMs + >= MAX_BATTERY_STATS_HELPER_FREQUENCY_MS) { + // Load BatteryStats and do all the calculations. + mBatteryStatsHelper.refreshStats(BatteryStats.STATS_SINCE_CHARGED, + UserHandle.USER_ALL); + // Calculations are done so we don't need to save the raw BatteryStats data in RAM. + mBatteryStatsHelper.clearStats(); + mBatteryStatsHelperTimestampMs = currentTime; } - mBatteryStatsHelper.create((Bundle) null); - } - long currentTime = SystemClock.elapsedRealtime(); - if (currentTime - mBatteryStatsHelperTimestampMs >= MAX_BATTERY_STATS_HELPER_FREQUENCY_MS) { - // Load BatteryStats and do all the calculations. - mBatteryStatsHelper.refreshStats(BatteryStats.STATS_SINCE_CHARGED, UserHandle.USER_ALL); - // Calculations are done so we don't need to save the raw BatteryStats data in RAM. - mBatteryStatsHelper.clearStats(); - mBatteryStatsHelperTimestampMs = currentTime; } return mBatteryStatsHelper; } @@ -2652,7 +2821,7 @@ public class StatsPullAtomService extends SystemService { ); } - int pullDeviceCalculatedPowerUse(int atomTag, List<StatsEvent> pulledData) { + int pullDeviceCalculatedPowerUseLocked(int atomTag, List<StatsEvent> pulledData) { BatteryStatsHelper bsHelper = getBatteryStatsHelper(); StatsEvent e = StatsEvent.newBuilder() .setAtomId(atomTag) @@ -2672,7 +2841,7 @@ public class StatsPullAtomService extends SystemService { ); } - int pullDeviceCalculatedPowerBlameUid(int atomTag, List<StatsEvent> pulledData) { + int pullDeviceCalculatedPowerBlameUidLocked(int atomTag, List<StatsEvent> pulledData) { final List<BatterySipper> sippers = getBatteryStatsHelper().getUsageList(); if (sippers == null) { return StatsManager.PULL_SKIP; @@ -2703,7 +2872,7 @@ public class StatsPullAtomService extends SystemService { ); } - int pullDeviceCalculatedPowerBlameOther(int atomTag, List<StatsEvent> pulledData) { + int pullDeviceCalculatedPowerBlameOtherLocked(int atomTag, List<StatsEvent> pulledData) { final List<BatterySipper> sippers = getBatteryStatsHelper().getUsageList(); if (sippers == null) { return StatsManager.PULL_SKIP; @@ -2739,41 +2908,37 @@ public class StatsPullAtomService extends SystemService { ); } - int pullDebugElapsedClock(int atomTag, List<StatsEvent> pulledData) { + int pullDebugElapsedClockLocked(int atomTag, List<StatsEvent> pulledData) { final long elapsedMillis = SystemClock.elapsedRealtime(); + final long clockDiffMillis = mDebugElapsedClockPreviousValue == 0 + ? 0 : elapsedMillis - mDebugElapsedClockPreviousValue; - synchronized (mDebugElapsedClockLock) { - final long clockDiffMillis = mDebugElapsedClockPreviousValue == 0 - ? 0 : elapsedMillis - mDebugElapsedClockPreviousValue; + StatsEvent e = StatsEvent.newBuilder() + .setAtomId(atomTag) + .writeLong(mDebugElapsedClockPullCount) + .writeLong(elapsedMillis) + // Log it twice to be able to test multi-value aggregation from ValueMetric. + .writeLong(elapsedMillis) + .writeLong(clockDiffMillis) + .writeInt(1 /* always set */) + .build(); + pulledData.add(e); - StatsEvent e = StatsEvent.newBuilder() + if (mDebugElapsedClockPullCount % 2 == 1) { + StatsEvent e2 = StatsEvent.newBuilder() .setAtomId(atomTag) .writeLong(mDebugElapsedClockPullCount) .writeLong(elapsedMillis) // Log it twice to be able to test multi-value aggregation from ValueMetric. .writeLong(elapsedMillis) .writeLong(clockDiffMillis) - .writeInt(1 /* always set */) + .writeInt(2 /* set on odd pulls */) .build(); - pulledData.add(e); - - if (mDebugElapsedClockPullCount % 2 == 1) { - StatsEvent e2 = StatsEvent.newBuilder() - .setAtomId(atomTag) - .writeLong(mDebugElapsedClockPullCount) - .writeLong(elapsedMillis) - // Log it twice to be able to test multi-value aggregation from ValueMetric. - .writeLong(elapsedMillis) - .writeLong(clockDiffMillis) - .writeInt(2 /* set on odd pulls */) - .build(); - pulledData.add(e2); - } - - mDebugElapsedClockPullCount++; - mDebugElapsedClockPreviousValue = elapsedMillis; + pulledData.add(e2); } + mDebugElapsedClockPullCount++; + mDebugElapsedClockPreviousValue = elapsedMillis; return StatsManager.PULL_SUCCESS; } @@ -2790,31 +2955,27 @@ public class StatsPullAtomService extends SystemService { ); } - int pullDebugFailingElapsedClock(int atomTag, List<StatsEvent> pulledData) { + int pullDebugFailingElapsedClockLocked(int atomTag, List<StatsEvent> pulledData) { final long elapsedMillis = SystemClock.elapsedRealtime(); - - synchronized (mDebugFailingElapsedClockLock) { - // Fails every 5 buckets. - if (mDebugFailingElapsedClockPullCount++ % 5 == 0) { - mDebugFailingElapsedClockPreviousValue = elapsedMillis; - Slog.e(TAG, "Failing debug elapsed clock"); - return StatsManager.PULL_SKIP; - } - - StatsEvent e = StatsEvent.newBuilder() - .setAtomId(atomTag) - .writeLong(mDebugFailingElapsedClockPullCount) - .writeLong(elapsedMillis) - // Log it twice to be able to test multi-value aggregation from ValueMetric. - .writeLong(elapsedMillis) - .writeLong(mDebugFailingElapsedClockPreviousValue == 0 - ? 0 : elapsedMillis - mDebugFailingElapsedClockPreviousValue) - .build(); - pulledData.add(e); - + // Fails every 5 buckets. + if (mDebugFailingElapsedClockPullCount++ % 5 == 0) { mDebugFailingElapsedClockPreviousValue = elapsedMillis; + Slog.e(TAG, "Failing debug elapsed clock"); + return StatsManager.PULL_SKIP; } + StatsEvent e = StatsEvent.newBuilder() + .setAtomId(atomTag) + .writeLong(mDebugFailingElapsedClockPullCount) + .writeLong(elapsedMillis) + // Log it twice to be able to test multi-value aggregation from ValueMetric. + .writeLong(elapsedMillis) + .writeLong(mDebugFailingElapsedClockPreviousValue == 0 + ? 0 : elapsedMillis - mDebugFailingElapsedClockPreviousValue) + .build(); + pulledData.add(e); + + mDebugFailingElapsedClockPreviousValue = elapsedMillis; return StatsManager.PULL_SUCCESS; } @@ -2828,7 +2989,7 @@ public class StatsPullAtomService extends SystemService { ); } - int pullBuildInformation(int atomTag, List<StatsEvent> pulledData) { + int pullBuildInformationLocked(int atomTag, List<StatsEvent> pulledData) { StatsEvent e = StatsEvent.newBuilder() .setAtomId(atomTag) .writeString(Build.FINGERPRINT) @@ -2856,7 +3017,7 @@ public class StatsPullAtomService extends SystemService { } // Add a RoleHolder atom for each package that holds a role. - int pullRoleHolder(int atomTag, List<StatsEvent> pulledData) { + int pullRoleHolderLocked(int atomTag, List<StatsEvent> pulledData) { long callingToken = Binder.clearCallingIdentity(); try { PackageManager pm = mContext.getPackageManager(); @@ -2914,7 +3075,7 @@ public class StatsPullAtomService extends SystemService { ); } - int pullDangerousPermissionState(int atomTag, List<StatsEvent> pulledData) { + int pullDangerousPermissionStateLocked(int atomTag, List<StatsEvent> pulledData) { final long token = Binder.clearCallingIdentity(); float samplingRate = DeviceConfig.getFloat(DeviceConfig.NAMESPACE_PERMISSIONS, DANGEROUS_PERMISSION_STATE_SAMPLE_RATE, 0.02f); @@ -3007,7 +3168,7 @@ public class StatsPullAtomService extends SystemService { ); } - int pullTimeZoneDataInfo(int atomTag, List<StatsEvent> pulledData) { + int pullTimeZoneDataInfoLocked(int atomTag, List<StatsEvent> pulledData) { String tzDbVersion = "Unknown"; try { tzDbVersion = android.icu.util.TimeZone.getTZDataVersion(); @@ -3034,7 +3195,7 @@ public class StatsPullAtomService extends SystemService { ); } - int pullExternalStorageInfo(int atomTag, List<StatsEvent> pulledData) { + int pullExternalStorageInfoLocked(int atomTag, List<StatsEvent> pulledData) { if (mStorageManager == null) { return StatsManager.PULL_SKIP; } @@ -3084,7 +3245,7 @@ public class StatsPullAtomService extends SystemService { ); } - int pullAppsOnExternalStorageInfo(int atomTag, List<StatsEvent> pulledData) { + int pullAppsOnExternalStorageInfoLocked(int atomTag, List<StatsEvent> pulledData) { if (mStorageManager == null) { return StatsManager.PULL_SKIP; } @@ -3140,7 +3301,7 @@ public class StatsPullAtomService extends SystemService { ); } - int pullFaceSettings(int atomTag, List<StatsEvent> pulledData) { + int pullFaceSettingsLocked(int atomTag, List<StatsEvent> pulledData) { final long callingToken = Binder.clearCallingIdentity(); try { List<UserInfo> users = mContext.getSystemService(UserManager.class).getUsers(); @@ -3222,7 +3383,7 @@ public class StatsPullAtomService extends SystemService { } } - int pullAppOps(int atomTag, List<StatsEvent> pulledData) { + int pullAppOpsLocked(int atomTag, List<StatsEvent> pulledData) { final long token = Binder.clearCallingIdentity(); try { AppOpsManager appOps = mContext.getSystemService(AppOpsManager.class); @@ -3299,7 +3460,7 @@ public class StatsPullAtomService extends SystemService { ); } - int pullAttributedAppOps(int atomTag, List<StatsEvent> pulledData) { + int pullAttributedAppOpsLocked(int atomTag, List<StatsEvent> pulledData) { final long token = Binder.clearCallingIdentity(); try { AppOpsManager appOps = mContext.getSystemService(AppOpsManager.class); @@ -3377,7 +3538,9 @@ public class StatsPullAtomService extends SystemService { } int estimatedSamplingRate = (int) constrain( appOpsTargetCollectionSize * 100 / estimatedSize, 0, 100); - mAppOpsSamplingRate = min(mAppOpsSamplingRate, estimatedSamplingRate); + synchronized (mAppOpsSamplingRateLock) { + mAppOpsSamplingRate = min(mAppOpsSamplingRate, estimatedSamplingRate); + } } private List<AppOpEntry> processHistoricalOps( @@ -3420,7 +3583,7 @@ public class StatsPullAtomService extends SystemService { } } - int pullRuntimeAppOpAccessMessage(int atomTag, List<StatsEvent> pulledData) { + int pullRuntimeAppOpAccessMessageLocked(int atomTag, List<StatsEvent> pulledData) { final long token = Binder.clearCallingIdentity(); try { AppOpsManager appOps = mContext.getSystemService(AppOpsManager.class); @@ -3507,7 +3670,7 @@ public class StatsPullAtomService extends SystemService { ); } - int pullNotificationRemoteViews(int atomTag, List<StatsEvent> pulledData) { + int pullNotificationRemoteViewsLocked(int atomTag, List<StatsEvent> pulledData) { INotificationManager notificationManagerService = getINotificationManagerService(); if (notificationManagerService == null) { return StatsManager.PULL_SKIP; @@ -3601,7 +3764,7 @@ public class StatsPullAtomService extends SystemService { ); } - int pullHealthHal(int atomTag, List<StatsEvent> pulledData) { + int pullHealthHalLocked(int atomTag, List<StatsEvent> pulledData) { IHealth healthService = mHealthService.getLastService(); if (healthService == null) { return StatsManager.PULL_SKIP; @@ -3651,7 +3814,7 @@ public class StatsPullAtomService extends SystemService { ); } - int pullSettingsStats(int atomTag, List<StatsEvent> pulledData) { + int pullSettingsStatsLocked(int atomTag, List<StatsEvent> pulledData) { UserManager userManager = mContext.getSystemService(UserManager.class); if (userManager == null) { return StatsManager.PULL_SKIP; @@ -3678,21 +3841,6 @@ public class StatsPullAtomService extends SystemService { return StatsManager.PULL_SUCCESS; } - private void registerDisplayWakeStats() { - int tagId = FrameworkStatsLog.DISPLAY_WAKE_REASON; - mStatsManager.setPullAtomCallback( - tagId, - null, // use default PullAtomMetadata values - DIRECT_EXECUTOR, - mStatsCallbackImpl - ); - } - - int pullDisplayWakeStats(int atomTag, List<StatsEvent> pulledData) { - //TODO: Denny, implement read/write DisplayWakeStats, b/154172964 - return 0; - } - // Thermal event received from vendor thermal management subsystem private static final class ThermalEventListener extends IThermalEventListener.Stub { @Override @@ -3749,11 +3897,13 @@ public class StatsPullAtomService extends SystemService { final SubInfo subInfo = new SubInfo(subId, sub.getCarrierId(), mcc, mnc, subscriberId, sub.isOpportunistic()); Slog.i(TAG, "subId " + subId + " added into historical sub list"); - mHistoricalSubs.add(subInfo); - // Since getting snapshot when pulling will also include data before boot, - // query stats as baseline to prevent double count is needed. - mNetworkStatsBaselines.addAll(getDataUsageBytesTransferSnapshotForSub(subInfo)); + synchronized (mDataBytesTransferLock) { + mHistoricalSubs.add(subInfo); + // Since getting snapshot when pulling will also include data before boot, + // query stats as baseline to prevent double count is needed. + mNetworkStatsBaselines.addAll(getDataUsageBytesTransferSnapshotForSub(subInfo)); + } } } } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index d1366bd2976e..a8f3ae5f24a3 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -5616,11 +5616,6 @@ public class WindowManagerService extends IWindowManager.Stub mLatencyTracker.onActionStart(ACTION_ROTATE_SCREEN); mExitAnimId = exitAnim; mEnterAnimId = enterAnim; - ScreenRotationAnimation screenRotationAnimation = - displayContent.getRotationAnimation(); - if (screenRotationAnimation != null) { - screenRotationAnimation.kill(); - } displayContent.updateDisplayInfo(); final int originalRotation = overrideOriginalRotation != ROTATION_UNDEFINED |