Loading core/java/android/os/WorkSource.java +1 −1 Original line number Diff line number Diff line Loading @@ -128,7 +128,7 @@ public class WorkSource implements Parcelable { mNames = in.createStringArray(); int numChains = in.readInt(); if (numChains > 0) { if (numChains >= 0) { mChains = new ArrayList<>(numChains); in.readParcelableList(mChains, WorkChain.class.getClassLoader(), android.os.WorkSource.WorkChain.class); } else { Loading core/java/android/service/voice/HotwordAudioStream.java +141 −19 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import android.os.ParcelFileDescriptor; import android.os.Parcelable; import android.os.PersistableBundle; import java.util.Arrays; import java.util.Objects; /** Loading Loading @@ -59,8 +60,17 @@ public final class HotwordAudioStream implements Parcelable { private final AudioFormat mAudioFormat; /** * This stream starts with the audio bytes used for hotword detection, but continues streaming * the audio until the stream is shutdown by the {@link HotwordDetectionService}. * This stream typically starts with the audio bytes used for hotword detection, but continues * streaming the audio (e.g., with the query) until the stream is shutdown by the * {@link HotwordDetectionService}. The data format is expected to match * {@link #getAudioFormat()}. * * <p> * Alternatively, the {@link HotwordDetectionService} may use {@link #getInitialAudio()} * to pass the start of the audio instead of streaming it here. This may prevent added latency * caused by the streaming buffer (see {@link #KEY_AUDIO_STREAM_COPY_BUFFER_LENGTH_BYTES}) not * being large enough to handle this initial chunk of audio. * </p> */ @NonNull @UnsupportedAppUsage Loading Loading @@ -138,6 +148,32 @@ public final class HotwordAudioStream implements Parcelable { } } /** * The start of the audio used for hotword detection. The data format is expected to match * {@link #getAudioFormat()}. * * <p> * The {@link HotwordDetectionService} may use this instead of using * {@link #getAudioStreamParcelFileDescriptor()} to stream these initial bytes of audio. This * may prevent added latency caused by the streaming buffer (see * {@link #KEY_AUDIO_STREAM_COPY_BUFFER_LENGTH_BYTES}) not being large enough to handle this * initial chunk of audio. * </p> */ @NonNull @UnsupportedAppUsage private final byte[] mInitialAudio; private static final byte[] DEFAULT_INITIAL_EMPTY_AUDIO = {}; private static byte[] defaultInitialAudio() { return DEFAULT_INITIAL_EMPTY_AUDIO; } private String initialAudioToString() { return "length=" + mInitialAudio.length; } /** * Provides an instance of {@link Builder} with state corresponding to this instance. * @hide Loading @@ -145,7 +181,8 @@ public final class HotwordAudioStream implements Parcelable { public Builder buildUpon() { return new Builder(mAudioFormat, mAudioStreamParcelFileDescriptor) .setTimestamp(mTimestamp) .setMetadata(mMetadata); .setMetadata(mMetadata) .setInitialAudio(mInitialAudio); } /* package-private */ Loading @@ -153,7 +190,8 @@ public final class HotwordAudioStream implements Parcelable { @NonNull AudioFormat audioFormat, @NonNull ParcelFileDescriptor audioStreamParcelFileDescriptor, @Nullable AudioTimestamp timestamp, @NonNull PersistableBundle metadata) { @NonNull PersistableBundle metadata, @NonNull byte[] initialAudio) { this.mAudioFormat = audioFormat; com.android.internal.util.AnnotationValidations.validate( NonNull.class, null, mAudioFormat); Loading @@ -164,6 +202,9 @@ public final class HotwordAudioStream implements Parcelable { this.mMetadata = metadata; com.android.internal.util.AnnotationValidations.validate( NonNull.class, null, mMetadata); this.mInitialAudio = initialAudio; com.android.internal.util.AnnotationValidations.validate( NonNull.class, null, mInitialAudio); // onConstructed(); // You can define this method to get a callback } Loading @@ -178,8 +219,17 @@ public final class HotwordAudioStream implements Parcelable { } /** * This stream starts with the audio bytes used for hotword detection, but continues streaming * the audio until the stream is shutdown by the {@link HotwordDetectionService}. * This stream typically starts with the audio bytes used for hotword detection, but continues * streaming the audio (e.g., with the query) until the stream is shutdown by the * {@link HotwordDetectionService}. The data format is expected to match * {@link #getAudioFormat()}. * * <p> * Alternatively, the {@link HotwordDetectionService} may use {@link #getInitialAudio()} * to pass the start of the audio instead of streaming it here. This may prevent added latency * caused by the streaming buffer (see {@link #KEY_AUDIO_STREAM_COPY_BUFFER_LENGTH_BYTES}) not * being large enough to handle this initial chunk of audio. * </p> */ @UnsupportedAppUsage @NonNull Loading Loading @@ -220,6 +270,24 @@ public final class HotwordAudioStream implements Parcelable { return mMetadata; } /** * The start of the audio used for hotword detection. The data format is expected to match * {@link #getAudioFormat()}. * * <p> * The {@link HotwordDetectionService} may use this instead of using * {@link #getAudioStreamParcelFileDescriptor()} to stream these initial bytes of audio. This * may prevent added latency caused by the streaming buffer (see * {@link #KEY_AUDIO_STREAM_COPY_BUFFER_LENGTH_BYTES}) not being large enough to handle this * initial chunk of audio. * </p> */ @UnsupportedAppUsage @NonNull public byte[] getInitialAudio() { return mInitialAudio; } @Override public String toString() { // You can override field toString logic by defining methods like: Loading @@ -229,7 +297,8 @@ public final class HotwordAudioStream implements Parcelable { + "audioFormat = " + mAudioFormat + ", " + "audioStreamParcelFileDescriptor = " + mAudioStreamParcelFileDescriptor + ", " + "timestamp = " + timestampToString() + ", " + "metadata = " + mMetadata + " }"; + "metadata = " + mMetadata + ", " + "initialAudio = " + initialAudioToString() + " }"; } @Override Loading @@ -247,7 +316,8 @@ public final class HotwordAudioStream implements Parcelable { && Objects.equals(mAudioStreamParcelFileDescriptor, that.mAudioStreamParcelFileDescriptor) && Objects.equals(mTimestamp, that.mTimestamp) && Objects.equals(mMetadata, that.mMetadata); && Objects.equals(mMetadata, that.mMetadata) && Arrays.equals(mInitialAudio, that.mInitialAudio); } @Override Loading @@ -260,6 +330,7 @@ public final class HotwordAudioStream implements Parcelable { _hash = 31 * _hash + Objects.hashCode(mAudioStreamParcelFileDescriptor); _hash = 31 * _hash + Objects.hashCode(mTimestamp); _hash = 31 * _hash + Objects.hashCode(mMetadata); _hash = 31 * _hash + Arrays.hashCode(mInitialAudio); return _hash; } Loading @@ -275,6 +346,7 @@ public final class HotwordAudioStream implements Parcelable { dest.writeTypedObject(mAudioStreamParcelFileDescriptor, flags); parcelTimestamp(dest, flags); dest.writeTypedObject(mMetadata, flags); dest.writeByteArray(mInitialAudio); } @Override Loading @@ -296,6 +368,7 @@ public final class HotwordAudioStream implements Parcelable { AudioTimestamp timestamp = unparcelTimestamp(in); PersistableBundle metadata = (PersistableBundle) in.readTypedObject( PersistableBundle.CREATOR); byte[] initialAudio = in.createByteArray(); this.mAudioFormat = audioFormat; com.android.internal.util.AnnotationValidations.validate( Loading @@ -307,6 +380,9 @@ public final class HotwordAudioStream implements Parcelable { this.mMetadata = metadata; com.android.internal.util.AnnotationValidations.validate( NonNull.class, null, mMetadata); this.mInitialAudio = initialAudio; com.android.internal.util.AnnotationValidations.validate( NonNull.class, null, mInitialAudio); // onConstructed(); // You can define this method to get a callback } Loading Loading @@ -339,17 +415,29 @@ public final class HotwordAudioStream implements Parcelable { private AudioTimestamp mTimestamp; @NonNull private PersistableBundle mMetadata; @NonNull private byte[] mInitialAudio; private long mBuilderFieldsSet = 0L; /** * Creates a new Builder. * * @param audioFormat The {@link AudioFormat} of the audio stream. * @param audioStreamParcelFileDescriptor This stream starts with the audio bytes used for * hotword detection, but continues streaming * the audio until the stream is shutdown by the * {@link HotwordDetectionService}. * @param audioFormat * The {@link AudioFormat} of the audio stream. * @param audioStreamParcelFileDescriptor * This stream typically starts with the audio bytes used for hotword detection, but * continues streaming the audio (e.g., with the query) until the stream is shutdown by * the {@link HotwordDetectionService}. The data format is expected to match * {@link #getAudioFormat()}. * * <p> * Alternatively, the {@link HotwordDetectionService} may use {@link #getInitialAudio()} * to pass the start of the audio instead of streaming it here. This may prevent added * latency caused by the streaming buffer * (see {@link #KEY_AUDIO_STREAM_COPY_BUFFER_LENGTH_BYTES}) not being large enough to * handle this initial chunk of audio. * </p> */ @UnsupportedAppUsage public Builder( Loading @@ -376,9 +464,18 @@ public final class HotwordAudioStream implements Parcelable { } /** * This stream starts with the audio bytes used for hotword detection, but continues * streaming * the audio until the stream is shutdown by the {@link HotwordDetectionService}. * This stream typically starts with the audio bytes used for hotword detection, but * continues streaming the audio (e.g., with the query) until the stream is shutdown by the * {@link HotwordDetectionService}. The data format is expected to match * {@link #getAudioFormat()}. * * <p> * Alternatively, the {@link HotwordDetectionService} may use {@link #getInitialAudio()} * to pass the start of the audio instead of streaming it here. This may prevent added * latency caused by the streaming buffer * (see {@link #KEY_AUDIO_STREAM_COPY_BUFFER_LENGTH_BYTES}) not being large enough to handle * this initial chunk of audio. * </p> */ @UnsupportedAppUsage @NonNull Loading Loading @@ -428,12 +525,33 @@ public final class HotwordAudioStream implements Parcelable { return this; } /** * The start of the audio used for hotword detection. The data format is expected to match * {@link #getAudioFormat()}. * * <p> * The {@link HotwordDetectionService} may use this instead of using * {@link #getAudioStreamParcelFileDescriptor()} to stream these initial bytes of audio. * This may prevent added latency caused by the streaming buffer (see * {@link #KEY_AUDIO_STREAM_COPY_BUFFER_LENGTH_BYTES}) not being large enough to handle this * initial chunk of audio. * </p> */ @UnsupportedAppUsage @NonNull public Builder setInitialAudio(@NonNull byte[] value) { checkNotUsed(); mBuilderFieldsSet |= 0x10; mInitialAudio = value; return this; } /** Builds the instance. This builder should not be touched after calling this! */ @UnsupportedAppUsage @NonNull public HotwordAudioStream build() { checkNotUsed(); mBuilderFieldsSet |= 0x10; // Mark builder used mBuilderFieldsSet |= 0x20; // Mark builder used if ((mBuilderFieldsSet & 0x4) == 0) { mTimestamp = defaultTimestamp(); Loading @@ -441,16 +559,20 @@ public final class HotwordAudioStream implements Parcelable { if ((mBuilderFieldsSet & 0x8) == 0) { mMetadata = defaultMetadata(); } if ((mBuilderFieldsSet & 0x10) == 0) { mInitialAudio = defaultInitialAudio(); } HotwordAudioStream o = new HotwordAudioStream( mAudioFormat, mAudioStreamParcelFileDescriptor, mTimestamp, mMetadata); mMetadata, mInitialAudio); return o; } private void checkNotUsed() { if ((mBuilderFieldsSet & 0x10) != 0) { if ((mBuilderFieldsSet & 0x20) != 0) { throw new IllegalStateException( "This Builder should not be reused. Use a new Builder instance instead"); } Loading core/java/com/android/internal/util/LatencyTracker.java +109 −10 Original line number Diff line number Diff line Loading @@ -37,12 +37,17 @@ import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPOR import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_UDFPS_ILLUMINATE; import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_USER_SWITCH; import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__UNKNOWN_ACTION; import static com.android.internal.util.LatencyTracker.ActionProperties.ENABLE_SUFFIX; import static com.android.internal.util.LatencyTracker.ActionProperties.LEGACY_TRACE_THRESHOLD_SUFFIX; import static com.android.internal.util.LatencyTracker.ActionProperties.SAMPLE_INTERVAL_SUFFIX; import static com.android.internal.util.LatencyTracker.ActionProperties.TRACE_THRESHOLD_SUFFIX; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; import android.os.Build; import android.os.ConditionVariable; import android.os.SystemClock; import android.os.Trace; import android.provider.DeviceConfig; Loading @@ -58,6 +63,7 @@ import com.android.internal.os.BackgroundThread; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Locale; import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.TimeUnit; Loading Loading @@ -261,11 +267,11 @@ public class LatencyTracker { @GuardedBy("mLock") private final SparseArray<Session> mSessions = new SparseArray<>(); @GuardedBy("mLock") private final int[] mTraceThresholdPerAction = new int[ACTIONS_ALL.length]; @GuardedBy("mLock") private int mSamplingInterval; private final SparseArray<ActionProperties> mActionPropertiesMap = new SparseArray<>(); @GuardedBy("mLock") private boolean mEnabled; @VisibleForTesting public final ConditionVariable mDeviceConfigPropertiesUpdated = new ConditionVariable(); public static LatencyTracker getInstance(Context context) { if (sLatencyTracker == null) { Loading @@ -278,9 +284,9 @@ public class LatencyTracker { return sLatencyTracker; } private LatencyTracker() { @VisibleForTesting public LatencyTracker() { mEnabled = DEFAULT_ENABLED; mSamplingInterval = DEFAULT_SAMPLING_INTERVAL; // Post initialization to the background in case we're running on the main thread. BackgroundThread.getHandler().post(() -> this.updateProperties( Loading @@ -291,14 +297,24 @@ public class LatencyTracker { private void updateProperties(DeviceConfig.Properties properties) { synchronized (mLock) { mSamplingInterval = properties.getInt(SETTINGS_SAMPLING_INTERVAL_KEY, int samplingInterval = properties.getInt(SETTINGS_SAMPLING_INTERVAL_KEY, DEFAULT_SAMPLING_INTERVAL); mEnabled = properties.getBoolean(SETTINGS_ENABLED_KEY, DEFAULT_ENABLED); for (int action : ACTIONS_ALL) { mTraceThresholdPerAction[action] = properties.getInt(getNameOfAction(STATSD_ACTION[action]), -1); String actionName = getNameOfAction(STATSD_ACTION[action]).toLowerCase(Locale.ROOT); int legacyActionTraceThreshold = properties.getInt( actionName + LEGACY_TRACE_THRESHOLD_SUFFIX, -1); mActionPropertiesMap.put(action, new ActionProperties(action, properties.getBoolean(actionName + ENABLE_SUFFIX, mEnabled), properties.getInt(actionName + SAMPLE_INTERVAL_SUFFIX, samplingInterval), properties.getInt(actionName + TRACE_THRESHOLD_SUFFIX, legacyActionTraceThreshold))); } if (DEBUG) { Log.d(TAG, "updated action properties: " + mActionPropertiesMap); } } mDeviceConfigPropertiesUpdated.open(); } /** Loading Loading @@ -369,16 +385,38 @@ public class LatencyTracker { return "com.android.telemetry.latency-tracker-" + getNameOfAction(STATSD_ACTION[action]); } /** * @deprecated Use {@link #isEnabled(Context, int)} */ @Deprecated public static boolean isEnabled(Context ctx) { return getInstance(ctx).isEnabled(); } /** * @deprecated Used {@link #isEnabled(int)} */ @Deprecated public boolean isEnabled() { synchronized (mLock) { return mEnabled; } } public static boolean isEnabled(Context ctx, int action) { return getInstance(ctx).isEnabled(action); } public boolean isEnabled(int action) { synchronized (mLock) { ActionProperties actionProperties = mActionPropertiesMap.get(action); if (actionProperties != null) { return actionProperties.isEnabled(); } return false; } } /** * Notifies that an action is starting. <s>This needs to be called from the main thread.</s> * Loading Loading @@ -468,8 +506,14 @@ public class LatencyTracker { boolean shouldSample; int traceThreshold; synchronized (mLock) { shouldSample = ThreadLocalRandom.current().nextInt() % mSamplingInterval == 0; traceThreshold = mTraceThresholdPerAction[action]; ActionProperties actionProperties = mActionPropertiesMap.get(action); if (actionProperties == null) { return; } int nextRandNum = ThreadLocalRandom.current().nextInt( actionProperties.getSamplingInterval()); shouldSample = nextRandNum == 0; traceThreshold = actionProperties.getTraceThreshold(); } if (traceThreshold > 0 && duration >= traceThreshold) { Loading Loading @@ -549,4 +593,59 @@ public class LatencyTracker { return (int) (mEndRtc - mStartRtc); } } @VisibleForTesting static class ActionProperties { static final String ENABLE_SUFFIX = "_enable"; static final String SAMPLE_INTERVAL_SUFFIX = "_sample_interval"; // TODO: migrate all usages of the legacy trace theshold property static final String LEGACY_TRACE_THRESHOLD_SUFFIX = ""; static final String TRACE_THRESHOLD_SUFFIX = "_trace_threshold"; @Action private final int mAction; private final boolean mEnabled; private final int mSamplingInterval; private final int mTraceThreshold; ActionProperties( @Action int action, boolean enabled, int samplingInterval, int traceThreshold) { this.mAction = action; com.android.internal.util.AnnotationValidations.validate( Action.class, null, mAction); this.mEnabled = enabled; this.mSamplingInterval = samplingInterval; this.mTraceThreshold = traceThreshold; } @Action int getAction() { return mAction; } boolean isEnabled() { return mEnabled; } int getSamplingInterval() { return mSamplingInterval; } int getTraceThreshold() { return mTraceThreshold; } @Override public String toString() { return "ActionProperties{" + " mAction=" + mAction + ", mEnabled=" + mEnabled + ", mSamplingInterval=" + mSamplingInterval + ", mTraceThreshold=" + mTraceThreshold + "}"; } } } core/res/res/values-b+sr+Latn-television/strings.xml +2 −2 Original line number Diff line number Diff line Loading @@ -17,6 +17,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="7002619958660406548">"Mikrofon je blokiran"</string> <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="2131954635322568179">"Kamera je blokirana"</string> <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="7002619958660406548">"Микрофон је блокиран"</string> <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="2131954635322568179">"Камера је блокирана"</string> </resources> core/res/res/values-b+sr+Latn/strings.xml +2058 −2058 File changed.File size exceeds preview limit. View original file View changed file Loading
core/java/android/os/WorkSource.java +1 −1 Original line number Diff line number Diff line Loading @@ -128,7 +128,7 @@ public class WorkSource implements Parcelable { mNames = in.createStringArray(); int numChains = in.readInt(); if (numChains > 0) { if (numChains >= 0) { mChains = new ArrayList<>(numChains); in.readParcelableList(mChains, WorkChain.class.getClassLoader(), android.os.WorkSource.WorkChain.class); } else { Loading
core/java/android/service/voice/HotwordAudioStream.java +141 −19 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import android.os.ParcelFileDescriptor; import android.os.Parcelable; import android.os.PersistableBundle; import java.util.Arrays; import java.util.Objects; /** Loading Loading @@ -59,8 +60,17 @@ public final class HotwordAudioStream implements Parcelable { private final AudioFormat mAudioFormat; /** * This stream starts with the audio bytes used for hotword detection, but continues streaming * the audio until the stream is shutdown by the {@link HotwordDetectionService}. * This stream typically starts with the audio bytes used for hotword detection, but continues * streaming the audio (e.g., with the query) until the stream is shutdown by the * {@link HotwordDetectionService}. The data format is expected to match * {@link #getAudioFormat()}. * * <p> * Alternatively, the {@link HotwordDetectionService} may use {@link #getInitialAudio()} * to pass the start of the audio instead of streaming it here. This may prevent added latency * caused by the streaming buffer (see {@link #KEY_AUDIO_STREAM_COPY_BUFFER_LENGTH_BYTES}) not * being large enough to handle this initial chunk of audio. * </p> */ @NonNull @UnsupportedAppUsage Loading Loading @@ -138,6 +148,32 @@ public final class HotwordAudioStream implements Parcelable { } } /** * The start of the audio used for hotword detection. The data format is expected to match * {@link #getAudioFormat()}. * * <p> * The {@link HotwordDetectionService} may use this instead of using * {@link #getAudioStreamParcelFileDescriptor()} to stream these initial bytes of audio. This * may prevent added latency caused by the streaming buffer (see * {@link #KEY_AUDIO_STREAM_COPY_BUFFER_LENGTH_BYTES}) not being large enough to handle this * initial chunk of audio. * </p> */ @NonNull @UnsupportedAppUsage private final byte[] mInitialAudio; private static final byte[] DEFAULT_INITIAL_EMPTY_AUDIO = {}; private static byte[] defaultInitialAudio() { return DEFAULT_INITIAL_EMPTY_AUDIO; } private String initialAudioToString() { return "length=" + mInitialAudio.length; } /** * Provides an instance of {@link Builder} with state corresponding to this instance. * @hide Loading @@ -145,7 +181,8 @@ public final class HotwordAudioStream implements Parcelable { public Builder buildUpon() { return new Builder(mAudioFormat, mAudioStreamParcelFileDescriptor) .setTimestamp(mTimestamp) .setMetadata(mMetadata); .setMetadata(mMetadata) .setInitialAudio(mInitialAudio); } /* package-private */ Loading @@ -153,7 +190,8 @@ public final class HotwordAudioStream implements Parcelable { @NonNull AudioFormat audioFormat, @NonNull ParcelFileDescriptor audioStreamParcelFileDescriptor, @Nullable AudioTimestamp timestamp, @NonNull PersistableBundle metadata) { @NonNull PersistableBundle metadata, @NonNull byte[] initialAudio) { this.mAudioFormat = audioFormat; com.android.internal.util.AnnotationValidations.validate( NonNull.class, null, mAudioFormat); Loading @@ -164,6 +202,9 @@ public final class HotwordAudioStream implements Parcelable { this.mMetadata = metadata; com.android.internal.util.AnnotationValidations.validate( NonNull.class, null, mMetadata); this.mInitialAudio = initialAudio; com.android.internal.util.AnnotationValidations.validate( NonNull.class, null, mInitialAudio); // onConstructed(); // You can define this method to get a callback } Loading @@ -178,8 +219,17 @@ public final class HotwordAudioStream implements Parcelable { } /** * This stream starts with the audio bytes used for hotword detection, but continues streaming * the audio until the stream is shutdown by the {@link HotwordDetectionService}. * This stream typically starts with the audio bytes used for hotword detection, but continues * streaming the audio (e.g., with the query) until the stream is shutdown by the * {@link HotwordDetectionService}. The data format is expected to match * {@link #getAudioFormat()}. * * <p> * Alternatively, the {@link HotwordDetectionService} may use {@link #getInitialAudio()} * to pass the start of the audio instead of streaming it here. This may prevent added latency * caused by the streaming buffer (see {@link #KEY_AUDIO_STREAM_COPY_BUFFER_LENGTH_BYTES}) not * being large enough to handle this initial chunk of audio. * </p> */ @UnsupportedAppUsage @NonNull Loading Loading @@ -220,6 +270,24 @@ public final class HotwordAudioStream implements Parcelable { return mMetadata; } /** * The start of the audio used for hotword detection. The data format is expected to match * {@link #getAudioFormat()}. * * <p> * The {@link HotwordDetectionService} may use this instead of using * {@link #getAudioStreamParcelFileDescriptor()} to stream these initial bytes of audio. This * may prevent added latency caused by the streaming buffer (see * {@link #KEY_AUDIO_STREAM_COPY_BUFFER_LENGTH_BYTES}) not being large enough to handle this * initial chunk of audio. * </p> */ @UnsupportedAppUsage @NonNull public byte[] getInitialAudio() { return mInitialAudio; } @Override public String toString() { // You can override field toString logic by defining methods like: Loading @@ -229,7 +297,8 @@ public final class HotwordAudioStream implements Parcelable { + "audioFormat = " + mAudioFormat + ", " + "audioStreamParcelFileDescriptor = " + mAudioStreamParcelFileDescriptor + ", " + "timestamp = " + timestampToString() + ", " + "metadata = " + mMetadata + " }"; + "metadata = " + mMetadata + ", " + "initialAudio = " + initialAudioToString() + " }"; } @Override Loading @@ -247,7 +316,8 @@ public final class HotwordAudioStream implements Parcelable { && Objects.equals(mAudioStreamParcelFileDescriptor, that.mAudioStreamParcelFileDescriptor) && Objects.equals(mTimestamp, that.mTimestamp) && Objects.equals(mMetadata, that.mMetadata); && Objects.equals(mMetadata, that.mMetadata) && Arrays.equals(mInitialAudio, that.mInitialAudio); } @Override Loading @@ -260,6 +330,7 @@ public final class HotwordAudioStream implements Parcelable { _hash = 31 * _hash + Objects.hashCode(mAudioStreamParcelFileDescriptor); _hash = 31 * _hash + Objects.hashCode(mTimestamp); _hash = 31 * _hash + Objects.hashCode(mMetadata); _hash = 31 * _hash + Arrays.hashCode(mInitialAudio); return _hash; } Loading @@ -275,6 +346,7 @@ public final class HotwordAudioStream implements Parcelable { dest.writeTypedObject(mAudioStreamParcelFileDescriptor, flags); parcelTimestamp(dest, flags); dest.writeTypedObject(mMetadata, flags); dest.writeByteArray(mInitialAudio); } @Override Loading @@ -296,6 +368,7 @@ public final class HotwordAudioStream implements Parcelable { AudioTimestamp timestamp = unparcelTimestamp(in); PersistableBundle metadata = (PersistableBundle) in.readTypedObject( PersistableBundle.CREATOR); byte[] initialAudio = in.createByteArray(); this.mAudioFormat = audioFormat; com.android.internal.util.AnnotationValidations.validate( Loading @@ -307,6 +380,9 @@ public final class HotwordAudioStream implements Parcelable { this.mMetadata = metadata; com.android.internal.util.AnnotationValidations.validate( NonNull.class, null, mMetadata); this.mInitialAudio = initialAudio; com.android.internal.util.AnnotationValidations.validate( NonNull.class, null, mInitialAudio); // onConstructed(); // You can define this method to get a callback } Loading Loading @@ -339,17 +415,29 @@ public final class HotwordAudioStream implements Parcelable { private AudioTimestamp mTimestamp; @NonNull private PersistableBundle mMetadata; @NonNull private byte[] mInitialAudio; private long mBuilderFieldsSet = 0L; /** * Creates a new Builder. * * @param audioFormat The {@link AudioFormat} of the audio stream. * @param audioStreamParcelFileDescriptor This stream starts with the audio bytes used for * hotword detection, but continues streaming * the audio until the stream is shutdown by the * {@link HotwordDetectionService}. * @param audioFormat * The {@link AudioFormat} of the audio stream. * @param audioStreamParcelFileDescriptor * This stream typically starts with the audio bytes used for hotword detection, but * continues streaming the audio (e.g., with the query) until the stream is shutdown by * the {@link HotwordDetectionService}. The data format is expected to match * {@link #getAudioFormat()}. * * <p> * Alternatively, the {@link HotwordDetectionService} may use {@link #getInitialAudio()} * to pass the start of the audio instead of streaming it here. This may prevent added * latency caused by the streaming buffer * (see {@link #KEY_AUDIO_STREAM_COPY_BUFFER_LENGTH_BYTES}) not being large enough to * handle this initial chunk of audio. * </p> */ @UnsupportedAppUsage public Builder( Loading @@ -376,9 +464,18 @@ public final class HotwordAudioStream implements Parcelable { } /** * This stream starts with the audio bytes used for hotword detection, but continues * streaming * the audio until the stream is shutdown by the {@link HotwordDetectionService}. * This stream typically starts with the audio bytes used for hotword detection, but * continues streaming the audio (e.g., with the query) until the stream is shutdown by the * {@link HotwordDetectionService}. The data format is expected to match * {@link #getAudioFormat()}. * * <p> * Alternatively, the {@link HotwordDetectionService} may use {@link #getInitialAudio()} * to pass the start of the audio instead of streaming it here. This may prevent added * latency caused by the streaming buffer * (see {@link #KEY_AUDIO_STREAM_COPY_BUFFER_LENGTH_BYTES}) not being large enough to handle * this initial chunk of audio. * </p> */ @UnsupportedAppUsage @NonNull Loading Loading @@ -428,12 +525,33 @@ public final class HotwordAudioStream implements Parcelable { return this; } /** * The start of the audio used for hotword detection. The data format is expected to match * {@link #getAudioFormat()}. * * <p> * The {@link HotwordDetectionService} may use this instead of using * {@link #getAudioStreamParcelFileDescriptor()} to stream these initial bytes of audio. * This may prevent added latency caused by the streaming buffer (see * {@link #KEY_AUDIO_STREAM_COPY_BUFFER_LENGTH_BYTES}) not being large enough to handle this * initial chunk of audio. * </p> */ @UnsupportedAppUsage @NonNull public Builder setInitialAudio(@NonNull byte[] value) { checkNotUsed(); mBuilderFieldsSet |= 0x10; mInitialAudio = value; return this; } /** Builds the instance. This builder should not be touched after calling this! */ @UnsupportedAppUsage @NonNull public HotwordAudioStream build() { checkNotUsed(); mBuilderFieldsSet |= 0x10; // Mark builder used mBuilderFieldsSet |= 0x20; // Mark builder used if ((mBuilderFieldsSet & 0x4) == 0) { mTimestamp = defaultTimestamp(); Loading @@ -441,16 +559,20 @@ public final class HotwordAudioStream implements Parcelable { if ((mBuilderFieldsSet & 0x8) == 0) { mMetadata = defaultMetadata(); } if ((mBuilderFieldsSet & 0x10) == 0) { mInitialAudio = defaultInitialAudio(); } HotwordAudioStream o = new HotwordAudioStream( mAudioFormat, mAudioStreamParcelFileDescriptor, mTimestamp, mMetadata); mMetadata, mInitialAudio); return o; } private void checkNotUsed() { if ((mBuilderFieldsSet & 0x10) != 0) { if ((mBuilderFieldsSet & 0x20) != 0) { throw new IllegalStateException( "This Builder should not be reused. Use a new Builder instance instead"); } Loading
core/java/com/android/internal/util/LatencyTracker.java +109 −10 Original line number Diff line number Diff line Loading @@ -37,12 +37,17 @@ import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPOR import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_UDFPS_ILLUMINATE; import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_USER_SWITCH; import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__UNKNOWN_ACTION; import static com.android.internal.util.LatencyTracker.ActionProperties.ENABLE_SUFFIX; import static com.android.internal.util.LatencyTracker.ActionProperties.LEGACY_TRACE_THRESHOLD_SUFFIX; import static com.android.internal.util.LatencyTracker.ActionProperties.SAMPLE_INTERVAL_SUFFIX; import static com.android.internal.util.LatencyTracker.ActionProperties.TRACE_THRESHOLD_SUFFIX; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; import android.os.Build; import android.os.ConditionVariable; import android.os.SystemClock; import android.os.Trace; import android.provider.DeviceConfig; Loading @@ -58,6 +63,7 @@ import com.android.internal.os.BackgroundThread; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Locale; import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.TimeUnit; Loading Loading @@ -261,11 +267,11 @@ public class LatencyTracker { @GuardedBy("mLock") private final SparseArray<Session> mSessions = new SparseArray<>(); @GuardedBy("mLock") private final int[] mTraceThresholdPerAction = new int[ACTIONS_ALL.length]; @GuardedBy("mLock") private int mSamplingInterval; private final SparseArray<ActionProperties> mActionPropertiesMap = new SparseArray<>(); @GuardedBy("mLock") private boolean mEnabled; @VisibleForTesting public final ConditionVariable mDeviceConfigPropertiesUpdated = new ConditionVariable(); public static LatencyTracker getInstance(Context context) { if (sLatencyTracker == null) { Loading @@ -278,9 +284,9 @@ public class LatencyTracker { return sLatencyTracker; } private LatencyTracker() { @VisibleForTesting public LatencyTracker() { mEnabled = DEFAULT_ENABLED; mSamplingInterval = DEFAULT_SAMPLING_INTERVAL; // Post initialization to the background in case we're running on the main thread. BackgroundThread.getHandler().post(() -> this.updateProperties( Loading @@ -291,14 +297,24 @@ public class LatencyTracker { private void updateProperties(DeviceConfig.Properties properties) { synchronized (mLock) { mSamplingInterval = properties.getInt(SETTINGS_SAMPLING_INTERVAL_KEY, int samplingInterval = properties.getInt(SETTINGS_SAMPLING_INTERVAL_KEY, DEFAULT_SAMPLING_INTERVAL); mEnabled = properties.getBoolean(SETTINGS_ENABLED_KEY, DEFAULT_ENABLED); for (int action : ACTIONS_ALL) { mTraceThresholdPerAction[action] = properties.getInt(getNameOfAction(STATSD_ACTION[action]), -1); String actionName = getNameOfAction(STATSD_ACTION[action]).toLowerCase(Locale.ROOT); int legacyActionTraceThreshold = properties.getInt( actionName + LEGACY_TRACE_THRESHOLD_SUFFIX, -1); mActionPropertiesMap.put(action, new ActionProperties(action, properties.getBoolean(actionName + ENABLE_SUFFIX, mEnabled), properties.getInt(actionName + SAMPLE_INTERVAL_SUFFIX, samplingInterval), properties.getInt(actionName + TRACE_THRESHOLD_SUFFIX, legacyActionTraceThreshold))); } if (DEBUG) { Log.d(TAG, "updated action properties: " + mActionPropertiesMap); } } mDeviceConfigPropertiesUpdated.open(); } /** Loading Loading @@ -369,16 +385,38 @@ public class LatencyTracker { return "com.android.telemetry.latency-tracker-" + getNameOfAction(STATSD_ACTION[action]); } /** * @deprecated Use {@link #isEnabled(Context, int)} */ @Deprecated public static boolean isEnabled(Context ctx) { return getInstance(ctx).isEnabled(); } /** * @deprecated Used {@link #isEnabled(int)} */ @Deprecated public boolean isEnabled() { synchronized (mLock) { return mEnabled; } } public static boolean isEnabled(Context ctx, int action) { return getInstance(ctx).isEnabled(action); } public boolean isEnabled(int action) { synchronized (mLock) { ActionProperties actionProperties = mActionPropertiesMap.get(action); if (actionProperties != null) { return actionProperties.isEnabled(); } return false; } } /** * Notifies that an action is starting. <s>This needs to be called from the main thread.</s> * Loading Loading @@ -468,8 +506,14 @@ public class LatencyTracker { boolean shouldSample; int traceThreshold; synchronized (mLock) { shouldSample = ThreadLocalRandom.current().nextInt() % mSamplingInterval == 0; traceThreshold = mTraceThresholdPerAction[action]; ActionProperties actionProperties = mActionPropertiesMap.get(action); if (actionProperties == null) { return; } int nextRandNum = ThreadLocalRandom.current().nextInt( actionProperties.getSamplingInterval()); shouldSample = nextRandNum == 0; traceThreshold = actionProperties.getTraceThreshold(); } if (traceThreshold > 0 && duration >= traceThreshold) { Loading Loading @@ -549,4 +593,59 @@ public class LatencyTracker { return (int) (mEndRtc - mStartRtc); } } @VisibleForTesting static class ActionProperties { static final String ENABLE_SUFFIX = "_enable"; static final String SAMPLE_INTERVAL_SUFFIX = "_sample_interval"; // TODO: migrate all usages of the legacy trace theshold property static final String LEGACY_TRACE_THRESHOLD_SUFFIX = ""; static final String TRACE_THRESHOLD_SUFFIX = "_trace_threshold"; @Action private final int mAction; private final boolean mEnabled; private final int mSamplingInterval; private final int mTraceThreshold; ActionProperties( @Action int action, boolean enabled, int samplingInterval, int traceThreshold) { this.mAction = action; com.android.internal.util.AnnotationValidations.validate( Action.class, null, mAction); this.mEnabled = enabled; this.mSamplingInterval = samplingInterval; this.mTraceThreshold = traceThreshold; } @Action int getAction() { return mAction; } boolean isEnabled() { return mEnabled; } int getSamplingInterval() { return mSamplingInterval; } int getTraceThreshold() { return mTraceThreshold; } @Override public String toString() { return "ActionProperties{" + " mAction=" + mAction + ", mEnabled=" + mEnabled + ", mSamplingInterval=" + mSamplingInterval + ", mTraceThreshold=" + mTraceThreshold + "}"; } } }
core/res/res/values-b+sr+Latn-television/strings.xml +2 −2 Original line number Diff line number Diff line Loading @@ -17,6 +17,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="7002619958660406548">"Mikrofon je blokiran"</string> <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="2131954635322568179">"Kamera je blokirana"</string> <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="7002619958660406548">"Микрофон је блокиран"</string> <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="2131954635322568179">"Камера је блокирана"</string> </resources>
core/res/res/values-b+sr+Latn/strings.xml +2058 −2058 File changed.File size exceeds preview limit. View original file View changed file