Merge "Fix name of TemperatureControlTemplate"
diff --git a/api/system-current.txt b/api/system-current.txt
index 6e05db9..8a888db 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -4099,6 +4099,10 @@
method public android.media.AudioRecord.Builder setSessionId(int) throws java.lang.IllegalArgumentException;
}
+ public final class AudioRecordingConfiguration implements android.os.Parcelable {
+ method public int getClientUid();
+ }
+
public class HwAudioSource {
method public boolean isPlaying();
method public void start();
@@ -5693,6 +5697,7 @@
@Deprecated public class WifiConfiguration implements android.os.Parcelable {
method @Deprecated public int getAuthType();
method @Deprecated @NonNull public android.net.IpConfiguration.IpAssignment getIpAssignment();
+ method @Deprecated @NonNull public android.net.IpConfiguration getIpConfiguration();
method @Deprecated @NonNull public android.net.wifi.WifiConfiguration.NetworkSelectionStatus getNetworkSelectionStatus();
method @Deprecated @NonNull public String getPrintableSsid();
method @Deprecated @NonNull public android.net.IpConfiguration.ProxySettings getProxySettings();
diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp
index 887d17c..7b96ce9 100644
--- a/cmds/statsd/Android.bp
+++ b/cmds/statsd/Android.bp
@@ -196,18 +196,6 @@
"libcutils",
"libstatslog",
],
- target: {
- android: {
- shared_libs: [
- "libutils",
- ],
- },
- host: {
- static_libs: [
- "libutils",
- ],
- },
- },
}
diff --git a/cmds/statsd/src/atom_field_options.proto b/cmds/statsd/src/atom_field_options.proto
index 16c936c..6d2bd04 100644
--- a/cmds/statsd/src/atom_field_options.proto
+++ b/cmds/statsd/src/atom_field_options.proto
@@ -85,5 +85,5 @@
optional bool allow_from_any_uid = 50003 [default = false];
- optional string log_from_module = 50004;
-}
\ No newline at end of file
+ optional string module = 50004;
+}
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 2270974..815e3e6 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -112,9 +112,9 @@
TouchEventReported touch_event_reported = 34;
WakeupAlarmOccurred wakeup_alarm_occurred = 35;
KernelWakeupReported kernel_wakeup_reported = 36;
- WifiLockStateChanged wifi_lock_state_changed = 37 [(log_from_module) = "wifi"];
- WifiSignalStrengthChanged wifi_signal_strength_changed = 38 [(log_from_module) = "wifi"];
- WifiScanStateChanged wifi_scan_state_changed = 39 [(log_from_module) = "wifi"];
+ WifiLockStateChanged wifi_lock_state_changed = 37 [(module) = "wifi"];
+ WifiSignalStrengthChanged wifi_signal_strength_changed = 38 [(module) = "wifi"];
+ WifiScanStateChanged wifi_scan_state_changed = 39 [(module) = "wifi"];
PhoneSignalStrengthChanged phone_signal_strength_changed = 40;
SettingChanged setting_changed = 41;
ActivityForegroundStateChanged activity_foreground_state_changed = 42;
@@ -128,7 +128,7 @@
AppStartFullyDrawn app_start_fully_drawn = 50;
LmkKillOccurred lmk_kill_occurred = 51;
PictureInPictureStateChanged picture_in_picture_state_changed = 52;
- WifiMulticastLockStateChanged wifi_multicast_lock_state_changed = 53 [(log_from_module) = "wifi"];
+ WifiMulticastLockStateChanged wifi_multicast_lock_state_changed = 53 [(module) = "wifi"];
LmkStateChanged lmk_state_changed = 54;
AppStartMemoryStateCaptured app_start_memory_state_captured = 55;
ShutdownSequenceReported shutdown_sequence_reported = 56;
@@ -182,39 +182,27 @@
FlagFlipUpdateOccurred flag_flip_update_occurred = 101;
BinaryPushStateChanged binary_push_state_changed = 102;
DevicePolicyEvent device_policy_event = 103;
- DocsUIFileOperationCanceledReported docs_ui_file_op_canceled =
- 104 [(log_from_module) = "docsui"];
- DocsUIFileOperationCopyMoveModeReported
- docs_ui_file_op_copy_move_mode_reported =
- 105 [(log_from_module) = "docsui"];
- DocsUIFileOperationFailureReported docs_ui_file_op_failure =
- 106 [(log_from_module) = "docsui"];
- DocsUIFileOperationReported docs_ui_provider_file_op =
- 107 [(log_from_module) = "docsui"];
- DocsUIInvalidScopedAccessRequestReported
- docs_ui_invalid_scoped_access_request =
- 108 [(log_from_module) = "docsui"];
- DocsUILaunchReported docs_ui_launch_reported =
- 109 [(log_from_module) = "docsui"];
- DocsUIRootVisitedReported docs_ui_root_visited =
- 110 [(log_from_module) = "docsui"];
- DocsUIStartupMsReported docs_ui_startup_ms =
- 111 [(log_from_module) = "docsui"];
- DocsUIUserActionReported docs_ui_user_action_reported =
- 112 [(log_from_module) = "docsui"];
+ DocsUIFileOperationCanceledReported docs_ui_file_op_canceled = 104 [(module) = "docsui"];
+ DocsUIFileOperationCopyMoveModeReported docs_ui_file_op_copy_move_mode_reported =
+ 105 [(module) = "docsui"];
+ DocsUIFileOperationFailureReported docs_ui_file_op_failure = 106 [(module) = "docsui"];
+ DocsUIFileOperationReported docs_ui_provider_file_op = 107 [(module) = "docsui"];
+ DocsUIInvalidScopedAccessRequestReported docs_ui_invalid_scoped_access_request =
+ 108 [(module) = "docsui"];
+ DocsUILaunchReported docs_ui_launch_reported = 109 [(module) = "docsui"];
+ DocsUIRootVisitedReported docs_ui_root_visited = 110 [(module) = "docsui"];
+ DocsUIStartupMsReported docs_ui_startup_ms = 111 [(module) = "docsui"];
+ DocsUIUserActionReported docs_ui_user_action_reported = 112 [(module) = "docsui"];
WifiEnabledStateChanged wifi_enabled_state_changed = 113;
WifiRunningStateChanged wifi_running_state_changed = 114;
AppCompacted app_compacted = 115;
- NetworkDnsEventReported network_dns_event_reported = 116 [(log_from_module) = "resolv"];
+ NetworkDnsEventReported network_dns_event_reported = 116 [(module) = "resolv"];
DocsUIPickerLaunchedFromReported docs_ui_picker_launched_from_reported =
- 117 [(log_from_module) = "docsui"];
- DocsUIPickResultReported docs_ui_pick_result_reported =
- 118 [(log_from_module) = "docsui"];
- DocsUISearchModeReported docs_ui_search_mode_reported =
- 119 [(log_from_module) = "docsui"];
- DocsUISearchTypeReported docs_ui_search_type_reported =
- 120 [(log_from_module) = "docsui"];
- DataStallEvent data_stall_event = 121 [(log_from_module) = "network_stack"];
+ 117 [(module) = "docsui"];
+ DocsUIPickResultReported docs_ui_pick_result_reported = 118 [(module) = "docsui"];
+ DocsUISearchModeReported docs_ui_search_mode_reported = 119 [(module) = "docsui"];
+ DocsUISearchTypeReported docs_ui_search_type_reported = 120 [(module) = "docsui"];
+ DataStallEvent data_stall_event = 121 [(module) = "network_stack"];
RescuePartyResetReported rescue_party_reset_reported = 122;
SignedConfigReported signed_config_reported = 123;
GnssNiEventReported gnss_ni_event_reported = 124;
@@ -264,7 +252,7 @@
ScreenTimeoutExtensionReported screen_timeout_extension_reported = 168;
ProcessStartTime process_start_time = 169;
PermissionGrantRequestResultReported permission_grant_request_result_reported =
- 170 [(log_from_module) = "permissioncontroller"];
+ 170 [(module) = "permissioncontroller"];
BluetoothSocketConnectionStateChanged bluetooth_socket_connection_state_changed = 171;
DeviceIdentifierAccessDenied device_identifier_access_denied = 172;
BubbleDeveloperErrorReported bubble_developer_error_reported = 173;
@@ -273,21 +261,21 @@
AssistGestureProgressReported assist_gesture_progress_reported = 176;
TouchGestureClassified touch_gesture_classified = 177;
HiddenApiUsed hidden_api_used = 178 [(allow_from_any_uid) = true];
- StyleUIChanged style_ui_changed = 179 [(log_from_module) = "style"];
+ StyleUIChanged style_ui_changed = 179 [(module) = "style"];
PrivacyIndicatorsInteracted privacy_indicators_interacted =
- 180 [(log_from_module) = "permissioncontroller"];
+ 180 [(module) = "permissioncontroller"];
AppInstallOnExternalStorageReported app_install_on_external_storage_reported = 181;
- NetworkStackReported network_stack_reported = 182 [(log_from_module) = "network_stack"];
+ NetworkStackReported network_stack_reported = 182 [(module) = "network_stack"];
AppMovedStorageReported app_moved_storage_reported = 183;
BiometricEnrolled biometric_enrolled = 184;
SystemServerWatchdogOccurred system_server_watchdog_occurred = 185;
TombStoneOccurred tomb_stone_occurred = 186;
BluetoothClassOfDeviceReported bluetooth_class_of_device_reported = 187;
IntelligenceEventReported intelligence_event_reported =
- 188 [(log_from_module) = "intelligence"];
+ 188 [(module) = "intelligence"];
ThermalThrottlingSeverityStateChanged thermal_throttling_severity_state_changed = 189;
RoleRequestResultReported role_request_result_reported =
- 190 [(log_from_module) = "permissioncontroller"];
+ 190 [(module) = "permissioncontroller"];
MediametricsAudiopolicyReported mediametrics_audiopolicy_reported = 191;
MediametricsAudiorecordReported mediametrics_audiorecord_reported = 192;
MediametricsAudiothreadReported mediametrics_audiothread_reported = 193;
@@ -301,36 +289,32 @@
MediametricsDrmManagerReported mediametrics_drmmanager_reported = 201;
CarPowerStateChanged car_power_state_changed = 203;
GarageModeInfo garage_mode_info = 204;
- TestAtomReported test_atom_reported = 205 [(log_from_module) = "cts"];
+ TestAtomReported test_atom_reported = 205 [(module) = "cts"];
ContentCaptureCallerMismatchReported content_capture_caller_mismatch_reported = 206;
ContentCaptureServiceEvents content_capture_service_events = 207;
ContentCaptureSessionEvents content_capture_session_events = 208;
ContentCaptureFlushed content_capture_flushed = 209;
LocationManagerApiUsageReported location_manager_api_usage_reported = 210;
ReviewPermissionsFragmentResultReported review_permissions_fragment_result_reported =
- 211 [(log_from_module) = "permissioncontroller"];
+ 211 [(module) = "permissioncontroller"];
RuntimePermissionsUpgradeResult runtime_permissions_upgrade_result =
- 212 [(log_from_module) = "permissioncontroller"];
+ 212 [(module) = "permissioncontroller"];
GrantPermissionsActivityButtonActions grant_permissions_activity_button_actions =
- 213 [(log_from_module) = "permissioncontroller"];
+ 213 [(module) = "permissioncontroller"];
LocationAccessCheckNotificationAction location_access_check_notification_action =
- 214 [(log_from_module) = "permissioncontroller"];
+ 214 [(module) = "permissioncontroller"];
AppPermissionFragmentActionReported app_permission_fragment_action_reported =
- 215 [(log_from_module) = "permissioncontroller"];
+ 215 [(module) = "permissioncontroller"];
AppPermissionFragmentViewed app_permission_fragment_viewed =
- 216 [(log_from_module) = "permissioncontroller"];
+ 216 [(module) = "permissioncontroller"];
AppPermissionsFragmentViewed app_permissions_fragment_viewed =
- 217 [(log_from_module) = "permissioncontroller"];
+ 217 [(module) = "permissioncontroller"];
PermissionAppsFragmentViewed permission_apps_fragment_viewed =
- 218 [(log_from_module) = "permissioncontroller"];
- TextSelectionEvent text_selection_event =
- 219 [(log_from_module) = "textclassifier"];
- TextLinkifyEvent text_linkify_event =
- 220 [(log_from_module) = "textclassifier"];
- ConversationActionsEvent conversation_actions_event =
- 221 [(log_from_module) = "textclassifier"];
- LanguageDetectionEvent language_detection_event =
- 222 [(log_from_module) = "textclassifier"];
+ 218 [(module) = "permissioncontroller"];
+ TextSelectionEvent text_selection_event = 219 [(module) = "textclassifier"];
+ TextLinkifyEvent text_linkify_event = 220 [(module) = "textclassifier"];
+ ConversationActionsEvent conversation_actions_event = 221 [(module) = "textclassifier"];
+ LanguageDetectionEvent language_detection_event = 222 [(module) = "textclassifier"];
ExclusionRectStateChanged exclusion_rect_state_changed = 223;
BackGesture back_gesture_reported_reported = 224;
UpdateEngineUpdateAttemptReported update_engine_update_attempt_reported = 225;
@@ -338,21 +322,17 @@
CameraActionEvent camera_action_event = 227;
AppCompatibilityChangeReported app_compatibility_change_reported =
228 [(allow_from_any_uid) = true];
- PerfettoUploaded perfetto_uploaded =
- 229 [(log_from_module) = "perfetto"];
+ PerfettoUploaded perfetto_uploaded = 229 [(module) = "perfetto"];
VmsClientConnectionStateChanged vms_client_connection_state_changed = 230;
GpsLocationStatusReported gps_location_status_reported = 231;
GpsTimeToFirstFixReported gps_time_to_first_fix_reported = 232;
- MediaProviderScanEvent media_provider_scan_event =
- 233 [(log_from_module) = "mediaprovider"];
- MediaProviderDeletionEvent media_provider_deletion_event =
- 234 [(log_from_module) = "mediaprovider"];
+ MediaProviderScanEvent media_provider_scan_event = 233 [(module) = "mediaprovider"];
+ MediaProviderDeletionEvent media_provider_deletion_event = 234 [(module) = "mediaprovider"];
MediaProviderPermissionEvent media_provider_permission_event =
- 235 [(log_from_module) = "mediaprovider"];
- MediaProviderSchemaChange media_provider_schema_change =
- 236 [(log_from_module) = "mediaprovider"];
+ 235 [(module) = "mediaprovider"];
+ MediaProviderSchemaChange media_provider_schema_change = 236 [(module) = "mediaprovider"];
MediaProviderIdleMaintenance media_provider_idle_maintenance =
- 237 [(log_from_module) = "mediaprovider"];
+ 237 [(module) = "mediaprovider"];
}
// Pulled events will start at field 10000.
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index 453c600..775b1d1 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -46,7 +46,7 @@
import android.os.SystemProperties;
import android.os.Trace;
import android.os.UserHandle;
-import android.sysprop.ProductProperties;
+import android.sysprop.VndkProperties;
import android.text.TextUtils;
import android.util.AndroidRuntimeException;
import android.util.ArrayMap;
@@ -785,13 +785,12 @@
// Similar to vendor apks, we should add /product/lib for apks from product partition
// when product apps are marked as unbundled. We cannot use the same way from vendor
// to check if lib path exists because there is possibility that /product/lib would not
- // exist from legacy device while product apks are bundled. To make this clear, new
- // property ("ro.product.apps.unbundled") is defined which should be true only when
- // product apks are unbundled.
+ // exist from legacy device while product apks are bundled. To make this clear, we use
+ // "ro.product.vndk.version" property. If the property is defined, we regard all product
+ // apks as unbundled.
if (mApplicationInfo.getCodePath() != null
- && mApplicationInfo.isProduct() && ProductProperties.unbundled_apps().orElse(false)
- // TODO(b/128557860): Change target SDK version when version code R is available.
- && getTargetSdkVersion() == Build.VERSION_CODES.CUR_DEVELOPMENT) {
+ && mApplicationInfo.isProduct()
+ && VndkProperties.product_vndk_version().isPresent()) {
isBundledApp = false;
}
diff --git a/core/java/android/bluetooth/BluetoothHearingAid.java b/core/java/android/bluetooth/BluetoothHearingAid.java
index 83eaa72..38498bc 100644
--- a/core/java/android/bluetooth/BluetoothHearingAid.java
+++ b/core/java/android/bluetooth/BluetoothHearingAid.java
@@ -472,63 +472,6 @@
}
/**
- * Get the volume of the device.
- *
- * <p> The volume is between -128 dB (mute) to 0 dB.
- *
- * @return volume of the hearing aid device.
- * @hide
- */
- @RequiresPermission(Manifest.permission.BLUETOOTH)
- public int getVolume() {
- if (VDBG) {
- log("getVolume()");
- }
- final IBluetoothHearingAid service = getService();
- try {
- if (service != null && isEnabled()) {
- return service.getVolume();
- }
- if (service == null) Log.w(TAG, "Proxy not attached to service");
- return 0;
- } catch (RemoteException e) {
- Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
- return 0;
- }
- }
-
- /**
- * Tells remote device to adjust volume. Uses the following values:
- * <ul>
- * <li>{@link AudioManager#ADJUST_LOWER}</li>
- * <li>{@link AudioManager#ADJUST_RAISE}</li>
- * <li>{@link AudioManager#ADJUST_MUTE}</li>
- * <li>{@link AudioManager#ADJUST_UNMUTE}</li>
- * </ul>
- *
- * @param direction One of the supported adjust values.
- * @hide
- */
- @RequiresPermission(Manifest.permission.BLUETOOTH)
- public void adjustVolume(int direction) {
- if (DBG) log("adjustVolume(" + direction + ")");
-
- final IBluetoothHearingAid service = getService();
- try {
- if (service == null) {
- Log.w(TAG, "Proxy not attached to service");
- return;
- }
-
- if (!isEnabled()) return;
-
- service.adjustVolume(direction);
- } catch (RemoteException e) {
- Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
- }
- }
-
- /**
* Tells remote device to set an absolute volume.
*
* @param volume Absolute volume to be set on remote
diff --git a/core/java/android/content/rollback/PackageRollbackInfo.java b/core/java/android/content/rollback/PackageRollbackInfo.java
index c89796d..6378db0 100644
--- a/core/java/android/content/rollback/PackageRollbackInfo.java
+++ b/core/java/android/content/rollback/PackageRollbackInfo.java
@@ -19,6 +19,7 @@
import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.annotation.TestApi;
+import android.content.pm.PackageManager;
import android.content.pm.VersionedPackage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -88,6 +89,11 @@
private final SparseLongArray mCeSnapshotInodes;
/**
+ * The userdata policy to execute when a rollback for this package is committed.
+ */
+ private final int mRollbackDataPolicy;
+
+ /**
* Returns the name of the package to roll back from.
*/
@NonNull
@@ -148,6 +154,11 @@
}
/** @hide */
+ public @PackageManager.RollbackDataPolicy int getRollbackDataPolicy() {
+ return mRollbackDataPolicy;
+ }
+
+ /** @hide */
public IntArray getSnapshottedUsers() {
return mSnapshottedUsers;
}
@@ -181,11 +192,23 @@
@NonNull IntArray pendingBackups, @NonNull ArrayList<RestoreInfo> pendingRestores,
boolean isApex, @NonNull IntArray snapshottedUsers,
@NonNull SparseLongArray ceSnapshotInodes) {
+ this(packageRolledBackFrom, packageRolledBackTo, pendingBackups, pendingRestores, isApex,
+ snapshottedUsers, ceSnapshotInodes, PackageManager.RollbackDataPolicy.RESTORE);
+ }
+
+ /** @hide */
+ public PackageRollbackInfo(VersionedPackage packageRolledBackFrom,
+ VersionedPackage packageRolledBackTo,
+ @NonNull IntArray pendingBackups, @NonNull ArrayList<RestoreInfo> pendingRestores,
+ boolean isApex, @NonNull IntArray snapshottedUsers,
+ @NonNull SparseLongArray ceSnapshotInodes,
+ @PackageManager.RollbackDataPolicy int rollbackDataPolicy) {
this.mVersionRolledBackFrom = packageRolledBackFrom;
this.mVersionRolledBackTo = packageRolledBackTo;
this.mPendingBackups = pendingBackups;
this.mPendingRestores = pendingRestores;
this.mIsApex = isApex;
+ this.mRollbackDataPolicy = rollbackDataPolicy;
this.mSnapshottedUsers = snapshottedUsers;
this.mCeSnapshotInodes = ceSnapshotInodes;
}
@@ -198,6 +221,7 @@
this.mPendingBackups = null;
this.mSnapshottedUsers = null;
this.mCeSnapshotInodes = null;
+ this.mRollbackDataPolicy = PackageManager.RollbackDataPolicy.RESTORE;
}
@Override
diff --git a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
index c3ebe43..6f90db4 100644
--- a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
+++ b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
@@ -240,6 +240,11 @@
*
* <p>This value is looked up the first time, and cached subsequently.</p>
*
+ * <p>This function may be called without cacheTag() if this is not a vendor key.
+ * If this is a vendor key, cacheTag() must be called first before getTag() can
+ * be called. Otherwise, mVendorId could be default (Long.MAX_VALUE) and vendor
+ * tag lookup could fail.</p>
+ *
* @return The tag numeric value corresponding to the string
*/
@UnsupportedAppUsage
@@ -252,6 +257,27 @@
}
/**
+ * Whether this key's tag is cached.
+ *
+ * @hide
+ */
+ @UnsupportedAppUsage
+ public final boolean hasTag() {
+ return mHasTag;
+ }
+
+ /**
+ * Cache this key's tag.
+ *
+ * @hide
+ */
+ @UnsupportedAppUsage
+ public final void cacheTag(int tag) {
+ mHasTag = true;
+ mTag = tag;
+ }
+
+ /**
* Get the raw class backing the type {@code T} for this key.
*
* <p>The distinction is only important if {@code T} is a generic, e.g.
@@ -523,7 +549,13 @@
}
private <T> T getBase(Key<T> key) {
- int tag = nativeGetTagFromKeyLocal(key.getName());
+ int tag;
+ if (key.hasTag()) {
+ tag = key.getTag();
+ } else {
+ tag = nativeGetTagFromKeyLocal(key.getName());
+ key.cacheTag(tag);
+ }
byte[] values = readValues(tag);
if (values == null) {
// If the key returns null, use the fallback key if exists.
@@ -1451,7 +1483,13 @@
}
private <T> void setBase(Key<T> key, T value) {
- int tag = nativeGetTagFromKeyLocal(key.getName());
+ int tag;
+ if (key.hasTag()) {
+ tag = key.getTag();
+ } else {
+ tag = nativeGetTagFromKeyLocal(key.getName());
+ key.cacheTag(tag);
+ }
if (value == null) {
// Erase the entry
writeValues(tag, /*src*/null);
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index 1c4ef382..3d44944 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -2590,4 +2590,12 @@
* @hide
*/
public static native long getIonMappedSizeKb();
+
+ /**
+ * Return whether virtually-mapped kernel stacks are enabled (CONFIG_VMAP_STACK).
+ * Note: caller needs config_gz read sepolicy permission
+ *
+ * @hide
+ */
+ public static native boolean isVmapStack();
}
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index a4cd4f1..8d3c572 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -353,7 +353,11 @@
finish();
}
});
- if (isVoiceInteraction()) {
+
+ boolean hasTouchScreen = getPackageManager()
+ .hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN);
+
+ if (isVoiceInteraction() || !hasTouchScreen) {
rdl.setCollapsed(false);
}
@@ -1301,10 +1305,11 @@
// In case this method is called again (due to activity recreation), avoid adding a new
// header if one is already present.
- if (useHeader && listView != null && listView.getHeaderViewsCount() == 0) {
+ if (useHeader && listView.getHeaderViewsCount() == 0) {
listView.setHeaderDividersEnabled(true);
listView.addHeaderView(LayoutInflater.from(this).inflate(
- R.layout.resolver_different_item_header, listView, false));
+ R.layout.resolver_different_item_header, listView, false),
+ null, false);
}
}
@@ -1367,6 +1372,8 @@
if (useLayoutWithDefault() && filteredPosition != ListView.INVALID_POSITION) {
setAlwaysButtonEnabled(true, filteredPosition, false);
mOnceButton.setEnabled(true);
+ // Focus the button if we already have the default option
+ mOnceButton.requestFocus();
return;
}
@@ -1499,6 +1506,7 @@
mOnceButton.setEnabled(hasValidSelection);
if (hasValidSelection) {
currentAdapterView.smoothScrollToPosition(checkedPos);
+ mOnceButton.requestFocus();
}
mLastSelected = checkedPos;
} else {
diff --git a/core/java/com/android/internal/os/ZygoteServer.java b/core/java/com/android/internal/os/ZygoteServer.java
index 4a21d37..8d281b7 100644
--- a/core/java/com/android/internal/os/ZygoteServer.java
+++ b/core/java/com/android/internal/os/ZygoteServer.java
@@ -184,9 +184,8 @@
Zygote.USAP_POOL_SECONDARY_SOCKET_NAME);
}
- fetchUsapPoolPolicyProps();
-
mUsapPoolSupported = true;
+ fetchUsapPoolPolicyProps();
}
void setForkChild() {
diff --git a/core/java/com/android/internal/util/MemInfoReader.java b/core/java/com/android/internal/util/MemInfoReader.java
index 362bc92..580c2fa 100644
--- a/core/java/com/android/internal/util/MemInfoReader.java
+++ b/core/java/com/android/internal/util/MemInfoReader.java
@@ -107,9 +107,12 @@
* Amount of RAM that is in use by the kernel for actual allocations.
*/
public long getKernelUsedSizeKb() {
- return mInfos[Debug.MEMINFO_SHMEM] + mInfos[Debug.MEMINFO_SLAB_UNRECLAIMABLE]
- + mInfos[Debug.MEMINFO_VM_ALLOC_USED] + mInfos[Debug.MEMINFO_PAGE_TABLES]
- + mInfos[Debug.MEMINFO_KERNEL_STACK];
+ long size = mInfos[Debug.MEMINFO_SHMEM] + mInfos[Debug.MEMINFO_SLAB_UNRECLAIMABLE]
+ + mInfos[Debug.MEMINFO_VM_ALLOC_USED] + mInfos[Debug.MEMINFO_PAGE_TABLES];
+ if (!Debug.isVmapStack()) {
+ size += mInfos[Debug.MEMINFO_KERNEL_STACK];
+ }
+ return size;
}
public long getSwapTotalSizeKb() {
diff --git a/core/java/com/android/internal/widget/ResolverDrawerLayout.java b/core/java/com/android/internal/widget/ResolverDrawerLayout.java
index 1bb2ba2..e0c3823 100644
--- a/core/java/com/android/internal/widget/ResolverDrawerLayout.java
+++ b/core/java/com/android/internal/widget/ResolverDrawerLayout.java
@@ -187,7 +187,7 @@
public void setCollapsed(boolean collapsed) {
if (!isLaidOut()) {
- mOpenOnLayout = collapsed;
+ mOpenOnLayout = !collapsed;
} else {
smoothScrollTo(collapsed ? mCollapsibleHeight : 0, 0);
}
diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp
index 6e0d5d8..4314eb6 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -50,6 +50,7 @@
#include <memunreachable/memunreachable.h>
#include <android-base/strings.h>
#include "android_os_Debug.h"
+#include <vintf/VintfObject.h>
namespace android
{
@@ -835,6 +836,23 @@
return ionPss;
}
+static jboolean android_os_Debug_isVmapStack(JNIEnv *env, jobject clazz)
+{
+ static enum {
+ CONFIG_UNKNOWN,
+ CONFIG_SET,
+ CONFIG_UNSET,
+ } cfg_state = CONFIG_UNKNOWN;
+
+ if (cfg_state == CONFIG_UNKNOWN) {
+ const std::map<std::string, std::string> configs =
+ vintf::VintfObject::GetInstance()->getRuntimeInfo()->kernelConfigs();
+ std::map<std::string, std::string>::const_iterator it = configs.find("CONFIG_VMAP_STACK");
+ cfg_state = (it != configs.end() && it->second == "y") ? CONFIG_SET : CONFIG_UNSET;
+ }
+ return cfg_state == CONFIG_SET;
+}
+
/*
* JNI registration.
*/
@@ -884,6 +902,8 @@
(void*)android_os_Debug_getIonPoolsSizeKb },
{ "getIonMappedSizeKb", "()J",
(void*)android_os_Debug_getIonMappedSizeKb },
+ { "isVmapStack", "()Z",
+ (void*)android_os_Debug_isVmapStack },
};
int register_android_os_Debug(JNIEnv *env)
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index e874ac7..a00296c 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3209,11 +3209,6 @@
<java-symbol type="id" name="accessibility_button_target_label" />
<java-symbol type="string" name="accessibility_magnification_chooser_text" />
- <java-symbol type="string" name="accessibility_gesture_prompt_text" />
- <java-symbol type="string" name="accessibility_gesture_3finger_prompt_text" />
- <java-symbol type="string" name="accessibility_gesture_instructional_text" />
- <java-symbol type="string" name="accessibility_gesture_3finger_instructional_text" />
-
<java-symbol type="drawable" name="ic_accessibility_magnification" />
<!-- com.android.internal.widget.RecyclerView -->
diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
index 8622b7e..c086421 100644
--- a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
@@ -54,6 +54,7 @@
import android.content.pm.ResolveInfo;
import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutManager.ShareShortcutInfo;
+import android.content.res.Configuration;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.Canvas;
@@ -977,6 +978,7 @@
serviceTargets,
TARGET_TYPE_CHOOSER_TARGET)
);
+
// Thread.sleep shouldn't be a thing in an integration test but it's
// necessary here because of the way the code is structured
// TODO: restructure the tests b/129870719
@@ -1075,7 +1077,29 @@
// This test is too long and too slow and should not be taken as an example for future tests.
@Test
- public void testDirectTargetLoggingWithAppTargetNotRanked() throws InterruptedException {
+ public void testDirectTargetLoggingWithAppTargetNotRankedPortrait()
+ throws InterruptedException {
+ testDirectTargetLoggingWithAppTargetNotRanked(Configuration.ORIENTATION_PORTRAIT, 4);
+ }
+
+ @Test
+ public void testDirectTargetLoggingWithAppTargetNotRankedLandscape()
+ throws InterruptedException {
+ testDirectTargetLoggingWithAppTargetNotRanked(Configuration.ORIENTATION_LANDSCAPE, 8);
+ }
+
+ private void testDirectTargetLoggingWithAppTargetNotRanked(
+ int orientation, int appTargetsExpected
+ ) throws InterruptedException {
+ Configuration configuration =
+ new Configuration(InstrumentationRegistry.getInstrumentation().getContext()
+ .getResources().getConfiguration());
+ configuration.orientation = orientation;
+
+ sOverrides.resources = Mockito.spy(
+ InstrumentationRegistry.getInstrumentation().getContext().getResources());
+ when(sOverrides.resources.getConfiguration()).thenReturn(configuration);
+
Intent sendIntent = createSendTextIntent();
// We need app targets for direct targets to get displayed
List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(15);
@@ -1111,8 +1135,10 @@
// TODO: restructure the tests b/129870719
Thread.sleep(ChooserActivity.LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS);
- assertThat("Chooser should have 20 targets (4 apps, 1 direct, 15 A-Z)",
- activity.getAdapter().getCount(), is(20));
+ assertThat(
+ String.format("Chooser should have %d targets (%d apps, 1 direct, 15 A-Z)",
+ appTargetsExpected + 16, appTargetsExpected),
+ activity.getAdapter().getCount(), is(appTargetsExpected + 16));
assertThat("Chooser should have exactly one selectable direct target",
activity.getAdapter().getSelectableServiceTargetCount(), is(1));
assertThat("The resolver info must match the resolver info used to create the target",
diff --git a/media/java/android/media/AudioRecordingConfiguration.java b/media/java/android/media/AudioRecordingConfiguration.java
index 5f32c0f..f3613d3 100644
--- a/media/java/android/media/AudioRecordingConfiguration.java
+++ b/media/java/android/media/AudioRecordingConfiguration.java
@@ -18,6 +18,7 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.media.audiofx.AudioEffect;
@@ -224,15 +225,16 @@
public String getClientPackageName() { return mClientPackageName; }
/**
- * @pending for SystemApi
* Returns the user id of the application performing the recording.
* <p>This information is only available if the caller has the
* {@link android.Manifest.permission.MODIFY_AUDIO_ROUTING}
* permission.
* <br>The result is -1 without the permission.
* @return the user id
+ *
+ * @hide
*/
- @UnsupportedAppUsage
+ @SystemApi
public int getClientUid() { return mClientUid; }
/**
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index 176bb37..f780d40 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -362,7 +362,8 @@
</tr>
<tr>
<td>FLAC</td>
- <td>mandatory metadata block (called the STREAMINFO block),<br>
+ <td>"fLaC", the FLAC stream marker in ASCII,<br>
+ followed by the STREAMINFO block (the mandatory metadata block),<br>
optionally followed by any number of other metadata blocks</td>
<td class=NA>Not Used</td>
<td class=NA>Not Used</td>
diff --git a/media/java/android/media/MediaRouter2.java b/media/java/android/media/MediaRouter2.java
index 0be49d8..9100032 100644
--- a/media/java/android/media/MediaRouter2.java
+++ b/media/java/android/media/MediaRouter2.java
@@ -547,8 +547,6 @@
* {@link SessionCallback#onSessionCreationFailed}.
* <p>
* Pass {@code null} to sessionInfo for the failure case.
- *
- * TODO: What should router do when the session is created by manager?
*/
void createControllerOnHandler(@Nullable RouteSessionInfo sessionInfo, int requestId) {
SessionCreationRequest matchingRequest = null;
@@ -559,40 +557,44 @@
}
}
- if (matchingRequest == null) {
- Log.w(TAG, "Ignoring session creation result for unknown request."
- + " requestId=" + requestId + ", sessionInfo=" + sessionInfo);
- return;
+ if (matchingRequest != null) {
+ mSessionCreationRequests.remove(matchingRequest);
+
+ MediaRoute2Info requestedRoute = matchingRequest.mRoute;
+ String requestedControlCategory = matchingRequest.mControlCategory;
+
+ if (sessionInfo == null) {
+ // TODO: We may need to distinguish between failure and rejection.
+ // One way can be introducing 'reason'.
+ notifySessionCreationFailed(requestedRoute, requestedControlCategory);
+ return;
+ } else if (!TextUtils.equals(requestedControlCategory,
+ sessionInfo.getControlCategory())) {
+ Log.w(TAG, "The session has different control category from what we requested. "
+ + "(requested=" + requestedControlCategory
+ + ", actual=" + sessionInfo.getControlCategory()
+ + ")");
+ notifySessionCreationFailed(requestedRoute, requestedControlCategory);
+ return;
+ } else if (!sessionInfo.getSelectedRoutes().contains(requestedRoute.getId())) {
+ Log.w(TAG, "The session does not contain the requested route. "
+ + "(requestedRouteId=" + requestedRoute.getId()
+ + ", actualRoutes=" + sessionInfo.getSelectedRoutes()
+ + ")");
+ notifySessionCreationFailed(requestedRoute, requestedControlCategory);
+ return;
+ } else if (!TextUtils.equals(requestedRoute.getProviderId(),
+ sessionInfo.getProviderId())) {
+ Log.w(TAG, "The session's provider ID does not match the requested route's. "
+ + "(requested route's providerId=" + requestedRoute.getProviderId()
+ + ", actual providerId=" + sessionInfo.getProviderId()
+ + ")");
+ notifySessionCreationFailed(requestedRoute, requestedControlCategory);
+ return;
+ }
}
- mSessionCreationRequests.remove(matchingRequest);
-
- MediaRoute2Info requestedRoute = matchingRequest.mRoute;
- String requestedControlCategory = matchingRequest.mControlCategory;
-
- if (sessionInfo == null) {
- // TODO: We may need to distinguish between failure and rejection.
- // One way can be introducing 'reason'.
- notifySessionCreationFailed(requestedRoute, requestedControlCategory);
- } else if (!TextUtils.equals(requestedControlCategory, sessionInfo.getControlCategory())) {
- Log.w(TAG, "The session has different control category from what we requested. "
- + "(requested=" + requestedControlCategory
- + ", actual=" + sessionInfo.getControlCategory()
- + ")");
- notifySessionCreationFailed(requestedRoute, requestedControlCategory);
- } else if (!sessionInfo.getSelectedRoutes().contains(requestedRoute.getId())) {
- Log.w(TAG, "The session does not contain the requested route. "
- + "(requestedRouteId=" + requestedRoute.getId()
- + ", actualRoutes=" + sessionInfo.getSelectedRoutes()
- + ")");
- notifySessionCreationFailed(requestedRoute, requestedControlCategory);
- } else if (!TextUtils.equals(requestedRoute.getProviderId(), sessionInfo.getProviderId())) {
- Log.w(TAG, "The session's provider ID does not match the requested route's. "
- + "(requested route's providerId=" + requestedRoute.getProviderId()
- + ", actual providerId=" + sessionInfo.getProviderId()
- + ")");
- notifySessionCreationFailed(requestedRoute, requestedControlCategory);
- } else {
+ if (sessionInfo != null) {
RouteSessionController controller = new RouteSessionController(sessionInfo);
mSessionControllers.put(controller.getUniqueSessionId(), controller);
notifySessionCreated(controller);
diff --git a/media/jni/android_media_tv_Tuner.cpp b/media/jni/android_media_tv_Tuner.cpp
index ef806e4..da52696 100644
--- a/media/jni/android_media_tv_Tuner.cpp
+++ b/media/jni/android_media_tv_Tuner.cpp
@@ -966,7 +966,7 @@
{ "nativeStopFilter", "()I", (void *)android_media_tv_Tuner_stop_filter },
{ "nativeFlushFilter", "()I", (void *)android_media_tv_Tuner_flush_filter },
{ "nativeRead", "([BII)I", (void *)android_media_tv_Tuner_read_filter_fmq },
- { "nativeCloseFilter", "()I", (void *)android_media_tv_Tuner_close_filter },
+ { "nativeClose", "()I", (void *)android_media_tv_Tuner_close_filter },
};
static const JNINativeMethod gDescramblerMethods[] = {
@@ -975,7 +975,7 @@
{ "nativeRemovePid", "(IILandroid/media/tv/tuner/Tuner$Filter;)I",
(void *)android_media_tv_Tuner_remove_pid },
{ "nativeSetKeyToken", "([B)I", (void *)android_media_tv_Tuner_set_key_token },
- { "nativeClose", "()V", (void *)android_media_tv_Tuner_close_descrambler },
+ { "nativeClose", "()I", (void *)android_media_tv_Tuner_close_descrambler },
};
static const JNINativeMethod gDvrMethods[] = {
diff --git a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java
index 1d51c96..83c7c17 100644
--- a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java
+++ b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java
@@ -29,6 +29,7 @@
import android.media.MediaRoute2Info;
import android.media.MediaRouter2;
import android.media.MediaRouter2.RouteCallback;
+import android.media.MediaRouter2.SessionCallback;
import android.media.MediaRouter2Manager;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.SmallTest;
@@ -101,8 +102,8 @@
private String mPackageName;
private final List<MediaRouter2Manager.Callback> mManagerCallbacks = new ArrayList<>();
- private final List<RouteCallback> mRouteCallbacks =
- new ArrayList<>();
+ private final List<RouteCallback> mRouteCallbacks = new ArrayList<>();
+ private final List<SessionCallback> mSessionCallbacks = new ArrayList<>();
public static final List<String> CATEGORIES_ALL = new ArrayList();
public static final List<String> CATEGORIES_SPECIAL = new ArrayList();
@@ -205,27 +206,26 @@
}
/**
- * Tests if MR2.Callback.onRouteSelected is called when a route is selected from MR2Manager.
- *
- * TODO: Change this test so that this test check whether the route is added in a session.
- * Until then, temporailiy marking @Ignore
+ * Tests if MR2.SessionCallback.onSessionCreated is called
+ * when a route is selected from MR2Manager.
*/
@Test
- @Ignore
- public void testRouterOnRouteSelected() throws Exception {
+ public void testRouterOnSessionCreated() throws Exception {
Map<String, MediaRoute2Info> routes = waitAndGetRoutesWithManager(CATEGORIES_ALL);
CountDownLatch latch = new CountDownLatch(1);
addManagerCallback(new MediaRouter2Manager.Callback());
-// addRouterCallback(new RouteDiscoveryCallback() {
-// @Override
-// public void onRouteSelected(MediaRoute2Info route, int reason, Bundle controlHints) {
-// if (route != null && TextUtils.equals(route.getId(), ROUTE_ID1)) {
-// latch.countDown();
-// }
-// }
-// });
+ //TODO: remove this when it's not necessary.
+ addRouterCallback(new MediaRouter2.RouteCallback());
+ addSessionCallback(new SessionCallback() {
+ @Override
+ public void onSessionCreated(MediaRouter2.RouteSessionController controller) {
+ if (createRouteMap(controller.getSelectedRoutes()).containsKey(ROUTE_ID1)) {
+ latch.countDown();
+ }
+ }
+ });
MediaRoute2Info routeToSelect = routes.get(ROUTE_ID1);
assertNotNull(routeToSelect);
@@ -446,6 +446,11 @@
mRouter2.registerRouteCallback(mExecutor, routeCallback);
}
+ private void addSessionCallback(SessionCallback sessionCallback) {
+ mSessionCallbacks.add(sessionCallback);
+ mRouter2.registerSessionCallback(mExecutor, sessionCallback);
+ }
+
private void clearCallbacks() {
for (MediaRouter2Manager.Callback callback : mManagerCallbacks) {
mManager.unregisterCallback(callback);
@@ -456,5 +461,10 @@
mRouter2.unregisterRouteCallback(routeCallback);
}
mRouteCallbacks.clear();
+
+ for (SessionCallback sessionCallback : mSessionCallbacks) {
+ mRouter2.unregisterSessionCallback(sessionCallback);
+ }
+ mSessionCallbacks.clear();
}
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java
index 58655a2..b4b55f3 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java
@@ -203,13 +203,6 @@
}
}
- public int getVolume() {
- if (mService == null) {
- return 0;
- }
- return mService.getVolume();
- }
-
public void setVolume(int volume) {
if (mService == null) {
return;
@@ -224,20 +217,6 @@
return mService.getHiSyncId(device);
}
- public int getDeviceSide(BluetoothDevice device) {
- if (mService == null) {
- return BluetoothHearingAid.SIDE_LEFT;
- }
- return mService.getDeviceSide(device);
- }
-
- public int getDeviceMode(BluetoothDevice device) {
- if (mService == null) {
- return BluetoothHearingAid.MODE_MONAURAL;
- }
- return mService.getDeviceMode(device);
- }
-
public String toString() {
return NAME;
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
index d3ccbeb..77c3ad9 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
@@ -27,7 +27,6 @@
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
-import android.graphics.Point;
import android.graphics.drawable.Icon;
import android.hardware.display.DisplayManager;
import android.hardware.display.VirtualDisplay;
@@ -42,6 +41,7 @@
import android.util.Log;
import android.util.Size;
import android.view.Surface;
+import android.view.WindowManager;
import android.widget.Toast;
import com.android.systemui.R;
@@ -76,7 +76,7 @@
private static final String ACTION_DELETE = "com.android.systemui.screenrecord.DELETE";
private static final int TOTAL_NUM_TRACKS = 1;
- private static final int VIDEO_BIT_RATE = 6000000;
+ private static final int VIDEO_BIT_RATE = 10000000;
private static final int VIDEO_FRAME_RATE = 30;
private static final int AUDIO_BIT_RATE = 16;
private static final int AUDIO_SAMPLE_RATE = 44100;
@@ -238,7 +238,9 @@
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
// Set up video
- DisplayMetrics metrics = getResources().getDisplayMetrics();
+ DisplayMetrics metrics = new DisplayMetrics();
+ WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
+ wm.getDefaultDisplay().getRealMetrics(metrics);
int screenWidth = metrics.widthPixels;
int screenHeight = metrics.heightPixels;
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index c689ed1..03d9626 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -288,7 +288,14 @@
boolean isTemporary) {
mAugmentedAutofillState.setServiceInfo(userId, serviceName, isTemporary);
synchronized (mLock) {
- getServiceForUserLocked(userId).updateRemoteAugmentedAutofillService();
+ final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId);
+ if (service == null) {
+ // If we cannot get the service from the services cache, it will call
+ // updateRemoteAugmentedAutofillService() finally. Skip call this update again.
+ getServiceForUserLocked(userId);
+ } else {
+ service.updateRemoteAugmentedAutofillService();
+ }
}
}
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 9f23cdaf..8c9bff9 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -477,9 +477,12 @@
/** A in progress startOp->finishOp event */
private static final class InProgressStartOpEvent implements IBinder.DeathRecipient {
- /** Time of startOp event */
+ /** Wall clock time of startOp event (not monotonic) */
final long startTime;
+ /** Elapsed time since boot of startOp event */
+ final long startElapsedTime;
+
/** Id of the client that started the event */
final @NonNull IBinder clientId;
@@ -492,9 +495,11 @@
/** How many times the op was started but not finished yet */
int numUnfinishedStarts;
- private InProgressStartOpEvent(long startTime, @NonNull IBinder clientId,
- @NonNull Runnable onDeath, int uidState) throws RemoteException {
+ private InProgressStartOpEvent(long startTime, long startElapsedTime,
+ @NonNull IBinder clientId, @NonNull Runnable onDeath, int uidState)
+ throws RemoteException {
this.startTime = startTime;
+ this.startElapsedTime = startElapsedTime;
this.clientId = clientId;
this.onDeath = onDeath;
this.uidState = uidState;
@@ -636,7 +641,8 @@
InProgressStartOpEvent event = mInProgressEvents.get(clientId);
if (event == null) {
- event = new InProgressStartOpEvent(System.currentTimeMillis(), clientId, () -> {
+ event = new InProgressStartOpEvent(System.currentTimeMillis(),
+ SystemClock.elapsedRealtime(), clientId, () -> {
// In the case the client dies without calling finish first
synchronized (AppOpsService.this) {
if (mInProgressEvents == null) {
@@ -698,7 +704,7 @@
// startOp events don't support proxy, hence use flags==SELF
NoteOpEvent finishedEvent = new NoteOpEvent(event.startTime,
- System.currentTimeMillis() - event.startTime, null);
+ SystemClock.elapsedRealtime() - event.startElapsedTime, null);
mAccessEvents.put(makeKey(event.uidState, OP_FLAG_SELF), finishedEvent);
mHistoricalRegistry.increaseOpAccessDuration(parent.op, parent.uid,
@@ -759,7 +765,7 @@
// Add in progress events as access events
if (mInProgressEvents != null) {
- long now = System.currentTimeMillis();
+ long now = SystemClock.elapsedRealtime();
int numInProgressEvents = mInProgressEvents.size();
if (accessEvents == null) {
@@ -771,7 +777,7 @@
// startOp events don't support proxy
accessEvents.append(makeKey(event.uidState, OP_FLAG_SELF),
- new NoteOpEvent(event.startTime, now - event.startTime, null));
+ new NoteOpEvent(event.startTime, now - event.startElapsedTime, null));
}
}
@@ -4188,18 +4194,18 @@
final FeatureOp featureOp = op.mFeatures.get(featureId);
if (featureOp.isRunning()) {
- long earliestStartTime = Long.MAX_VALUE;
+ long earliestElapsedTime = Long.MAX_VALUE;
long maxNumStarts = 0;
int numInProgressEvents = featureOp.mInProgressEvents.size();
for (int i = 0; i < numInProgressEvents; i++) {
InProgressStartOpEvent event = featureOp.mInProgressEvents.valueAt(i);
- earliestStartTime = Math.min(earliestStartTime, event.startTime);
+ earliestElapsedTime = Math.min(earliestElapsedTime, event.startElapsedTime);
maxNumStarts = Math.max(maxNumStarts, event.numUnfinishedStarts);
}
pw.print(prefix + "Running start at: ");
- TimeUtils.formatDuration(nowElapsed - earliestStartTime, pw);
+ TimeUtils.formatDuration(nowElapsed - earliestElapsedTime, pw);
pw.println();
if (maxNumStarts > 1) {
@@ -4471,7 +4477,7 @@
if (dumpOp >= 0 || dumpPackage != null || dumpMode >= 0) {
boolean hasOp = dumpOp < 0 || (uidState.opModes != null
&& uidState.opModes.indexOfKey(dumpOp) >= 0);
- boolean hasPackage = dumpPackage == null;
+ boolean hasPackage = dumpPackage == null || dumpUid == mUidStates.keyAt(i);
boolean hasMode = dumpMode < 0;
if (!hasMode && opModes != null) {
for (int opi = 0; !hasMode && opi < opModes.size(); opi++) {
diff --git a/services/core/java/com/android/server/media/MediaRoute2ProviderProxy.java b/services/core/java/com/android/server/media/MediaRoute2ProviderProxy.java
index 423001f..f8d8f9f 100644
--- a/services/core/java/com/android/server/media/MediaRoute2ProviderProxy.java
+++ b/services/core/java/com/android/server/media/MediaRoute2ProviderProxy.java
@@ -286,6 +286,11 @@
if (mActiveConnection != connection) {
return;
}
+ if (sessionInfo != null) {
+ sessionInfo = new RouteSessionInfo.Builder(sessionInfo)
+ .setProviderId(getUniqueId())
+ .build();
+ }
mCallback.onSessionCreated(this, sessionInfo, requestId);
}
diff --git a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
index 0bdcc97..82d2250 100644
--- a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
+++ b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
@@ -1071,12 +1071,6 @@
return;
}
- //TODO: remove this when we are sure that request id is properly implemented.
- if (matchingRequest.mClientRecord.mClientId != toClientId(requestId)) {
- Slog.w(TAG, "Client id is changed. This shouldn't happen.");
- return;
- }
-
mSessionCreationRequests.remove(matchingRequest);
if (sessionInfo == null) {
@@ -1086,21 +1080,17 @@
return;
}
- RouteSessionInfo sessionInfoWithProviderId = new RouteSessionInfo.Builder(sessionInfo)
- .setProviderId(provider.getUniqueId())
- .build();
-
String originalRouteId = matchingRequest.mRoute.getId();
String originalCategory = matchingRequest.mControlCategory;
Client2Record client2Record = matchingRequest.mClientRecord;
- if (!sessionInfoWithProviderId.getSelectedRoutes().contains(originalRouteId)
+ if (!sessionInfo.getSelectedRoutes().contains(originalRouteId)
|| !TextUtils.equals(originalCategory,
- sessionInfoWithProviderId.getControlCategory())) {
+ sessionInfo.getControlCategory())) {
Slog.w(TAG, "Created session doesn't match the original request."
+ " originalRouteId=" + originalRouteId
+ ", originalCategory=" + originalCategory + ", requestId=" + requestId
- + ", sessionInfo=" + sessionInfoWithProviderId);
+ + ", sessionInfo=" + sessionInfo);
notifySessionCreationFailed(matchingRequest.mClientRecord,
toClientRequestId(requestId));
return;
@@ -1108,8 +1098,8 @@
// Succeeded
notifySessionCreated(matchingRequest.mClientRecord,
- sessionInfoWithProviderId, toClientRequestId(requestId));
- mSessionToClientMap.put(sessionInfoWithProviderId.getUniqueSessionId(), client2Record);
+ sessionInfo, toClientRequestId(requestId));
+ mSessionToClientMap.put(sessionInfo.getUniqueSessionId(), client2Record);
// TODO: Tell managers for the session creation
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 785ca7d..b793d6d 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -12872,7 +12872,7 @@
@Override
public String[] getUnsuspendablePackagesForUser(String[] packageNames, int userId) {
- Preconditions.checkNotNull("packageNames cannot be null", packageNames);
+ Preconditions.checkNotNull(packageNames, "packageNames cannot be null");
mContext.enforceCallingOrSelfPermission(Manifest.permission.SUSPEND_APPS,
"getUnsuspendablePackagesForUser");
final int callingUid = Binder.getCallingUid();
diff --git a/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java b/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java
index b0f22e4..f3a6018 100644
--- a/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java
+++ b/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java
@@ -145,7 +145,8 @@
}
@Override
public boolean mayAllowExtraAppOp() {
- return !shouldApplyRestriction && hasRequestedLegacyExternalStorage;
+ return !shouldApplyRestriction && hasRequestedLegacyExternalStorage
+ && targetSDK <= Build.VERSION_CODES.Q;
}
@Override
public boolean mayDenyExtraAppOpIfGranted() {
diff --git a/services/core/java/com/android/server/rollback/AppDataRollbackHelper.java b/services/core/java/com/android/server/rollback/AppDataRollbackHelper.java
index 1123f70..e6e6e23 100644
--- a/services/core/java/com/android/server/rollback/AppDataRollbackHelper.java
+++ b/services/core/java/com/android/server/rollback/AppDataRollbackHelper.java
@@ -16,6 +16,7 @@
package com.android.server.rollback;
+import android.content.pm.PackageManager;
import android.content.rollback.PackageRollbackInfo;
import android.content.rollback.PackageRollbackInfo.RestoreInfo;
import android.os.storage.StorageManager;
@@ -119,11 +120,22 @@
}
try {
- mInstaller.restoreAppDataSnapshot(packageRollbackInfo.getPackageName(), appId, seInfo,
- userId, rollbackId, storageFlags);
+ switch (packageRollbackInfo.getRollbackDataPolicy()) {
+ case PackageManager.RollbackDataPolicy.WIPE:
+ mInstaller.clearAppData(null, packageRollbackInfo.getPackageName(),
+ userId, storageFlags, 0);
+ break;
+ case PackageManager.RollbackDataPolicy.RESTORE:
+ mInstaller.restoreAppDataSnapshot(packageRollbackInfo.getPackageName(), appId,
+ seInfo, userId, rollbackId, storageFlags);
+ break;
+ default:
+ break;
+ }
} catch (InstallerException ie) {
- Slog.e(TAG, "Unable to restore app data snapshot: "
- + packageRollbackInfo.getPackageName(), ie);
+ Slog.e(TAG, "Unable to restore/wipe app data: "
+ + packageRollbackInfo.getPackageName() + " policy="
+ + packageRollbackInfo.getRollbackDataPolicy(), ie);
}
return changedRollback;
@@ -207,13 +219,24 @@
if (hasPendingRestore) {
try {
- mInstaller.restoreAppDataSnapshot(info.getPackageName(), ri.appId,
- ri.seInfo, userId, rollback.info.getRollbackId(),
- Installer.FLAG_STORAGE_CE);
+ switch (info.getRollbackDataPolicy()) {
+ case PackageManager.RollbackDataPolicy.WIPE:
+ mInstaller.clearAppData(null, info.getPackageName(), userId,
+ Installer.FLAG_STORAGE_CE, 0);
+ break;
+ case PackageManager.RollbackDataPolicy.RESTORE:
+ mInstaller.restoreAppDataSnapshot(info.getPackageName(), ri.appId,
+ ri.seInfo, userId, rollback.info.getRollbackId(),
+ Installer.FLAG_STORAGE_CE);
+ break;
+ default:
+ break;
+ }
info.removeRestoreInfo(ri);
} catch (InstallerException ie) {
- Slog.e(TAG, "Unable to restore app data snapshot for: "
- + info.getPackageName(), ie);
+ Slog.e(TAG, "Unable to restore/wipe app data for: "
+ + info.getPackageName() + " policy="
+ + info.getRollbackDataPolicy(), ie);
}
}
}
diff --git a/services/core/java/com/android/server/rollback/Rollback.java b/services/core/java/com/android/server/rollback/Rollback.java
index 6898e1c..88c1564 100644
--- a/services/core/java/com/android/server/rollback/Rollback.java
+++ b/services/core/java/com/android/server/rollback/Rollback.java
@@ -306,7 +306,7 @@
* @return boolean True if the rollback was enabled successfully for the specified package.
*/
boolean enableForPackage(String packageName, long newVersion, long installedVersion,
- boolean isApex, String sourceDir, String[] splitSourceDirs) {
+ boolean isApex, String sourceDir, String[] splitSourceDirs, int rollbackDataPolicy) {
try {
RollbackStore.backupPackageCodePath(this, packageName, sourceDir);
if (!ArrayUtils.isEmpty(splitSourceDirs)) {
@@ -323,7 +323,8 @@
new VersionedPackage(packageName, newVersion),
new VersionedPackage(packageName, installedVersion),
new IntArray() /* pendingBackups */, new ArrayList<>() /* pendingRestores */,
- isApex, new IntArray(), new SparseLongArray() /* ceSnapshotInodes */);
+ isApex, new IntArray(), new SparseLongArray() /* ceSnapshotInodes */,
+ rollbackDataPolicy);
synchronized (mLock) {
info.getPackages().add(packageRollbackInfo);
@@ -344,10 +345,12 @@
for (PackageRollbackInfo pkgRollbackInfo : info.getPackages()) {
if (pkgRollbackInfo.getPackageName().equals(packageName)) {
- dataHelper.snapshotAppData(info.getRollbackId(), pkgRollbackInfo, userIds);
-
- RollbackStore.saveRollback(this);
- pkgRollbackInfo.getSnapshottedUsers().addAll(IntArray.wrap(userIds));
+ if (pkgRollbackInfo.getRollbackDataPolicy()
+ == PackageManager.RollbackDataPolicy.RESTORE) {
+ dataHelper.snapshotAppData(info.getRollbackId(), pkgRollbackInfo, userIds);
+ pkgRollbackInfo.getSnapshottedUsers().addAll(IntArray.wrap(userIds));
+ RollbackStore.saveRollback(this);
+ }
break;
}
}
diff --git a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
index 6cdfcff..9a65ae6 100644
--- a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
+++ b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
@@ -841,7 +841,7 @@
ApplicationInfo appInfo = pkgInfo.applicationInfo;
return rollback.enableForPackage(packageName, newPackage.versionCode,
pkgInfo.getLongVersionCode(), isApex, appInfo.sourceDir,
- appInfo.splitSourceDirs);
+ appInfo.splitSourceDirs, session.rollbackDataPolicy);
}
@Override
diff --git a/services/core/java/com/android/server/rollback/RollbackStore.java b/services/core/java/com/android/server/rollback/RollbackStore.java
index 550c754..df75a29 100644
--- a/services/core/java/com/android/server/rollback/RollbackStore.java
+++ b/services/core/java/com/android/server/rollback/RollbackStore.java
@@ -21,6 +21,7 @@
import static com.android.server.rollback.Rollback.rollbackStateFromString;
import android.annotation.NonNull;
+import android.content.pm.PackageManager;
import android.content.pm.VersionedPackage;
import android.content.rollback.PackageRollbackInfo;
import android.content.rollback.PackageRollbackInfo.RestoreInfo;
@@ -345,6 +346,8 @@
json.put("installedUsers", convertToJsonArray(snapshottedUsers));
json.put("ceSnapshotInodes", ceSnapshotInodesToJson(info.getCeSnapshotInodes()));
+ json.put("rollbackDataPolicy", info.getRollbackDataPolicy());
+
return json;
}
@@ -367,8 +370,13 @@
final SparseLongArray ceSnapshotInodes = ceSnapshotInodesFromJson(
json.getJSONArray("ceSnapshotInodes"));
+ // Backward compatibility: no such field for old versions.
+ final int rollbackDataPolicy = json.optInt("rollbackDataPolicy",
+ PackageManager.RollbackDataPolicy.RESTORE);
+
return new PackageRollbackInfo(versionRolledBackFrom, versionRolledBackTo,
- pendingBackups, pendingRestores, isApex, snapshottedUsers, ceSnapshotInodes);
+ pendingBackups, pendingRestores, isApex, snapshottedUsers, ceSnapshotInodes,
+ rollbackDataPolicy);
}
private static JSONArray versionedPackagesToJson(List<VersionedPackage> packages)
diff --git a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareService.java b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareService.java
index a7cfe10..987c05f 100644
--- a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareService.java
+++ b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareService.java
@@ -42,6 +42,7 @@
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
+import java.util.Objects;
import java.util.Set;
/**
@@ -179,8 +180,8 @@
// Permission check.
checkPermissions();
// Input validation.
- Preconditions.checkNotNull(callback);
- Preconditions.checkNotNull(callback.asBinder());
+ Objects.requireNonNull(callback);
+ Objects.requireNonNull(callback.asBinder());
synchronized (this) {
// State validation.
diff --git a/services/core/java/com/android/server/soundtrigger_middleware/ValidationUtil.java b/services/core/java/com/android/server/soundtrigger_middleware/ValidationUtil.java
index 4898e6b..43047d1 100644
--- a/services/core/java/com/android/server/soundtrigger_middleware/ValidationUtil.java
+++ b/services/core/java/com/android/server/soundtrigger_middleware/ValidationUtil.java
@@ -29,6 +29,7 @@
import com.android.internal.util.Preconditions;
+import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -42,7 +43,7 @@
*/
public class ValidationUtil {
static void validateUuid(@Nullable String uuid) {
- Preconditions.checkNotNull(uuid);
+ Objects.requireNonNull(uuid);
Matcher matcher = UuidUtil.PATTERN.matcher(uuid);
if (!matcher.matches()) {
throw new IllegalArgumentException(
@@ -55,37 +56,37 @@
}
static void validateModel(@Nullable SoundModel model, int expectedType) {
- Preconditions.checkNotNull(model);
+ Objects.requireNonNull(model);
if (model.type != expectedType) {
throw new IllegalArgumentException("Invalid type");
}
validateUuid(model.uuid);
validateUuid(model.vendorUuid);
- Preconditions.checkNotNull(model.data);
+ Objects.requireNonNull(model.data);
}
static void validatePhraseModel(@Nullable PhraseSoundModel model) {
- Preconditions.checkNotNull(model);
+ Objects.requireNonNull(model);
validateModel(model.common, SoundModelType.KEYPHRASE);
- Preconditions.checkNotNull(model.phrases);
+ Objects.requireNonNull(model.phrases);
for (Phrase phrase : model.phrases) {
- Preconditions.checkNotNull(phrase);
+ Objects.requireNonNull(phrase);
if ((phrase.recognitionModes & ~(RecognitionMode.VOICE_TRIGGER
| RecognitionMode.USER_IDENTIFICATION | RecognitionMode.USER_AUTHENTICATION
| RecognitionMode.GENERIC_TRIGGER)) != 0) {
throw new IllegalArgumentException("Invalid recognitionModes");
}
- Preconditions.checkNotNull(phrase.users);
- Preconditions.checkNotNull(phrase.locale);
- Preconditions.checkNotNull(phrase.text);
+ Objects.requireNonNull(phrase.users);
+ Objects.requireNonNull(phrase.locale);
+ Objects.requireNonNull(phrase.text);
}
}
static void validateRecognitionConfig(@Nullable RecognitionConfig config) {
- Preconditions.checkNotNull(config);
- Preconditions.checkNotNull(config.phraseRecognitionExtras);
+ Objects.requireNonNull(config);
+ Objects.requireNonNull(config.phraseRecognitionExtras);
for (PhraseRecognitionExtra extra : config.phraseRecognitionExtras) {
- Preconditions.checkNotNull(extra);
+ Objects.requireNonNull(extra);
if ((extra.recognitionModes & ~(RecognitionMode.VOICE_TRIGGER
| RecognitionMode.USER_IDENTIFICATION | RecognitionMode.USER_AUTHENTICATION
| RecognitionMode.GENERIC_TRIGGER)) != 0) {
@@ -94,15 +95,15 @@
if (extra.confidenceLevel < 0 || extra.confidenceLevel > 100) {
throw new IllegalArgumentException("Invalid confidenceLevel");
}
- Preconditions.checkNotNull(extra.levels);
+ Objects.requireNonNull(extra.levels);
for (ConfidenceLevel level : extra.levels) {
- Preconditions.checkNotNull(level);
+ Objects.requireNonNull(level);
if (level.levelPercent < 0 || level.levelPercent > 100) {
throw new IllegalArgumentException("Invalid confidenceLevel");
}
}
}
- Preconditions.checkNotNull(config.data);
+ Objects.requireNonNull(config.data);
}
static void validateModelParameter(int modelParam) {
diff --git a/telephony/java/android/telephony/Annotation.java b/telephony/java/android/telephony/Annotation.java
index 077b67a..9e6dfef 100644
--- a/telephony/java/android/telephony/Annotation.java
+++ b/telephony/java/android/telephony/Annotation.java
@@ -98,7 +98,13 @@
TelephonyManager.NETWORK_TYPE_GSM,
TelephonyManager.NETWORK_TYPE_TD_SCDMA,
TelephonyManager.NETWORK_TYPE_IWLAN,
- TelephonyManager.NETWORK_TYPE_LTE_CA,
+
+ //TODO: In order for @SystemApi methods to use this class, there cannot be any
+ // public hidden members. This network type is marked as hidden because it is not a
+ // true network type and we are looking to remove it completely from the available list
+ // of network types.
+ //TelephonyManager.NETWORK_TYPE_LTE_CA,
+
TelephonyManager.NETWORK_TYPE_NR,
})
@Retention(RetentionPolicy.SOURCE)
diff --git a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java
index daa85bd..f6699fa 100644
--- a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java
+++ b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java
@@ -31,6 +31,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.pm.PackageManager;
import android.content.rollback.RollbackInfo;
import android.content.rollback.RollbackManager;
import android.os.UserManager;
@@ -1122,4 +1123,39 @@
InstallUtils.dropShellPermissionIdentity();
}
}
+
+ @Test
+ public void testRollbackDataPolicy() throws Exception {
+ try {
+ InstallUtils.adoptShellPermissionIdentity(
+ Manifest.permission.INSTALL_PACKAGES,
+ Manifest.permission.DELETE_PACKAGES,
+ Manifest.permission.TEST_MANAGE_ROLLBACKS);
+
+ Uninstall.packages(TestApp.A, TestApp.B);
+ Install.multi(TestApp.A1, TestApp.B1).commit();
+ // Write user data version = 1
+ InstallUtils.processUserData(TestApp.A);
+ InstallUtils.processUserData(TestApp.B);
+
+ Install a2 = Install.single(TestApp.A2)
+ .setEnableRollback(PackageManager.RollbackDataPolicy.WIPE);
+ Install b2 = Install.single(TestApp.B2)
+ .setEnableRollback(PackageManager.RollbackDataPolicy.RESTORE);
+ Install.multi(a2, b2).setEnableRollback().commit();
+ // Write user data version = 2
+ InstallUtils.processUserData(TestApp.A);
+ InstallUtils.processUserData(TestApp.B);
+
+ RollbackInfo info = RollbackUtils.getAvailableRollback(TestApp.A);
+ RollbackUtils.rollback(info.getRollbackId());
+ // Read user data version from userdata.txt
+ // A's user data version is -1 for user data is wiped.
+ // B's user data version is 1 as rollback committed.
+ assertThat(InstallUtils.getUserDataVersion(TestApp.A)).isEqualTo(-1);
+ assertThat(InstallUtils.getUserDataVersion(TestApp.B)).isEqualTo(1);
+ } finally {
+ InstallUtils.dropShellPermissionIdentity();
+ }
+ }
}
diff --git a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java
index bb3906d..40169b8 100644
--- a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java
+++ b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java
@@ -384,6 +384,44 @@
RollbackUtils.getRollbackManager().expireRollbackForPackage(getModuleMetadataPackageName());
}
+ @Test
+ public void testRollbackDataPolicy_Phase1() throws Exception {
+ Uninstall.packages(TestApp.A, TestApp.B);
+ Install.multi(TestApp.A1, TestApp.B1).commit();
+ // Write user data version = 1
+ InstallUtils.processUserData(TestApp.A);
+ InstallUtils.processUserData(TestApp.B);
+
+ Install a2 = Install.single(TestApp.A2).setStaged()
+ .setEnableRollback(PackageManager.RollbackDataPolicy.WIPE);
+ Install b2 = Install.single(TestApp.B2).setStaged()
+ .setEnableRollback(PackageManager.RollbackDataPolicy.RESTORE);
+ Install.multi(a2, b2).setEnableRollback().setStaged().commit();
+ }
+
+ @Test
+ public void testRollbackDataPolicy_Phase2() throws Exception {
+ assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
+ assertThat(InstallUtils.getInstalledVersion(TestApp.B)).isEqualTo(2);
+ // Write user data version = 2
+ InstallUtils.processUserData(TestApp.A);
+ InstallUtils.processUserData(TestApp.B);
+
+ RollbackInfo info = RollbackUtils.getAvailableRollback(TestApp.A);
+ RollbackUtils.rollback(info.getRollbackId());
+ }
+
+ @Test
+ public void testRollbackDataPolicy_Phase3() throws Exception {
+ assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);
+ assertThat(InstallUtils.getInstalledVersion(TestApp.B)).isEqualTo(1);
+ // Read user data version from userdata.txt
+ // A's user data version is -1 for user data is wiped.
+ // B's user data version is 1 as rollback committed.
+ assertThat(InstallUtils.getUserDataVersion(TestApp.A)).isEqualTo(-1);
+ assertThat(InstallUtils.getUserDataVersion(TestApp.B)).isEqualTo(1);
+ }
+
private static void runShellCommand(String cmd) {
ParcelFileDescriptor pfd = InstrumentationRegistry.getInstrumentation().getUiAutomation()
.executeShellCommand(cmd);
diff --git a/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java b/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java
index 8ab4c4c..4644d8a 100644
--- a/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java
+++ b/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java
@@ -192,6 +192,15 @@
}
}
+ @Test
+ public void testRollbackDataPolicy() throws Exception {
+ runPhase("testRollbackDataPolicy_Phase1");
+ getDevice().reboot();
+ runPhase("testRollbackDataPolicy_Phase2");
+ getDevice().reboot();
+ runPhase("testRollbackDataPolicy_Phase3");
+ }
+
private void crashProcess(String processName, int numberOfCrashes) throws Exception {
String pid = "";
String lastPid = "invalid";
diff --git a/tools/stats_log_api_gen/Android.bp b/tools/stats_log_api_gen/Android.bp
index 15c3278..d3958a6 100644
--- a/tools/stats_log_api_gen/Android.bp
+++ b/tools/stats_log_api_gen/Android.bp
@@ -25,6 +25,8 @@
"java_writer.cpp",
"java_writer_q.cpp",
"main.cpp",
+ "native_writer.cpp",
+ "native_writer_q.cpp",
"utils.cpp",
],
cflags: [
@@ -121,17 +123,5 @@
"libcutils",
],
static_libs: ["libstatssocket"],
- target: {
- android: {
- shared_libs: [
- "libutils",
- ],
- },
- host: {
- static_libs: [
- "libutils",
- ],
- },
- },
}
diff --git a/tools/stats_log_api_gen/Collation.cpp b/tools/stats_log_api_gen/Collation.cpp
index fa55601..0b82a3d 100644
--- a/tools/stats_log_api_gen/Collation.cpp
+++ b/tools/stats_log_api_gen/Collation.cpp
@@ -405,9 +405,9 @@
atomDecl.whitelisted = true;
}
- if (atomField->options().HasExtension(os::statsd::log_from_module)) {
+ if (atomField->options().HasExtension(os::statsd::module)) {
atomDecl.hasModule = true;
- atomDecl.moduleName = atomField->options().GetExtension(os::statsd::log_from_module);
+ atomDecl.moduleName = atomField->options().GetExtension(os::statsd::module);
}
vector<java_type_t> signature;
diff --git a/tools/stats_log_api_gen/atoms_info_writer.h b/tools/stats_log_api_gen/atoms_info_writer.h
index bc67782..12ac862 100644
--- a/tools/stats_log_api_gen/atoms_info_writer.h
+++ b/tools/stats_log_api_gen/atoms_info_writer.h
@@ -27,8 +27,7 @@
using namespace std;
int write_atoms_info_cpp(FILE* out, const Atoms& atoms, const string& namespaceStr,
- const string& importHeader, const string& statslogHeader
-);
+ const string& importHeader, const string& statslogHeader);
int write_atoms_info_header(FILE* out, const Atoms& atoms, const string& namespaceStr);
diff --git a/tools/stats_log_api_gen/java_writer.cpp b/tools/stats_log_api_gen/java_writer.cpp
index 712b48e..7f0872c 100644
--- a/tools/stats_log_api_gen/java_writer.cpp
+++ b/tools/stats_log_api_gen/java_writer.cpp
@@ -48,7 +48,8 @@
FILE* out,
const map<vector<java_type_t>, set<string>>& signatures_to_modules,
const AtomDecl &attributionDecl,
- const string& moduleName
+ const string& moduleName,
+ const bool supportQ
) {
for (auto signature_to_modules_it = signatures_to_modules.begin();
signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) {
@@ -82,8 +83,10 @@
// Print method body.
string indent("");
- if (DEFAULT_MODULE_NAME != moduleName) {
- fprintf(out, " if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Q) {\n");
+ if (supportQ) {
+ // TODO(b/146235828): Use just SDK_INT check once it is incremented from Q.
+ fprintf(out, " if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Q ||\n");
+ fprintf(out, " Build.VERSION.CODENAME.equals(\"R\")) {\n");
indent = " ";
}
@@ -193,7 +196,7 @@
fprintf(out, "%s StatsLog.write(builder.build());\n", indent.c_str());
// Add support for writing using Q schema if this is not the default module.
- if (DEFAULT_MODULE_NAME != moduleName) {
+ if (supportQ) {
fprintf(out, " } else {\n");
fprintf(out, " QLogger.write(code");
argIndex = 1;
@@ -225,15 +228,17 @@
int write_stats_log_java(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl,
const string& moduleName, const string& javaClass,
- const string& javaPackage) {
+ const string& javaPackage, const bool supportQ) {
// Print prelude
fprintf(out, "// This file is autogenerated\n");
fprintf(out, "\n");
fprintf(out, "package %s;\n", javaPackage.c_str());
fprintf(out, "\n");
fprintf(out, "\n");
- fprintf(out, "import android.os.Build;\n");
- fprintf(out, "import android.os.SystemClock;\n");
+ if (supportQ) {
+ fprintf(out, "import android.os.Build;\n");
+ fprintf(out, "import android.os.SystemClock;\n");
+ }
if (DEFAULT_MODULE_NAME == moduleName) {
// Mainline modules don't use WorkSource logging.
@@ -271,12 +276,15 @@
// Print write methods.
fprintf(out, " // Write methods\n");
- errors += write_java_methods(out, atoms.signatures_to_modules, attributionDecl, moduleName);
+ errors += write_java_methods(
+ out, atoms.signatures_to_modules, attributionDecl, moduleName, supportQ);
errors += write_java_non_chained_methods(
out, atoms.non_chained_signatures_to_modules, moduleName);
if (DEFAULT_MODULE_NAME == moduleName) {
errors += write_java_work_source_methods(out, atoms.signatures_to_modules, moduleName);
- } else {
+ }
+
+ if (supportQ) {
errors += write_java_q_logger_class(
out, atoms.signatures_to_modules, attributionDecl, moduleName);
}
diff --git a/tools/stats_log_api_gen/java_writer.h b/tools/stats_log_api_gen/java_writer.h
index 031266b..9324b23 100644
--- a/tools/stats_log_api_gen/java_writer.h
+++ b/tools/stats_log_api_gen/java_writer.h
@@ -32,8 +32,7 @@
int write_stats_log_java(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl,
const string& moduleName, const string& javaClass,
- const string& javaPackage
-);
+ const string& javaPackage, const bool supportQ);
} // namespace stats_log_api_gen
} // namespace android
diff --git a/tools/stats_log_api_gen/java_writer_q.h b/tools/stats_log_api_gen/java_writer_q.h
index c8f4ccf..96ac745 100644
--- a/tools/stats_log_api_gen/java_writer_q.h
+++ b/tools/stats_log_api_gen/java_writer_q.h
@@ -37,22 +37,20 @@
const map<vector<java_type_t>, set<string>>& signatures_to_modules,
const AtomDecl &attributionDecl,
const string& moduleName,
- const string& indent
-);
+ const string& indent);
void write_java_helpers_for_q_schema_methods(
FILE * out,
const AtomDecl &attributionDecl,
const int requiredHelpers,
- const string& indent
-);
+ const string& indent);
#if defined(STATS_SCHEMA_LEGACY)
int write_stats_log_java_q(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl);
-int write_stats_log_java_q_for_module(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl,
- const string& moduleName, const string& javaClass,
- const string& javaPackage);
+int write_stats_log_java_q_for_module(FILE* out, const Atoms& atoms,
+ const AtomDecl &attributionDecl, const string& moduleName, const string& javaClass,
+ const string& javaPackage);
#endif
} // namespace stats_log_api_gen
} // namespace android
diff --git a/tools/stats_log_api_gen/main.cpp b/tools/stats_log_api_gen/main.cpp
index ad171da..00a3704 100644
--- a/tools/stats_log_api_gen/main.cpp
+++ b/tools/stats_log_api_gen/main.cpp
@@ -6,6 +6,7 @@
#include "java_writer.h"
#endif
#include "java_writer_q.h"
+#include "native_writer.h"
#include "utils.h"
#include "frameworks/base/cmds/statsd/src/atoms.pb.h"
@@ -27,496 +28,6 @@
using android::os::statsd::Atom;
-static int write_stats_log_cpp(FILE *out, const Atoms &atoms, const AtomDecl &attributionDecl,
- const string& moduleName, const string& cppNamespace,
- const string& importHeader) {
- // Print prelude
- fprintf(out, "// This file is autogenerated\n");
- fprintf(out, "\n");
-
- fprintf(out, "#include <mutex>\n");
- fprintf(out, "#include <chrono>\n");
- fprintf(out, "#include <thread>\n");
- fprintf(out, "#ifdef __ANDROID__\n");
- fprintf(out, "#include <cutils/properties.h>\n");
- fprintf(out, "#endif\n");
- fprintf(out, "#include <stats_event_list.h>\n");
- fprintf(out, "#include <log/log.h>\n");
- fprintf(out, "#include <%s>\n", importHeader.c_str());
- fprintf(out, "#include <utils/SystemClock.h>\n");
- fprintf(out, "\n");
-
- write_namespace(out, cppNamespace);
- fprintf(out, "// the single event tag id for all stats logs\n");
- fprintf(out, "const static int kStatsEventTag = 1937006964;\n");
- fprintf(out, "#ifdef __ANDROID__\n");
- fprintf(out, "const static bool kStatsdEnabled = property_get_bool(\"ro.statsd.enable\", true);\n");
- fprintf(out, "#else\n");
- fprintf(out, "const static bool kStatsdEnabled = false;\n");
- fprintf(out, "#endif\n");
-
- fprintf(out, "int64_t lastRetryTimestampNs = -1;\n");
- fprintf(out, "const int64_t kMinRetryIntervalNs = NS_PER_SEC * 60 * 20; // 20 minutes\n");
- fprintf(out, "static std::mutex mLogdRetryMutex;\n");
-
- // Print write methods
- fprintf(out, "\n");
- for (auto signature_to_modules_it = atoms.signatures_to_modules.begin();
- signature_to_modules_it != atoms.signatures_to_modules.end(); signature_to_modules_it++) {
- if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) {
- continue;
- }
- vector<java_type_t> signature = signature_to_modules_it->first;
- int argIndex;
-
- fprintf(out, "int\n");
- fprintf(out, "try_stats_write(int32_t code");
- argIndex = 1;
- for (vector<java_type_t>::const_iterator arg = signature.begin();
- arg != signature.end(); arg++) {
- if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
- for (auto chainField : attributionDecl.fields) {
- if (chainField.javaType == JAVA_TYPE_STRING) {
- fprintf(out, ", const std::vector<%s>& %s",
- cpp_type_name(chainField.javaType),
- chainField.name.c_str());
- } else {
- fprintf(out, ", const %s* %s, size_t %s_length",
- cpp_type_name(chainField.javaType),
- chainField.name.c_str(), chainField.name.c_str());
- }
- }
- } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) {
- fprintf(out, ", const std::map<int, int32_t>& arg%d_1, "
- "const std::map<int, int64_t>& arg%d_2, "
- "const std::map<int, char const*>& arg%d_3, "
- "const std::map<int, float>& arg%d_4",
- argIndex, argIndex, argIndex, argIndex);
- } else {
- fprintf(out, ", %s arg%d", cpp_type_name(*arg), argIndex);
- }
- argIndex++;
- }
- fprintf(out, ")\n");
-
- fprintf(out, "{\n");
- argIndex = 1;
- fprintf(out, " if (kStatsdEnabled) {\n");
- fprintf(out, " stats_event_list event(kStatsEventTag);\n");
- fprintf(out, " event << android::elapsedRealtimeNano();\n\n");
- fprintf(out, " event << code;\n\n");
- for (vector<java_type_t>::const_iterator arg = signature.begin();
- arg != signature.end(); arg++) {
- if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
- for (const auto &chainField : attributionDecl.fields) {
- if (chainField.javaType == JAVA_TYPE_STRING) {
- fprintf(out, " if (%s_length != %s.size()) {\n",
- attributionDecl.fields.front().name.c_str(), chainField.name.c_str());
- fprintf(out, " return -EINVAL;\n");
- fprintf(out, " }\n");
- }
- }
- fprintf(out, "\n event.begin();\n");
- fprintf(out, " for (size_t i = 0; i < %s_length; ++i) {\n",
- attributionDecl.fields.front().name.c_str());
- fprintf(out, " event.begin();\n");
- for (const auto &chainField : attributionDecl.fields) {
- if (chainField.javaType == JAVA_TYPE_STRING) {
- fprintf(out, " if (%s[i] != NULL) {\n", chainField.name.c_str());
- fprintf(out, " event << %s[i];\n", chainField.name.c_str());
- fprintf(out, " } else {\n");
- fprintf(out, " event << \"\";\n");
- fprintf(out, " }\n");
- } else {
- fprintf(out, " event << %s[i];\n", chainField.name.c_str());
- }
- }
- fprintf(out, " event.end();\n");
- fprintf(out, " }\n");
- fprintf(out, " event.end();\n\n");
- } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) {
- fprintf(out, " event.begin();\n\n");
- fprintf(out, " for (const auto& it : arg%d_1) {\n", argIndex);
- fprintf(out, " event.begin();\n");
- fprintf(out, " event << it.first;\n");
- fprintf(out, " event << it.second;\n");
- fprintf(out, " event.end();\n");
- fprintf(out, " }\n");
-
- fprintf(out, " for (const auto& it : arg%d_2) {\n", argIndex);
- fprintf(out, " event.begin();\n");
- fprintf(out, " event << it.first;\n");
- fprintf(out, " event << it.second;\n");
- fprintf(out, " event.end();\n");
- fprintf(out, " }\n");
-
- fprintf(out, " for (const auto& it : arg%d_3) {\n", argIndex);
- fprintf(out, " event.begin();\n");
- fprintf(out, " event << it.first;\n");
- fprintf(out, " event << it.second;\n");
- fprintf(out, " event.end();\n");
- fprintf(out, " }\n");
-
- fprintf(out, " for (const auto& it : arg%d_4) {\n", argIndex);
- fprintf(out, " event.begin();\n");
- fprintf(out, " event << it.first;\n");
- fprintf(out, " event << it.second;\n");
- fprintf(out, " event.end();\n");
- fprintf(out, " }\n");
-
- fprintf(out, " event.end();\n\n");
- } else if (*arg == JAVA_TYPE_BYTE_ARRAY) {
- fprintf(out,
- " event.AppendCharArray(arg%d.arg, "
- "arg%d.arg_length);\n",
- argIndex, argIndex);
- } else {
- if (*arg == JAVA_TYPE_STRING) {
- fprintf(out, " if (arg%d == NULL) {\n", argIndex);
- fprintf(out, " arg%d = \"\";\n", argIndex);
- fprintf(out, " }\n");
- }
- fprintf(out, " event << arg%d;\n", argIndex);
- }
- argIndex++;
- }
-
- fprintf(out, " return event.write(LOG_ID_STATS);\n");
- fprintf(out, " } else {\n");
- fprintf(out, " return 1;\n");
- fprintf(out, " }\n");
- fprintf(out, "}\n");
- fprintf(out, "\n");
- }
-
- for (auto signature_to_modules_it = atoms.signatures_to_modules.begin();
- signature_to_modules_it != atoms.signatures_to_modules.end(); signature_to_modules_it++) {
- if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) {
- continue;
- }
- vector<java_type_t> signature = signature_to_modules_it->first;
- int argIndex;
-
- fprintf(out, "int\n");
- fprintf(out, "stats_write(int32_t code");
- argIndex = 1;
- for (vector<java_type_t>::const_iterator arg = signature.begin();
- arg != signature.end(); arg++) {
- if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
- for (auto chainField : attributionDecl.fields) {
- if (chainField.javaType == JAVA_TYPE_STRING) {
- fprintf(out, ", const std::vector<%s>& %s",
- cpp_type_name(chainField.javaType),
- chainField.name.c_str());
- } else {
- fprintf(out, ", const %s* %s, size_t %s_length",
- cpp_type_name(chainField.javaType),
- chainField.name.c_str(), chainField.name.c_str());
- }
- }
- } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) {
- fprintf(out,
- ", const std::map<int, int32_t>& arg%d_1, "
- "const std::map<int, int64_t>& arg%d_2, "
- "const std::map<int, char const*>& arg%d_3, "
- "const std::map<int, float>& arg%d_4",
- argIndex, argIndex, argIndex, argIndex);
- } else {
- fprintf(out, ", %s arg%d", cpp_type_name(*arg), argIndex);
- }
- argIndex++;
- }
- fprintf(out, ")\n");
-
- fprintf(out, "{\n");
- fprintf(out, " int ret = 0;\n");
-
- fprintf(out, " for(int retry = 0; retry < 2; ++retry) {\n");
- fprintf(out, " ret = try_stats_write(code");
-
- argIndex = 1;
- for (vector<java_type_t>::const_iterator arg = signature.begin();
- arg != signature.end(); arg++) {
- if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
- for (auto chainField : attributionDecl.fields) {
- if (chainField.javaType == JAVA_TYPE_STRING) {
- fprintf(out, ", %s",
- chainField.name.c_str());
- } else {
- fprintf(out, ", %s, %s_length",
- chainField.name.c_str(), chainField.name.c_str());
- }
- }
- } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) {
- fprintf(out, ", arg%d_1, arg%d_2, arg%d_3, arg%d_4", argIndex,
- argIndex, argIndex, argIndex);
- } else {
- fprintf(out, ", arg%d", argIndex);
- }
- argIndex++;
- }
- fprintf(out, ");\n");
- fprintf(out, " if (ret >= 0) { break; }\n");
-
- fprintf(out, " {\n");
- fprintf(out, " std::lock_guard<std::mutex> lock(mLogdRetryMutex);\n");
- fprintf(out, " if ((android::elapsedRealtimeNano() - lastRetryTimestampNs) <= "
- "kMinRetryIntervalNs) break;\n");
- fprintf(out, " lastRetryTimestampNs = android::elapsedRealtimeNano();\n");
- fprintf(out, " }\n");
- fprintf(out, " std::this_thread::sleep_for(std::chrono::milliseconds(10));\n");
- fprintf(out, " }\n");
- fprintf(out, " if (ret < 0) {\n");
- fprintf(out, " note_log_drop(ret, code);\n");
- fprintf(out, " }\n");
- fprintf(out, " return ret;\n");
- fprintf(out, "}\n");
- fprintf(out, "\n");
- }
-
- for (auto signature_it = atoms.non_chained_signatures_to_modules.begin();
- signature_it != atoms.non_chained_signatures_to_modules.end(); signature_it++) {
- if (!signature_needed_for_module(signature_it->second, moduleName)) {
- continue;
- }
- vector<java_type_t> signature = signature_it->first;
- int argIndex;
-
- fprintf(out, "int\n");
- fprintf(out, "try_stats_write_non_chained(int32_t code");
- argIndex = 1;
- for (vector<java_type_t>::const_iterator arg = signature.begin();
- arg != signature.end(); arg++) {
- fprintf(out, ", %s arg%d", cpp_type_name(*arg), argIndex);
- argIndex++;
- }
- fprintf(out, ")\n");
-
- fprintf(out, "{\n");
- argIndex = 1;
- fprintf(out, " if (kStatsdEnabled) {\n");
- fprintf(out, " stats_event_list event(kStatsEventTag);\n");
- fprintf(out, " event << android::elapsedRealtimeNano();\n\n");
- fprintf(out, " event << code;\n\n");
- for (vector<java_type_t>::const_iterator arg = signature.begin();
- arg != signature.end(); arg++) {
- if (argIndex == 1) {
- fprintf(out, " event.begin();\n\n");
- fprintf(out, " event.begin();\n");
- }
- if (*arg == JAVA_TYPE_STRING) {
- fprintf(out, " if (arg%d == NULL) {\n", argIndex);
- fprintf(out, " arg%d = \"\";\n", argIndex);
- fprintf(out, " }\n");
- }
- if (*arg == JAVA_TYPE_BYTE_ARRAY) {
- fprintf(out,
- " event.AppendCharArray(arg%d.arg, "
- "arg%d.arg_length);",
- argIndex, argIndex);
- } else {
- fprintf(out, " event << arg%d;\n", argIndex);
- }
- if (argIndex == 2) {
- fprintf(out, " event.end();\n\n");
- fprintf(out, " event.end();\n\n");
- }
- argIndex++;
- }
-
- fprintf(out, " return event.write(LOG_ID_STATS);\n");
- fprintf(out, " } else {\n");
- fprintf(out, " return 1;\n");
- fprintf(out, " }\n");
- fprintf(out, "}\n");
- fprintf(out, "\n");
- }
-
- for (auto signature_it = atoms.non_chained_signatures_to_modules.begin();
- signature_it != atoms.non_chained_signatures_to_modules.end(); signature_it++) {
- if (!signature_needed_for_module(signature_it->second, moduleName)) {
- continue;
- }
- vector<java_type_t> signature = signature_it->first;
- int argIndex;
-
- fprintf(out, "int\n");
- fprintf(out, "stats_write_non_chained(int32_t code");
- argIndex = 1;
- for (vector<java_type_t>::const_iterator arg = signature.begin();
- arg != signature.end(); arg++) {
- fprintf(out, ", %s arg%d", cpp_type_name(*arg), argIndex);
- argIndex++;
- }
- fprintf(out, ")\n");
-
- fprintf(out, "{\n");
-
- fprintf(out, " int ret = 0;\n");
- fprintf(out, " for(int retry = 0; retry < 2; ++retry) {\n");
- fprintf(out, " ret = try_stats_write_non_chained(code");
-
- argIndex = 1;
- for (vector<java_type_t>::const_iterator arg = signature.begin();
- arg != signature.end(); arg++) {
- fprintf(out, ", arg%d", argIndex);
- argIndex++;
- }
- fprintf(out, ");\n");
- fprintf(out, " if (ret >= 0) { break; }\n");
-
- fprintf(out, " {\n");
- fprintf(out, " std::lock_guard<std::mutex> lock(mLogdRetryMutex);\n");
- fprintf(out, " if ((android::elapsedRealtimeNano() - lastRetryTimestampNs) <= "
- "kMinRetryIntervalNs) break;\n");
- fprintf(out, " lastRetryTimestampNs = android::elapsedRealtimeNano();\n");
- fprintf(out, " }\n");
-
- fprintf(out, " std::this_thread::sleep_for(std::chrono::milliseconds(10));\n");
- fprintf(out, " }\n");
- fprintf(out, " if (ret < 0) {\n");
- fprintf(out, " note_log_drop(ret, code);\n");
- fprintf(out, " }\n");
- fprintf(out, " return ret;\n\n");
- fprintf(out, "}\n");
-
- fprintf(out, "\n");
- }
-
-
- // Print footer
- fprintf(out, "\n");
- write_closing_namespace(out, cppNamespace);
-
- return 0;
-}
-
-static void write_cpp_method_header(
- FILE* out,
- const string& method_name,
- const map<vector<java_type_t>, set<string>>& signatures_to_modules,
- const AtomDecl &attributionDecl, const string& moduleName) {
-
- for (auto signature_to_modules_it = signatures_to_modules.begin();
- signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) {
- // Skip if this signature is not needed for the module.
- if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) {
- continue;
- }
-
- vector<java_type_t> signature = signature_to_modules_it->first;
- fprintf(out, "int %s(int32_t code", method_name.c_str());
- int argIndex = 1;
- for (vector<java_type_t>::const_iterator arg = signature.begin();
- arg != signature.end(); arg++) {
- if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
- for (auto chainField : attributionDecl.fields) {
- if (chainField.javaType == JAVA_TYPE_STRING) {
- fprintf(out, ", const std::vector<%s>& %s",
- cpp_type_name(chainField.javaType), chainField.name.c_str());
- } else {
- fprintf(out, ", const %s* %s, size_t %s_length",
- cpp_type_name(chainField.javaType),
- chainField.name.c_str(), chainField.name.c_str());
- }
- }
- } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) {
- fprintf(out, ", const std::map<int, int32_t>& arg%d_1, "
- "const std::map<int, int64_t>& arg%d_2, "
- "const std::map<int, char const*>& arg%d_3, "
- "const std::map<int, float>& arg%d_4",
- argIndex, argIndex, argIndex, argIndex);
- } else {
- fprintf(out, ", %s arg%d", cpp_type_name(*arg), argIndex);
- }
- argIndex++;
- }
- fprintf(out, ");\n");
-
- }
-}
-
-static int
-write_stats_log_header(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl,
- const string& moduleName, const string& cppNamespace)
-{
- // Print prelude
- fprintf(out, "// This file is autogenerated\n");
- fprintf(out, "\n");
- fprintf(out, "#pragma once\n");
- fprintf(out, "\n");
- fprintf(out, "#include <stdint.h>\n");
- fprintf(out, "#include <vector>\n");
- fprintf(out, "#include <map>\n");
- fprintf(out, "#include <set>\n");
- fprintf(out, "\n");
-
- write_namespace(out, cppNamespace);
- fprintf(out, "\n");
- fprintf(out, "/*\n");
- fprintf(out, " * API For logging statistics events.\n");
- fprintf(out, " */\n");
- fprintf(out, "\n");
-
- write_native_atom_constants(out, atoms, attributionDecl, moduleName);
-
- // Print constants for the enum values.
- fprintf(out, "//\n");
- fprintf(out, "// Constants for enum values\n");
- fprintf(out, "//\n\n");
- for (set<AtomDecl>::const_iterator atom = atoms.decls.begin();
- atom != atoms.decls.end(); atom++) {
- // Skip if the atom is not needed for the module.
- if (!atom_needed_for_module(*atom, moduleName)) {
- continue;
- }
-
- for (vector<AtomField>::const_iterator field = atom->fields.begin();
- field != atom->fields.end(); field++) {
- if (field->javaType == JAVA_TYPE_ENUM) {
- fprintf(out, "// Values for %s.%s\n", atom->message.c_str(),
- field->name.c_str());
- for (map<int, string>::const_iterator value = field->enumValues.begin();
- value != field->enumValues.end(); value++) {
- fprintf(out, "const int32_t %s__%s__%s = %d;\n",
- make_constant_name(atom->message).c_str(),
- make_constant_name(field->name).c_str(),
- make_constant_name(value->second).c_str(),
- value->first);
- }
- fprintf(out, "\n");
- }
- }
- }
-
- fprintf(out, "struct BytesField {\n");
- fprintf(out,
- " BytesField(char const* array, size_t len) : arg(array), "
- "arg_length(len) {}\n");
- fprintf(out, " char const* arg;\n");
- fprintf(out, " size_t arg_length;\n");
- fprintf(out, "};\n");
- fprintf(out, "\n");
-
- // Print write methods
- fprintf(out, "//\n");
- fprintf(out, "// Write methods\n");
- fprintf(out, "//\n");
- write_cpp_method_header(out, "stats_write", atoms.signatures_to_modules, attributionDecl,
- moduleName);
-
- fprintf(out, "//\n");
- fprintf(out, "// Write flattened methods\n");
- fprintf(out, "//\n");
- write_cpp_method_header(out, "stats_write_non_chained", atoms.non_chained_signatures_to_modules,
- attributionDecl, moduleName);
-
- fprintf(out, "\n");
- write_closing_namespace(out, cppNamespace);
-
- return 0;
-}
-
// Hide the JNI write helpers that are not used in the new schema.
// TODO(b/145100015): Remove this and other JNI related functionality once StatsEvent migration is
// complete.
@@ -999,7 +510,9 @@
fprintf(stderr, " required for java with module\n");
fprintf(stderr, " --javaClass CLASS the class name of the java class.\n");
fprintf(stderr, " Optional for Java with module.\n");
- fprintf(stderr, " Default is \"StatsLogInternal\"\n");}
+ fprintf(stderr, " Default is \"StatsLogInternal\"\n");
+ fprintf(stderr, " --supportQ Include support for Android Q.\n");
+}
/**
* Do the argument parsing and execute the tasks.
@@ -1020,6 +533,7 @@
string atomsInfoCppHeaderImport = DEFAULT_ATOMS_INFO_CPP_HEADER_IMPORT;
string javaPackage = DEFAULT_JAVA_PACKAGE;
string javaClass = DEFAULT_JAVA_CLASS;
+ bool supportQ = false;
int index = 1;
while (index < argc) {
@@ -1110,6 +624,8 @@
return 1;
}
atomsInfoCppHeaderImport = argv[index];
+ } else if (0 == strcmp("--supportQ", argv[index])) {
+ supportQ = true;
}
index++;
@@ -1125,6 +641,12 @@
return 1;
}
+ if (DEFAULT_MODULE_NAME == moduleName && supportQ) {
+ // Support for Q schema is not needed for default module.
+ fprintf(stderr, "%s cannot support Q schema\n", moduleName.c_str());
+ return 1;
+ }
+
// Collate the parameters
Atoms atoms;
int errorCount = collate_atoms(Atom::descriptor(), &atoms);
@@ -1179,7 +701,7 @@
return 1;
}
errorCount = android::stats_log_api_gen::write_stats_log_cpp(
- out, atoms, attributionDecl, moduleName, cppNamespace, cppHeaderImport);
+ out, atoms, attributionDecl, moduleName, cppNamespace, cppHeaderImport, supportQ);
fclose(out);
}
@@ -1227,7 +749,7 @@
javaPackage = "android.util";
}
errorCount = android::stats_log_api_gen::write_stats_log_java(
- out, atoms, attributionDecl, moduleName, javaClass, javaPackage);
+ out, atoms, attributionDecl, moduleName, javaClass, javaPackage, supportQ);
#endif
fclose(out);
diff --git a/tools/stats_log_api_gen/native_writer.cpp b/tools/stats_log_api_gen/native_writer.cpp
new file mode 100644
index 0000000..c7a34fe
--- /dev/null
+++ b/tools/stats_log_api_gen/native_writer.cpp
@@ -0,0 +1,342 @@
+/*
+ * Copyright (C) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "native_writer.h"
+#include "native_writer_q.h"
+#include "utils.h"
+
+namespace android {
+namespace stats_log_api_gen {
+
+#if !defined(STATS_SCHEMA_LEGACY)
+static void write_native_key_value_pairs_for_type(FILE* out, const int argIndex,
+ const int typeIndex, const string& type, const string& valueFieldName) {
+ fprintf(out, " for (const auto& it : arg%d_%d) {\n", argIndex, typeIndex);
+ fprintf(out, " pairs.push_back("
+ "{ .key = it.first, .valueType = %s, .%s = it.second });\n",
+ type.c_str(), valueFieldName.c_str());
+ fprintf(out, " }\n");
+
+}
+
+static int write_native_stats_write_methods(FILE* out, const Atoms& atoms,
+ const AtomDecl& attributionDecl, const string& moduleName, const bool supportQ) {
+ fprintf(out, "\n");
+ for (auto signature_to_modules_it = atoms.signatures_to_modules.begin();
+ signature_to_modules_it != atoms.signatures_to_modules.end(); signature_to_modules_it++) {
+ if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) {
+ continue;
+ }
+ vector<java_type_t> signature = signature_to_modules_it->first;
+
+ write_native_method_signature(out, "int stats_write", signature,
+ attributionDecl, " {");
+
+ int argIndex = 1;
+ if (supportQ) {
+ fprintf(out, " StatsEventCompat event;\n");
+ fprintf(out, " event.setAtomId(code);\n");
+ for (vector<java_type_t>::const_iterator arg = signature.begin();
+ arg != signature.end(); arg++) {
+ switch (*arg) {
+ case JAVA_TYPE_ATTRIBUTION_CHAIN: {
+ const char* uidName = attributionDecl.fields.front().name.c_str();
+ const char* tagName = attributionDecl.fields.back().name.c_str();
+ fprintf(out, " event.writeAttributionChain(%s, %s_length, %s);\n",
+ uidName, uidName, tagName);
+ break;
+ }
+ case JAVA_TYPE_KEY_VALUE_PAIR:
+ fprintf(out, " event.writeKeyValuePairs("
+ "arg%d_1, arg%d_2, arg%d_3, arg%d_4);\n",
+ argIndex, argIndex, argIndex, argIndex);
+ break;
+ case JAVA_TYPE_BYTE_ARRAY:
+ fprintf(out, " event.writeByteArray(arg%d.arg, arg%d.arg_length);\n",
+ argIndex, argIndex);
+ break;
+ case JAVA_TYPE_BOOLEAN:
+ fprintf(out, " event.writeBool(arg%d);\n", argIndex);
+ break;
+ case JAVA_TYPE_INT: // Fall through.
+ case JAVA_TYPE_ENUM:
+ fprintf(out, " event.writeInt32(arg%d);\n", argIndex);
+ break;
+ case JAVA_TYPE_FLOAT:
+ fprintf(out, " event.writeFloat(arg%d);\n", argIndex);
+ break;
+ case JAVA_TYPE_LONG:
+ fprintf(out, " event.writeInt64(arg%d);\n", argIndex);
+ break;
+ case JAVA_TYPE_STRING:
+ fprintf(out, " event.writeString(arg%d);\n", argIndex);
+ break;
+ default:
+ // Unsupported types: OBJECT, DOUBLE.
+ fprintf(stderr, "Encountered unsupported type.");
+ return 1;
+ }
+ argIndex++;
+ }
+ fprintf(out, " return event.writeToSocket();\n");
+ } else {
+ fprintf(out, " struct stats_event* event = stats_event_obtain();\n");
+ fprintf(out, " stats_event_set_atom_id(event, code);\n");
+ for (vector<java_type_t>::const_iterator arg = signature.begin();
+ arg != signature.end(); arg++) {
+ switch (*arg) {
+ case JAVA_TYPE_ATTRIBUTION_CHAIN: {
+ const char* uidName = attributionDecl.fields.front().name.c_str();
+ const char* tagName = attributionDecl.fields.back().name.c_str();
+ fprintf(out,
+ " stats_event_write_attribution_chain(event, "
+ "reinterpret_cast<const uint32_t*>(%s), %s.data(), "
+ "static_cast<uint8_t>(%s_length));\n",
+ uidName, tagName, uidName);
+ break;
+ }
+ case JAVA_TYPE_KEY_VALUE_PAIR:
+ fprintf(out, " std::vector<key_value_pair> pairs;\n");
+ write_native_key_value_pairs_for_type(
+ out, argIndex, 1, "INT32_TYPE", "int32Value");
+ write_native_key_value_pairs_for_type(
+ out, argIndex, 2, "INT64_TYPE", "int64Value");
+ write_native_key_value_pairs_for_type(
+ out, argIndex, 3, "STRING_TYPE", "stringValue");
+ write_native_key_value_pairs_for_type(
+ out, argIndex, 4, "FLOAT_TYPE", "floatValue");
+ fprintf(out,
+ " stats_event_write_key_value_pairs(event, pairs.data(), "
+ "static_cast<uint8_t>(pairs.size()));\n");
+ break;
+ case JAVA_TYPE_BYTE_ARRAY:
+ fprintf(out,
+ " stats_event_write_byte_array(event, "
+ "reinterpret_cast<const uint8_t*>(arg%d.arg), arg%d.arg_length);\n",
+ argIndex, argIndex);
+ break;
+ case JAVA_TYPE_BOOLEAN:
+ fprintf(out, " stats_event_write_bool(event, arg%d);\n", argIndex);
+ break;
+ case JAVA_TYPE_INT: // Fall through.
+ case JAVA_TYPE_ENUM:
+ fprintf(out, " stats_event_write_int32(event, arg%d);\n", argIndex);
+ break;
+ case JAVA_TYPE_FLOAT:
+ fprintf(out, " stats_event_write_float(event, arg%d);\n", argIndex);
+ break;
+ case JAVA_TYPE_LONG:
+ fprintf(out, " stats_event_write_int64(event, arg%d);\n", argIndex);
+ break;
+ case JAVA_TYPE_STRING:
+ fprintf(out, " stats_event_write_string8(event, arg%d);\n", argIndex);
+ break;
+ default:
+ // Unsupported types: OBJECT, DOUBLE.
+ fprintf(stderr, "Encountered unsupported type.");
+ return 1;
+ }
+ argIndex++;
+ }
+ fprintf(out, " const int ret = stats_event_write(event);\n");
+ fprintf(out, " stats_event_release(event);\n");
+ fprintf(out, " return ret;\n");
+ }
+ fprintf(out, "}\n\n");
+ }
+ return 0;
+}
+
+static void write_native_stats_write_non_chained_methods(FILE* out, const Atoms& atoms,
+ const AtomDecl& attributionDecl, const string& moduleName) {
+ fprintf(out, "\n");
+ for (auto signature_it = atoms.non_chained_signatures_to_modules.begin();
+ signature_it != atoms.non_chained_signatures_to_modules.end(); signature_it++) {
+ if (!signature_needed_for_module(signature_it->second, moduleName)) {
+ continue;
+ }
+ vector<java_type_t> signature = signature_it->first;
+
+ write_native_method_signature(out, "int stats_write_non_chained", signature,
+ attributionDecl, " {");
+
+ vector<java_type_t> newSignature;
+
+ // First two args form the attribution node so size goes down by 1.
+ newSignature.reserve(signature.size() - 1);
+
+ // First arg is Attribution Chain.
+ newSignature.push_back(JAVA_TYPE_ATTRIBUTION_CHAIN);
+
+ // Followed by the originial signature except the first 2 args.
+ newSignature.insert(newSignature.end(), signature.begin() + 2, signature.end());
+
+ const char* uidName = attributionDecl.fields.front().name.c_str();
+ const char* tagName = attributionDecl.fields.back().name.c_str();
+ fprintf(out, " const int32_t* %s = &arg1;\n", uidName);
+ fprintf(out, " const size_t %s_length = 1;\n", uidName);
+ fprintf(out, " const std::vector<char const*> %s(1, arg2);\n", tagName);
+ fprintf(out, " return ");
+ write_native_method_call(out, "stats_write", newSignature, attributionDecl, 2);
+
+ fprintf(out, "}\n\n");
+ }
+
+}
+#endif
+
+static void write_native_method_header(
+ FILE* out,
+ const string& methodName,
+ const map<vector<java_type_t>, set<string>>& signatures_to_modules,
+ const AtomDecl &attributionDecl, const string& moduleName) {
+
+ for (auto signature_to_modules_it = signatures_to_modules.begin();
+ signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) {
+ // Skip if this signature is not needed for the module.
+ if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) {
+ continue;
+ }
+
+ vector<java_type_t> signature = signature_to_modules_it->first;
+ write_native_method_signature(out, methodName, signature, attributionDecl, ";");
+ }
+}
+
+int write_stats_log_cpp(FILE *out, const Atoms &atoms, const AtomDecl &attributionDecl,
+ const string& moduleName, const string& cppNamespace,
+ const string& importHeader, const bool supportQ) {
+ // Print prelude
+ fprintf(out, "// This file is autogenerated\n");
+ fprintf(out, "\n");
+
+ fprintf(out, "#include <%s>\n", importHeader.c_str());
+#if defined(STATS_SCHEMA_LEGACY)
+ (void)supportQ; // Workaround for unused parameter error.
+ write_native_cpp_includes_q(out);
+#else
+ if (supportQ) {
+ fprintf(out, "#include <StatsEventCompat.h>\n");
+ } else {
+ fprintf(out, "#include <stats_event.h>\n");
+ }
+#endif
+
+ fprintf(out, "\n");
+ write_namespace(out, cppNamespace);
+
+#if defined(STATS_SCHEMA_LEGACY)
+ write_native_stats_log_cpp_globals_q(out);
+ write_native_get_timestamp_ns_q(out);
+ write_native_try_stats_write_methods_q(out, atoms, attributionDecl, moduleName);
+ write_native_stats_write_methods_q(out, "int stats_write", atoms, attributionDecl, moduleName,
+ "try_stats_write");
+ write_native_try_stats_write_non_chained_methods_q(out, atoms, attributionDecl, moduleName);
+ write_native_stats_write_non_chained_methods_q(out, "int stats_write_non_chained", atoms,
+ attributionDecl, moduleName, "try_stats_write_non_chained");
+#else
+ write_native_stats_write_methods(out, atoms, attributionDecl, moduleName, supportQ);
+ write_native_stats_write_non_chained_methods(out, atoms, attributionDecl, moduleName);
+#endif
+
+ // Print footer
+ fprintf(out, "\n");
+ write_closing_namespace(out, cppNamespace);
+
+ return 0;
+}
+
+int write_stats_log_header(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl,
+ const string& moduleName, const string& cppNamespace) {
+ // Print prelude
+ fprintf(out, "// This file is autogenerated\n");
+ fprintf(out, "\n");
+ fprintf(out, "#pragma once\n");
+ fprintf(out, "\n");
+ fprintf(out, "#include <stdint.h>\n");
+ fprintf(out, "#include <vector>\n");
+ fprintf(out, "#include <map>\n");
+ fprintf(out, "#include <set>\n");
+ fprintf(out, "\n");
+
+ write_namespace(out, cppNamespace);
+ fprintf(out, "\n");
+ fprintf(out, "/*\n");
+ fprintf(out, " * API For logging statistics events.\n");
+ fprintf(out, " */\n");
+ fprintf(out, "\n");
+
+ write_native_atom_constants(out, atoms, attributionDecl, moduleName);
+
+ // Print constants for the enum values.
+ fprintf(out, "//\n");
+ fprintf(out, "// Constants for enum values\n");
+ fprintf(out, "//\n\n");
+ for (set<AtomDecl>::const_iterator atom = atoms.decls.begin();
+ atom != atoms.decls.end(); atom++) {
+ // Skip if the atom is not needed for the module.
+ if (!atom_needed_for_module(*atom, moduleName)) {
+ continue;
+ }
+
+ for (vector<AtomField>::const_iterator field = atom->fields.begin();
+ field != atom->fields.end(); field++) {
+ if (field->javaType == JAVA_TYPE_ENUM) {
+ fprintf(out, "// Values for %s.%s\n", atom->message.c_str(),
+ field->name.c_str());
+ for (map<int, string>::const_iterator value = field->enumValues.begin();
+ value != field->enumValues.end(); value++) {
+ fprintf(out, "const int32_t %s__%s__%s = %d;\n",
+ make_constant_name(atom->message).c_str(),
+ make_constant_name(field->name).c_str(),
+ make_constant_name(value->second).c_str(),
+ value->first);
+ }
+ fprintf(out, "\n");
+ }
+ }
+ }
+
+ fprintf(out, "struct BytesField {\n");
+ fprintf(out,
+ " BytesField(char const* array, size_t len) : arg(array), "
+ "arg_length(len) {}\n");
+ fprintf(out, " char const* arg;\n");
+ fprintf(out, " size_t arg_length;\n");
+ fprintf(out, "};\n");
+ fprintf(out, "\n");
+
+ // Print write methods
+ fprintf(out, "//\n");
+ fprintf(out, "// Write methods\n");
+ fprintf(out, "//\n");
+ write_native_method_header(out, "int stats_write", atoms.signatures_to_modules, attributionDecl,
+ moduleName);
+
+ fprintf(out, "//\n");
+ fprintf(out, "// Write flattened methods\n");
+ fprintf(out, "//\n");
+ write_native_method_header(out, "int stats_write_non_chained",
+ atoms.non_chained_signatures_to_modules, attributionDecl, moduleName);
+
+ fprintf(out, "\n");
+ write_closing_namespace(out, cppNamespace);
+
+ return 0;
+}
+
+} // namespace stats_log_api_gen
+} // namespace android
diff --git a/tools/stats_log_api_gen/native_writer.h b/tools/stats_log_api_gen/native_writer.h
new file mode 100644
index 0000000..aafa96e
--- /dev/null
+++ b/tools/stats_log_api_gen/native_writer.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2019, 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.
+ */
+
+#pragma once
+
+#include "Collation.h"
+
+#include <stdio.h>
+#include <string.h>
+
+namespace android {
+namespace stats_log_api_gen {
+
+using namespace std;
+
+int write_stats_log_cpp(FILE *out, const Atoms &atoms, const AtomDecl &attributionDecl,
+ const string& moduleName, const string& cppNamespace, const string& importHeader,
+ const bool supportQ);
+
+int write_stats_log_header(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl,
+ const string& moduleName, const string& cppNamespace);
+
+} // namespace stats_log_api_gen
+} // namespace android
diff --git a/tools/stats_log_api_gen/native_writer_q.cpp b/tools/stats_log_api_gen/native_writer_q.cpp
new file mode 100644
index 0000000..299873d
--- /dev/null
+++ b/tools/stats_log_api_gen/native_writer_q.cpp
@@ -0,0 +1,276 @@
+/*
+ * Copyright (C) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "native_writer_q.h"
+#include "utils.h"
+
+namespace android {
+namespace stats_log_api_gen {
+
+static void write_native_stats_write_body_q(FILE* out, const vector<java_type_t>& signature,
+ const AtomDecl& attributionDecl, const string& indent, const string& tryMethodName) {
+ fprintf(out, "%sint ret = 0;\n", indent.c_str());
+
+ fprintf(out, "%sfor(int retry = 0; retry < 2; ++retry) {\n", indent.c_str());
+ fprintf(out, "%s ret = ", indent.c_str());
+ write_native_method_call(out, tryMethodName, signature, attributionDecl);
+ fprintf(out, "%s if (ret >= 0) { break; }\n", indent.c_str());
+
+ fprintf(out, "%s {\n", indent.c_str());
+ fprintf(out, "%s std::lock_guard<std::mutex> lock(mLogdRetryMutex);\n", indent.c_str());
+ fprintf(out, "%s if ((get_elapsed_realtime_ns() - lastRetryTimestampNs) <= "
+ "kMinRetryIntervalNs) break;\n", indent.c_str());
+ fprintf(out, "%s lastRetryTimestampNs = get_elapsed_realtime_ns();\n",
+ indent.c_str());
+ fprintf(out, "%s }\n", indent.c_str());
+ fprintf(out, "%s std::this_thread::sleep_for(std::chrono::milliseconds(10));\n",
+ indent.c_str());
+ fprintf(out, "%s}\n", indent.c_str());
+ fprintf(out, "%sif (ret < 0) {\n", indent.c_str());
+ fprintf(out, "%s note_log_drop(ret, code);\n", indent.c_str());
+ fprintf(out, "%s}\n", indent.c_str());
+ fprintf(out, "%sreturn ret;\n", indent.c_str());
+}
+
+void write_native_cpp_includes_q(FILE* out) {
+ fprintf(out, "#include <mutex>\n");
+ fprintf(out, "#include <chrono>\n");
+ fprintf(out, "#include <thread>\n");
+ fprintf(out, "#ifdef __ANDROID__\n");
+ fprintf(out, "#include <cutils/properties.h>\n");
+ fprintf(out, "#endif\n");
+ fprintf(out, "#include <stats_event_list.h>\n");
+ fprintf(out, "#include <log/log.h>\n");
+ fprintf(out, "#include <time.h>\n");
+}
+
+void write_native_get_timestamp_ns_q(FILE* out) {
+ fprintf(out, "\n");
+ fprintf(out, "static int64_t get_elapsed_realtime_ns() {\n");
+ fprintf(out, " struct timespec t;\n");
+ fprintf(out, " t.tv_sec = t.tv_nsec = 0;\n");
+ fprintf(out, " clock_gettime(CLOCK_BOOTTIME, &t);\n");
+ fprintf(out, " return (int64_t)t.tv_sec * 1000000000LL + t.tv_nsec;\n");
+ fprintf(out, "}\n");
+}
+
+void write_native_stats_log_cpp_globals_q(FILE* out) {
+ fprintf(out, "// the single event tag id for all stats logs\n");
+ fprintf(out, "const static int kStatsEventTag = 1937006964;\n");
+ fprintf(out, "#ifdef __ANDROID__\n");
+ fprintf(out,
+ "const static bool kStatsdEnabled = property_get_bool(\"ro.statsd.enable\", true);\n");
+ fprintf(out, "#else\n");
+ fprintf(out, "const static bool kStatsdEnabled = false;\n");
+ fprintf(out, "#endif\n");
+
+ fprintf(out, "int64_t lastRetryTimestampNs = -1;\n");
+ fprintf(out, "const int64_t kMinRetryIntervalNs = NS_PER_SEC * 60 * 20; // 20 minutes\n");
+ fprintf(out, "static std::mutex mLogdRetryMutex;\n");
+}
+
+void write_native_try_stats_write_methods_q(FILE* out, const Atoms& atoms,
+ const AtomDecl& attributionDecl, const string& moduleName) {
+ fprintf(out, "\n");
+ for (auto signature_to_modules_it = atoms.signatures_to_modules.begin();
+ signature_to_modules_it != atoms.signatures_to_modules.end(); signature_to_modules_it++) {
+ if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) {
+ continue;
+ }
+ vector<java_type_t> signature = signature_to_modules_it->first;
+
+ write_native_method_signature(out, "static int try_stats_write", signature,
+ attributionDecl, " {");
+
+ int argIndex = 1;
+ fprintf(out, " if (kStatsdEnabled) {\n");
+ fprintf(out, " stats_event_list event(kStatsEventTag);\n");
+ fprintf(out, " event << get_elapsed_realtime_ns();\n\n");
+ fprintf(out, " event << code;\n\n");
+ for (vector<java_type_t>::const_iterator arg = signature.begin();
+ arg != signature.end(); arg++) {
+ if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
+ for (const auto &chainField : attributionDecl.fields) {
+ if (chainField.javaType == JAVA_TYPE_STRING) {
+ fprintf(out, " if (%s_length != %s.size()) {\n",
+ attributionDecl.fields.front().name.c_str(), chainField.name.c_str());
+ fprintf(out, " return -EINVAL;\n");
+ fprintf(out, " }\n");
+ }
+ }
+ fprintf(out, "\n event.begin();\n");
+ fprintf(out, " for (size_t i = 0; i < %s_length; ++i) {\n",
+ attributionDecl.fields.front().name.c_str());
+ fprintf(out, " event.begin();\n");
+ for (const auto &chainField : attributionDecl.fields) {
+ if (chainField.javaType == JAVA_TYPE_STRING) {
+ fprintf(out, " if (%s[i] != NULL) {\n", chainField.name.c_str());
+ fprintf(out, " event << %s[i];\n", chainField.name.c_str());
+ fprintf(out, " } else {\n");
+ fprintf(out, " event << \"\";\n");
+ fprintf(out, " }\n");
+ } else {
+ fprintf(out, " event << %s[i];\n", chainField.name.c_str());
+ }
+ }
+ fprintf(out, " event.end();\n");
+ fprintf(out, " }\n");
+ fprintf(out, " event.end();\n\n");
+ } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) {
+ fprintf(out, " event.begin();\n\n");
+ fprintf(out, " for (const auto& it : arg%d_1) {\n", argIndex);
+ fprintf(out, " event.begin();\n");
+ fprintf(out, " event << it.first;\n");
+ fprintf(out, " event << it.second;\n");
+ fprintf(out, " event.end();\n");
+ fprintf(out, " }\n");
+
+ fprintf(out, " for (const auto& it : arg%d_2) {\n", argIndex);
+ fprintf(out, " event.begin();\n");
+ fprintf(out, " event << it.first;\n");
+ fprintf(out, " event << it.second;\n");
+ fprintf(out, " event.end();\n");
+ fprintf(out, " }\n");
+
+ fprintf(out, " for (const auto& it : arg%d_3) {\n", argIndex);
+ fprintf(out, " event.begin();\n");
+ fprintf(out, " event << it.first;\n");
+ fprintf(out, " event << it.second;\n");
+ fprintf(out, " event.end();\n");
+ fprintf(out, " }\n");
+
+ fprintf(out, " for (const auto& it : arg%d_4) {\n", argIndex);
+ fprintf(out, " event.begin();\n");
+ fprintf(out, " event << it.first;\n");
+ fprintf(out, " event << it.second;\n");
+ fprintf(out, " event.end();\n");
+ fprintf(out, " }\n");
+
+ fprintf(out, " event.end();\n\n");
+ } else if (*arg == JAVA_TYPE_BYTE_ARRAY) {
+ fprintf(out,
+ " event.AppendCharArray(arg%d.arg, "
+ "arg%d.arg_length);\n",
+ argIndex, argIndex);
+ } else {
+ if (*arg == JAVA_TYPE_STRING) {
+ fprintf(out, " if (arg%d == NULL) {\n", argIndex);
+ fprintf(out, " arg%d = \"\";\n", argIndex);
+ fprintf(out, " }\n");
+ }
+ fprintf(out, " event << arg%d;\n", argIndex);
+ }
+ argIndex++;
+ }
+
+ fprintf(out, " return event.write(LOG_ID_STATS);\n");
+ fprintf(out, " } else {\n");
+ fprintf(out, " return 1;\n");
+ fprintf(out, " }\n");
+ fprintf(out, "}\n");
+ fprintf(out, "\n");
+ }
+
+}
+
+void write_native_stats_write_methods_q(FILE* out, const string& methodName, const Atoms& atoms,
+ const AtomDecl& attributionDecl, const string& moduleName, const string& tryMethodName) {
+ for (auto signature_to_modules_it = atoms.signatures_to_modules.begin();
+ signature_to_modules_it != atoms.signatures_to_modules.end();
+ signature_to_modules_it++) {
+ if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) {
+ continue;
+ }
+ vector<java_type_t> signature = signature_to_modules_it->first;
+
+ write_native_method_signature(out, methodName, signature, attributionDecl, " {");
+
+ write_native_stats_write_body_q(out, signature, attributionDecl, " ", tryMethodName);
+ fprintf(out, "}\n\n");
+ }
+}
+
+void write_native_stats_write_non_chained_methods_q(FILE* out, const string& methodName,
+ const Atoms& atoms, const AtomDecl& attributionDecl, const string& moduleName,
+ const string& tryMethodName) {
+ for (auto signature_it = atoms.non_chained_signatures_to_modules.begin();
+ signature_it != atoms.non_chained_signatures_to_modules.end(); signature_it++) {
+ if (!signature_needed_for_module(signature_it->second, moduleName)) {
+ continue;
+ }
+ vector<java_type_t> signature = signature_it->first;
+
+ write_native_method_signature(out, methodName, signature, attributionDecl, " {");
+
+ write_native_stats_write_body_q(out, signature, attributionDecl, " ", tryMethodName);
+ fprintf(out, "}\n\n");
+ }
+}
+
+void write_native_try_stats_write_non_chained_methods_q(FILE* out, const Atoms& atoms,
+ const AtomDecl& attributionDecl, const string& moduleName) {
+ for (auto signature_it = atoms.non_chained_signatures_to_modules.begin();
+ signature_it != atoms.non_chained_signatures_to_modules.end(); signature_it++) {
+ if (!signature_needed_for_module(signature_it->second, moduleName)) {
+ continue;
+ }
+ vector<java_type_t> signature = signature_it->first;
+
+ write_native_method_signature(out, "static int try_stats_write_non_chained", signature,
+ attributionDecl, " {");
+
+ int argIndex = 1;
+ fprintf(out, " if (kStatsdEnabled) {\n");
+ fprintf(out, " stats_event_list event(kStatsEventTag);\n");
+ fprintf(out, " event << get_elapsed_realtime_ns();\n\n");
+ fprintf(out, " event << code;\n\n");
+ for (vector<java_type_t>::const_iterator arg = signature.begin();
+ arg != signature.end(); arg++) {
+ if (argIndex == 1) {
+ fprintf(out, " event.begin();\n\n");
+ fprintf(out, " event.begin();\n");
+ }
+ if (*arg == JAVA_TYPE_STRING) {
+ fprintf(out, " if (arg%d == NULL) {\n", argIndex);
+ fprintf(out, " arg%d = \"\";\n", argIndex);
+ fprintf(out, " }\n");
+ }
+ if (*arg == JAVA_TYPE_BYTE_ARRAY) {
+ fprintf(out,
+ " event.AppendCharArray(arg%d.arg, "
+ "arg%d.arg_length);\n",
+ argIndex, argIndex);
+ } else {
+ fprintf(out, " event << arg%d;\n", argIndex);
+ }
+ if (argIndex == 2) {
+ fprintf(out, " event.end();\n\n");
+ fprintf(out, " event.end();\n\n");
+ }
+ argIndex++;
+ }
+
+ fprintf(out, " return event.write(LOG_ID_STATS);\n");
+ fprintf(out, " } else {\n");
+ fprintf(out, " return 1;\n");
+ fprintf(out, " }\n");
+ fprintf(out, "}\n");
+ fprintf(out, "\n");
+ }
+}
+
+} // namespace stats_log_api_gen
+} // namespace android
diff --git a/tools/stats_log_api_gen/native_writer_q.h b/tools/stats_log_api_gen/native_writer_q.h
new file mode 100644
index 0000000..a2ab1ae
--- /dev/null
+++ b/tools/stats_log_api_gen/native_writer_q.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2019, 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.
+ */
+
+#pragma once
+
+#include "Collation.h"
+
+#include <stdio.h>
+#include <string.h>
+
+namespace android {
+namespace stats_log_api_gen {
+
+using namespace std;
+
+void write_native_cpp_includes_q(FILE* out);
+
+void write_native_stats_log_cpp_globals_q(FILE* out);
+
+void write_native_try_stats_write_methods_q(FILE* out, const Atoms& atoms,
+ const AtomDecl& attributionDecl, const string& moduleName);
+
+void write_native_stats_write_methods_q(FILE* out, const string& methodName, const Atoms& atoms,
+ const AtomDecl& attributionDecl, const string& moduleName, const string& tryMethodName);
+
+void write_native_try_stats_write_non_chained_methods_q(FILE* out, const Atoms& atoms,
+ const AtomDecl& attributionDecl, const string& moduleName);
+
+void write_native_stats_write_non_chained_methods_q(FILE* out, const string& methodName,
+ const Atoms& atoms, const AtomDecl& attributionDecl, const string& moduleName,
+ const string& tryMethodName);
+
+void write_native_get_timestamp_ns_q(FILE* out);
+
+} // namespace stats_log_api_gen
+} // namespace android
diff --git a/tools/stats_log_api_gen/test.proto b/tools/stats_log_api_gen/test.proto
index c3e70382..c9a4763 100644
--- a/tools/stats_log_api_gen/test.proto
+++ b/tools/stats_log_api_gen/test.proto
@@ -229,8 +229,8 @@
message ModuleAtoms {
oneof event {
- ModuleOneAtom module_one_atom = 1 [(android.os.statsd.log_from_module) = "module1"];
- ModuleTwoAtom module_two_atom = 2 [(android.os.statsd.log_from_module) = "module2"];
+ ModuleOneAtom module_one_atom = 1 [(android.os.statsd.module) = "module1"];
+ ModuleTwoAtom module_two_atom = 2 [(android.os.statsd.module) = "module2"];
NoModuleAtom no_module_atom = 3;
}
-}
\ No newline at end of file
+}
diff --git a/tools/stats_log_api_gen/utils.cpp b/tools/stats_log_api_gen/utils.cpp
index d6cfe95..c65d190 100644
--- a/tools/stats_log_api_gen/utils.cpp
+++ b/tools/stats_log_api_gen/utils.cpp
@@ -204,6 +204,65 @@
fprintf(out, "\n");
}
+void write_native_method_signature(FILE* out, const string& methodName,
+ const vector<java_type_t>& signature, const AtomDecl& attributionDecl,
+ const string& closer) {
+ fprintf(out, "%s(int32_t code", methodName.c_str());
+ int argIndex = 1;
+ for (vector<java_type_t>::const_iterator arg = signature.begin();
+ arg != signature.end(); arg++) {
+ if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
+ for (auto chainField : attributionDecl.fields) {
+ if (chainField.javaType == JAVA_TYPE_STRING) {
+ fprintf(out, ", const std::vector<%s>& %s",
+ cpp_type_name(chainField.javaType),
+ chainField.name.c_str());
+ } else {
+ fprintf(out, ", const %s* %s, size_t %s_length",
+ cpp_type_name(chainField.javaType),
+ chainField.name.c_str(), chainField.name.c_str());
+ }
+ }
+ } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) {
+ fprintf(out, ", const std::map<int, int32_t>& arg%d_1, "
+ "const std::map<int, int64_t>& arg%d_2, "
+ "const std::map<int, char const*>& arg%d_3, "
+ "const std::map<int, float>& arg%d_4",
+ argIndex, argIndex, argIndex, argIndex);
+ } else {
+ fprintf(out, ", %s arg%d", cpp_type_name(*arg), argIndex);
+ }
+ argIndex++;
+ }
+ fprintf(out, ")%s\n", closer.c_str());
+}
+
+void write_native_method_call(FILE* out, const string& methodName,
+ const vector<java_type_t>& signature, const AtomDecl& attributionDecl, int argIndex) {
+ fprintf(out, "%s(code", methodName.c_str());
+ for (vector<java_type_t>::const_iterator arg = signature.begin();
+ arg != signature.end(); arg++) {
+ if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
+ for (auto chainField : attributionDecl.fields) {
+ if (chainField.javaType == JAVA_TYPE_STRING) {
+ fprintf(out, ", %s",
+ chainField.name.c_str());
+ } else {
+ fprintf(out, ", %s, %s_length",
+ chainField.name.c_str(), chainField.name.c_str());
+ }
+ }
+ } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) {
+ fprintf(out, ", arg%d_1, arg%d_2, arg%d_3, arg%d_4", argIndex,
+ argIndex, argIndex, argIndex);
+ } else {
+ fprintf(out, ", arg%d", argIndex);
+ }
+ argIndex++;
+ }
+ fprintf(out, ");\n");
+}
+
// Java
void write_java_atom_codes(FILE* out, const Atoms& atoms, const string& moduleName) {
fprintf(out, " // Constants for atom codes.\n");
diff --git a/tools/stats_log_api_gen/utils.h b/tools/stats_log_api_gen/utils.h
index a89387f..50737a6 100644
--- a/tools/stats_log_api_gen/utils.h
+++ b/tools/stats_log_api_gen/utils.h
@@ -56,8 +56,14 @@
void write_closing_namespace(FILE* out, const string& cppNamespaces);
void write_native_atom_constants(FILE* out, const Atoms& atoms, const AtomDecl& attributionDecl,
- const string& moduleName
-);
+ const string& moduleName);
+
+void write_native_method_signature(FILE* out, const string& methodName,
+ const vector<java_type_t>& signature, const AtomDecl& attributionDecl,
+ const string& closer);
+
+void write_native_method_call(FILE* out, const string& methodName,
+ const vector<java_type_t>& signature, const AtomDecl& attributionDecl, int argIndex = 1);
// Common Java helpers.
void write_java_atom_codes(FILE* out, const Atoms& atoms, const string& moduleName);
@@ -69,14 +75,12 @@
int write_java_non_chained_methods(FILE* out, const map<vector<java_type_t>,
set<string>>& signatures_to_modules,
- const string& moduleName
-);
+ const string& moduleName);
int write_java_work_source_methods(
FILE* out,
const map<vector<java_type_t>, set<string>>& signatures_to_modules,
- const string& moduleName
-);
+ const string& moduleName);
} // namespace stats_log_api_gen
} // namespace android
diff --git a/wifi/Android.bp b/wifi/Android.bp
index fb1f866..8155922 100644
--- a/wifi/Android.bp
+++ b/wifi/Android.bp
@@ -42,11 +42,21 @@
srcs: ["java/android/net/wifi/WifiAnnotations.java"],
}
+// list of tests that are allowed to access @hide APIs from framework-wifi
+test_access_hidden_api_whitelist = [
+ "//frameworks/base/wifi/tests",
+ "//frameworks/opt/net/wifi/tests/wifitests:__subpackages__",
+
+ "//frameworks/opt/net/wifi/libs/WifiTrackerLib/tests",
+]
+
java_library {
name: "framework-wifi",
- sdk_version: "core_platform", // TODO(b/140299412) should be core_current
+ // TODO(b/140299412) should be core_current once we build against framework-system-stubs
+ sdk_version: "core_platform",
libs: [
- "framework-minus-apex", // TODO(b/140299412) should be framework-system-stubs
+ // TODO(b/140299412) should be framework-system-stubs once we fix all @hide dependencies
+ "framework-minus-apex",
],
srcs: [
":framework-wifi-updatable-sources",
@@ -54,7 +64,11 @@
installable: true,
optimize: {
enabled: false
- }
+ },
+ visibility: [
+ "//frameworks/base", // TODO(b/140299412) remove once all dependencies are fixed
+ "//frameworks/opt/net/wifi/service:__subpackages__",
+ ] + test_access_hidden_api_whitelist,
}
droidstubs {
@@ -84,3 +98,16 @@
installable: false,
}
+// defaults for tests that need to build against framework-wifi's @hide APIs
+java_defaults {
+ name: "framework-wifi-test-defaults",
+ sdk_version: "core_platform", // tests can use @CorePlatformApi's
+ libs: [
+ "framework-wifi",
+ "framework-minus-apex",
+
+ // if sdk_version="" this gets automatically included, but here we need to add manually.
+ "framework-res",
+ ],
+ visibility: test_access_hidden_api_whitelist,
+}
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index e3a945d..2a165d3 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -2446,10 +2446,14 @@
return key;
}
- /** @hide */
- @UnsupportedAppUsage
+ /**
+ * Get the IpConfiguration object associated with this WifiConfiguration.
+ * @hide
+ */
+ @NonNull
+ @SystemApi
public IpConfiguration getIpConfiguration() {
- return mIpConfiguration;
+ return new IpConfiguration(mIpConfiguration);
}
/**