Merge "audioservice: add latency modes to dumpsys" into udc-dev
diff --git a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
index 820bb1b..4f6bcb6 100644
--- a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
+++ b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
@@ -185,37 +185,41 @@
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parseApkLite");
try {
for (File file : files) {
- if (isApkFile(file)) {
- final ParseResult<ApkLite> result = parseApkLite(input, file, flags);
- if (result.isError()) {
- return input.error(result);
- }
+ if (!isApkFile(file)) {
+ continue;
+ }
- final ApkLite lite = result.getResult();
- // Assert that all package names and version codes are
- // consistent with the first one we encounter.
- if (packageName == null) {
- packageName = lite.getPackageName();
- versionCode = lite.getVersionCode();
- } else {
- if (!packageName.equals(lite.getPackageName())) {
- return input.error(PackageManager.INSTALL_PARSE_FAILED_BAD_MANIFEST,
- "Inconsistent package " + lite.getPackageName() + " in " + file
- + "; expected " + packageName);
- }
- if (versionCode != lite.getVersionCode()) {
- return input.error(PackageManager.INSTALL_PARSE_FAILED_BAD_MANIFEST,
- "Inconsistent version " + lite.getVersionCode() + " in " + file
- + "; expected " + versionCode);
- }
- }
+ final ParseResult<ApkLite> result = parseApkLite(input, file, flags);
+ if (result.isError()) {
+ return input.error(result);
+ }
- // Assert that each split is defined only oncuses-static-libe
- if (apks.put(lite.getSplitName(), lite) != null) {
+ final ApkLite lite = result.getResult();
+ // Assert that all package names and version codes are
+ // consistent with the first one we encounter.
+ if (packageName == null) {
+ packageName = lite.getPackageName();
+ versionCode = lite.getVersionCode();
+ } else {
+ if (!packageName.equals(lite.getPackageName())) {
return input.error(PackageManager.INSTALL_PARSE_FAILED_BAD_MANIFEST,
- "Split name " + lite.getSplitName()
- + " defined more than once; most recent was " + file);
+ "Inconsistent package " + lite.getPackageName() + " in " + file
+ + "; expected " + packageName);
}
+ if (versionCode != lite.getVersionCode()) {
+ return input.error(PackageManager.INSTALL_PARSE_FAILED_BAD_MANIFEST,
+ "Inconsistent version " + lite.getVersionCode() + " in " + file
+ + "; expected " + versionCode);
+ }
+ }
+
+ // Assert that each split is defined only once
+ ApkLite prev = apks.put(lite.getSplitName(), lite);
+ if (prev != null) {
+ return input.error(PackageManager.INSTALL_PARSE_FAILED_BAD_MANIFEST,
+ "Split name " + lite.getSplitName()
+ + " defined more than once; most recent was " + file
+ + ", previous was " + prev.getPath());
}
}
baseApk = apks.remove(null);
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index e908ced..48b5cac 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -212,14 +212,7 @@
@GuardedBy("mLock")
private boolean mFoldedDeviceState;
- private final CameraManager.DeviceStateListener mFoldStateListener =
- new CameraManager.DeviceStateListener() {
- @Override
- public final void onDeviceStateChanged(boolean folded) {
- synchronized (mLock) {
- mFoldedDeviceState = folded;
- }
- }};
+ private CameraManager.DeviceStateListener mFoldStateListener;
private static final String TAG = "CameraCharacteristics";
@@ -245,7 +238,18 @@
/**
* Return the device state listener for this Camera characteristics instance
*/
- CameraManager.DeviceStateListener getDeviceStateListener() { return mFoldStateListener; }
+ CameraManager.DeviceStateListener getDeviceStateListener() {
+ if (mFoldStateListener == null) {
+ mFoldStateListener = new CameraManager.DeviceStateListener() {
+ @Override
+ public final void onDeviceStateChanged(boolean folded) {
+ synchronized (mLock) {
+ mFoldedDeviceState = folded;
+ }
+ }};
+ }
+ return mFoldStateListener;
+ }
/**
* Overrides the property value
diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java
index 51501b5..85f8ca6 100644
--- a/core/java/android/hardware/camera2/CameraManager.java
+++ b/core/java/android/hardware/camera2/CameraManager.java
@@ -1836,6 +1836,7 @@
ctx.getSystemService(DeviceStateManager.class).registerCallback(
new HandlerExecutor(mDeviceStateHandler), mFoldStateListener);
} catch (IllegalStateException e) {
+ mFoldStateListener = null;
Log.v(TAG, "Failed to register device state listener!");
Log.v(TAG, "Device state dependent characteristics updates will not be" +
"functional!");
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index ead5fd4..a044602 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -525,6 +525,8 @@
<permission name="android.permission.USE_ATTESTATION_VERIFICATION_SERVICE" />
<!-- Permission required for GTS test - GtsCredentialsTestCases -->
<permission name="android.permission.LAUNCH_CREDENTIAL_SELECTOR"/>
+ <!-- Permission required for CTS test IntentRedirectionTest -->
+ <permission name="android.permission.QUERY_CLONED_APPS"/>
</privapp-permissions>
<privapp-permissions package="com.android.statementservice">
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index 92c0dab..2a0e476 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -2059,6 +2059,12 @@
"group": "WM_DEBUG_CONFIGURATION",
"at": "com\/android\/server\/wm\/ActivityRecord.java"
},
+ "-233530384": {
+ "message": "Content Recording: Incoming session on display %d can't be set since it is already null; the corresponding VirtualDisplay must have already been removed.",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_CONTENT_RECORDING",
+ "at": "com\/android\/server\/wm\/ContentRecordingController.java"
+ },
"-230587670": {
"message": "SyncGroup %d: Unfinished container: %s",
"level": "VERBOSE",
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java
index 59f120d..4d87c95 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java
@@ -61,6 +61,9 @@
@VisibleForTesting
final ActivityEmbeddingAnimationSpec mAnimationSpec;
+ @Nullable
+ private Animator mActiveAnimator;
+
ActivityEmbeddingAnimationRunner(@NonNull Context context,
@NonNull ActivityEmbeddingController controller) {
mController = controller;
@@ -75,8 +78,10 @@
// applied to make sure the surface is ready.
final List<Consumer<SurfaceControl.Transaction>> postStartTransactionCallbacks =
new ArrayList<>();
- final Animator animator = createAnimator(info, startTransaction, finishTransaction,
+ final Animator animator = createAnimator(info, startTransaction,
+ finishTransaction,
() -> mController.onAnimationFinished(transition), postStartTransactionCallbacks);
+ mActiveAnimator = animator;
// Start the animation.
if (!postStartTransactionCallbacks.isEmpty()) {
@@ -98,6 +103,17 @@
}
}
+ void cancelAnimationFromMerge() {
+ if (mActiveAnimator == null) {
+ Log.e(TAG,
+ "No active ActivityEmbedding animator running but mergeAnimation is "
+ + "trying to cancel one."
+ );
+ return;
+ }
+ mActiveAnimator.end();
+ }
+
/**
* Sets transition animation scale settings value.
* @param scale The setting value of transition animation scale.
@@ -153,6 +169,7 @@
adapter.onAnimationEnd(t);
}
t.apply();
+ mActiveAnimator = null;
animationFinishCallback.run();
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingController.java
index bfbddbb..fbdbd3e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingController.java
@@ -118,6 +118,13 @@
return true;
}
+ @Override
+ public void mergeAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
+ @NonNull SurfaceControl.Transaction t, @NonNull IBinder mergeTarget,
+ @NonNull Transitions.TransitionFinishCallback finishCallback) {
+ mAnimationRunner.cancelAnimationFromMerge();
+ }
+
private boolean handleNonEmbeddedChanges(List<TransitionInfo.Change> changes) {
final Rect nonClosingEmbeddedArea = new Rect();
for (int i = changes.size() - 1; i >= 0; i--) {
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunnerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunnerTests.java
index a625346..4fca8b4 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunnerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunnerTests.java
@@ -65,12 +65,14 @@
final TransitionInfo info = new TransitionInfoBuilder(TRANSIT_OPEN, 0)
.addChange(createChange(FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY))
.build();
- doReturn(mAnimator).when(mAnimRunner).createAnimator(any(), any(), any(), any(), any());
+ doReturn(mAnimator).when(mAnimRunner).createAnimator(any(), any(), any(), any(),
+ any());
mAnimRunner.startAnimation(mTransition, info, mStartTransaction, mFinishTransaction);
final ArgumentCaptor<Runnable> finishCallback = ArgumentCaptor.forClass(Runnable.class);
- verify(mAnimRunner).createAnimator(eq(info), eq(mStartTransaction), eq(mFinishTransaction),
+ verify(mAnimRunner).createAnimator(eq(info), eq(mStartTransaction),
+ eq(mFinishTransaction),
finishCallback.capture(), any());
verify(mStartTransaction).apply();
verify(mAnimator).start();
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationTestBase.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationTestBase.java
index 4f4f356..ab1ccd4 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationTestBase.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationTestBase.java
@@ -47,6 +47,7 @@
@Mock
ShellInit mShellInit;
+
@Mock
Transitions mTransitions;
@Mock
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingControllerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingControllerTests.java
index b8f615a..ba34f1f7 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingControllerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingControllerTests.java
@@ -29,9 +29,13 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
+import android.animation.Animator;
+import android.animation.ValueAnimator;
import android.graphics.Rect;
+import android.view.SurfaceControl;
import android.window.TransitionInfo;
+import androidx.test.annotation.UiThreadTest;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
@@ -58,7 +62,8 @@
@Before
public void setup() {
super.setUp();
- doReturn(mAnimator).when(mAnimRunner).createAnimator(any(), any(), any(), any(), any());
+ doReturn(mAnimator).when(mAnimRunner).createAnimator(any(), any(), any(), any(),
+ any());
}
@Test
@@ -182,6 +187,44 @@
verifyNoMoreInteractions(mFinishTransaction);
}
+ @UiThreadTest
+ @Test
+ public void testMergeAnimation() {
+ final TransitionInfo info = new TransitionInfoBuilder(TRANSIT_OPEN, 0)
+ .addChange(createEmbeddedChange(
+ EMBEDDED_LEFT_BOUNDS, EMBEDDED_LEFT_BOUNDS, TASK_BOUNDS))
+ .build();
+
+ final ValueAnimator animator = ValueAnimator.ofFloat(0, 1);
+ animator.addListener(new Animator.AnimatorListener() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mController.onAnimationFinished(mTransition);
+ }
+
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ }
+
+ @Override
+ public void onAnimationRepeat(Animator animation) {
+ }
+ });
+ doReturn(animator).when(mAnimRunner).createAnimator(any(), any(), any(), any(), any());
+ mController.startAnimation(mTransition, info, mStartTransaction,
+ mFinishTransaction, mFinishCallback);
+ verify(mFinishCallback, never()).onTransitionFinished(any(), any());
+ mController.mergeAnimation(mTransition, info, new SurfaceControl.Transaction(),
+ mTransition,
+ (wct, cb) -> {
+ });
+ verify(mFinishCallback).onTransitionFinished(any(), any());
+ }
+
@Test
public void testOnAnimationFinished() {
// Should not call finish when there is no transition.
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index b1d2e33..4759689 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -3730,7 +3730,12 @@
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
@RequiresPermission(Manifest.permission.BLUETOOTH_STACK)
public void setA2dpSuspended(boolean enable) {
- AudioSystem.setParameters("A2dpSuspended=" + enable);
+ final IAudioService service = getService();
+ try {
+ service.setA2dpSuspended(enable);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
}
/**
@@ -3743,7 +3748,12 @@
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
@RequiresPermission(Manifest.permission.BLUETOOTH_STACK)
public void setLeAudioSuspended(boolean enable) {
- AudioSystem.setParameters("LeAudioSuspended=" + enable);
+ final IAudioService service = getService();
+ try {
+ service.setLeAudioSuspended(enable);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
}
/**
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index fe5afc5..7ce189b 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -231,6 +231,12 @@
void setBluetoothScoOn(boolean on);
+ @EnforcePermission("BLUETOOTH_STACK")
+ void setA2dpSuspended(boolean on);
+
+ @EnforcePermission("BLUETOOTH_STACK")
+ void setLeAudioSuspended(boolean enable);
+
boolean isBluetoothScoOn();
void setBluetoothA2dpOn(boolean on);
diff --git a/media/jni/android_media_tv_Tuner.cpp b/media/jni/android_media_tv_Tuner.cpp
index 6f67d68..1b04f18 100644
--- a/media/jni/android_media_tv_Tuner.cpp
+++ b/media/jni/android_media_tv_Tuner.cpp
@@ -372,13 +372,12 @@
void LnbClientCallbackImpl::onEvent(const LnbEventType lnbEventType) {
ALOGV("LnbClientCallbackImpl::onEvent, type=%d", lnbEventType);
JNIEnv *env = AndroidRuntime::getJNIEnv();
- jobject lnb(env->NewLocalRef(mLnbObj));
- if (!env->IsSameObject(lnb, nullptr)) {
+ ScopedLocalRef lnb(env, env->NewLocalRef(mLnbObj));
+ if (!env->IsSameObject(lnb.get(), nullptr)) {
env->CallVoidMethod(
- lnb,
+ lnb.get(),
gFields.onLnbEventID,
(jint)lnbEventType);
- env->DeleteLocalRef(lnb);
} else {
ALOGE("LnbClientCallbackImpl::onEvent:"
"Lnb object has been freed. Ignoring callback.");
@@ -388,17 +387,15 @@
void LnbClientCallbackImpl::onDiseqcMessage(const vector<uint8_t> &diseqcMessage) {
ALOGV("LnbClientCallbackImpl::onDiseqcMessage");
JNIEnv *env = AndroidRuntime::getJNIEnv();
- jobject lnb(env->NewLocalRef(mLnbObj));
- if (!env->IsSameObject(lnb, nullptr)) {
- jbyteArray array = env->NewByteArray(diseqcMessage.size());
- env->SetByteArrayRegion(array, 0, diseqcMessage.size(),
+ ScopedLocalRef lnb(env, env->NewLocalRef(mLnbObj));
+ if (!env->IsSameObject(lnb.get(), nullptr)) {
+ ScopedLocalRef array(env, env->NewByteArray(diseqcMessage.size()));
+ env->SetByteArrayRegion(array.get(), 0, diseqcMessage.size(),
reinterpret_cast<const jbyte *>(&diseqcMessage[0]));
env->CallVoidMethod(
- lnb,
+ lnb.get(),
gFields.onLnbDiseqcMessageID,
- array);
- env->DeleteLocalRef(lnb);
- env->DeleteLocalRef(array);
+ array.get());
} else {
ALOGE("LnbClientCallbackImpl::onDiseqcMessage:"
"Lnb object has been freed. Ignoring callback.");
@@ -422,10 +419,9 @@
void DvrClientCallbackImpl::onRecordStatus(RecordStatus status) {
ALOGV("DvrClientCallbackImpl::onRecordStatus");
JNIEnv *env = AndroidRuntime::getJNIEnv();
- jobject dvr(env->NewLocalRef(mDvrObj));
- if (!env->IsSameObject(dvr, nullptr)) {
- env->CallVoidMethod(dvr, gFields.onDvrRecordStatusID, (jint)status);
- env->DeleteLocalRef(dvr);
+ ScopedLocalRef dvr(env, env->NewLocalRef(mDvrObj));
+ if (!env->IsSameObject(dvr.get(), nullptr)) {
+ env->CallVoidMethod(dvr.get(), gFields.onDvrRecordStatusID, (jint)status);
} else {
ALOGE("DvrClientCallbackImpl::onRecordStatus:"
"Dvr object has been freed. Ignoring callback.");
@@ -435,10 +431,9 @@
void DvrClientCallbackImpl::onPlaybackStatus(PlaybackStatus status) {
ALOGV("DvrClientCallbackImpl::onPlaybackStatus");
JNIEnv *env = AndroidRuntime::getJNIEnv();
- jobject dvr(env->NewLocalRef(mDvrObj));
- if (!env->IsSameObject(dvr, nullptr)) {
- env->CallVoidMethod(dvr, gFields.onDvrPlaybackStatusID, (jint)status);
- env->DeleteLocalRef(dvr);
+ ScopedLocalRef dvr(env, env->NewLocalRef(mDvrObj));
+ if (!env->IsSameObject(dvr.get(), nullptr)) {
+ env->CallVoidMethod(dvr.get(), gFields.onDvrPlaybackStatusID, (jint)status);
} else {
ALOGE("DvrClientCallbackImpl::onPlaybackStatus:"
"Dvr object has been freed. Ignoring callback.");
@@ -614,7 +609,7 @@
}
/////////////// FilterClientCallbackImpl ///////////////////////
-void FilterClientCallbackImpl::getSectionEvent(jobjectArray &arr, const int size,
+void FilterClientCallbackImpl::getSectionEvent(const jobjectArray& arr, const int size,
const DemuxFilterEvent &event) {
JNIEnv *env = AndroidRuntime::getJNIEnv();
@@ -624,20 +619,20 @@
jint sectionNum = sectionEvent.sectionNum;
jlong dataLength = sectionEvent.dataLength;
- jobject obj = env->NewObject(mSectionEventClass, mSectionEventInitID, tableId, version,
- sectionNum, dataLength);
- env->SetObjectArrayElement(arr, size, obj);
- env->DeleteLocalRef(obj);
+ ScopedLocalRef obj(env, env->NewObject(mSectionEventClass, mSectionEventInitID, tableId,
+ version, sectionNum, dataLength));
+ env->SetObjectArrayElement(arr, size, obj.get());
}
-void FilterClientCallbackImpl::getMediaEvent(jobjectArray &arr, const int size,
+void FilterClientCallbackImpl::getMediaEvent(const jobjectArray& arr, const int size,
const DemuxFilterEvent &event) {
JNIEnv *env = AndroidRuntime::getJNIEnv();
const DemuxFilterMediaEvent &mediaEvent = event.get<DemuxFilterEvent::Tag::media>();
- jobject audioDescriptor = nullptr;
+ ScopedLocalRef<jobject> audioDescriptor(env);
gAudioPresentationFields.init(env);
- jobject presentationsJObj = JAudioPresentationInfo::asJobject(env, gAudioPresentationFields);
+ ScopedLocalRef presentationsJObj(env, JAudioPresentationInfo::asJobject(
+ env, gAudioPresentationFields));
switch (mediaEvent.extraMetaData.getTag()) {
case DemuxFilterMediaEventExtraMetaData::Tag::audio: {
@@ -650,9 +645,9 @@
jbyte adGainFront = ad.adGainFront;
jbyte adGainSurround = ad.adGainSurround;
- audioDescriptor = env->NewObject(mAudioDescriptorClass, mAudioDescriptorInitID, adFade,
- adPan, versionTextTag, adGainCenter, adGainFront,
- adGainSurround);
+ audioDescriptor.reset(env->NewObject(mAudioDescriptorClass, mAudioDescriptorInitID,
+ adFade, adPan, versionTextTag, adGainCenter,
+ adGainFront, adGainSurround));
break;
}
case DemuxFilterMediaEventExtraMetaData::Tag::audioPresentations: {
@@ -660,7 +655,7 @@
env, gAudioPresentationFields,
mediaEvent.extraMetaData
.get<DemuxFilterMediaEventExtraMetaData::Tag::audioPresentations>(),
- presentationsJObj);
+ presentationsJObj.get());
break;
}
default: {
@@ -693,31 +688,27 @@
sc = mediaEvent.scIndexMask.get<DemuxFilterScIndexMask::Tag::scVvc>();
}
- jobject obj = env->NewObject(mMediaEventClass, mMediaEventInitID, streamId, isPtsPresent, pts,
- isDtsPresent, dts, dataLength, offset, nullptr, isSecureMemory,
- avDataId, mpuSequenceNumber, isPesPrivateData, sc,
- audioDescriptor, presentationsJObj);
+ ScopedLocalRef obj(env, env->NewObject(mMediaEventClass, mMediaEventInitID, streamId,
+ isPtsPresent, pts, isDtsPresent, dts, dataLength,
+ offset, nullptr, isSecureMemory, avDataId,
+ mpuSequenceNumber, isPesPrivateData, sc,
+ audioDescriptor.get(), presentationsJObj.get()));
uint64_t avSharedMemSize = mFilterClient->getAvSharedHandleInfo().size;
if (mediaEvent.avMemory.fds.size() > 0 || mediaEvent.avDataId != 0 ||
(dataLength > 0 && (dataLength + offset) < avSharedMemSize)) {
sp<MediaEvent> mediaEventSp =
new MediaEvent(mFilterClient, dupFromAidl(mediaEvent.avMemory),
- mediaEvent.avDataId, dataLength + offset, obj);
+ mediaEvent.avDataId, dataLength + offset, obj.get());
mediaEventSp->mAvHandleRefCnt++;
- env->SetLongField(obj, mMediaEventFieldContextID, (jlong)mediaEventSp.get());
- mediaEventSp->incStrong(obj);
+ env->SetLongField(obj.get(), mMediaEventFieldContextID, (jlong)mediaEventSp.get());
+ mediaEventSp->incStrong(obj.get());
}
- env->SetObjectArrayElement(arr, size, obj);
- if(audioDescriptor != nullptr) {
- env->DeleteLocalRef(audioDescriptor);
- }
- env->DeleteLocalRef(obj);
- env->DeleteLocalRef(presentationsJObj);
+ env->SetObjectArrayElement(arr, size, obj.get());
}
-void FilterClientCallbackImpl::getPesEvent(jobjectArray &arr, const int size,
+void FilterClientCallbackImpl::getPesEvent(const jobjectArray& arr, const int size,
const DemuxFilterEvent &event) {
JNIEnv *env = AndroidRuntime::getJNIEnv();
@@ -726,13 +717,12 @@
jint dataLength = pesEvent.dataLength;
jint mpuSequenceNumber = pesEvent.mpuSequenceNumber;
- jobject obj = env->NewObject(mPesEventClass, mPesEventInitID, streamId, dataLength,
- mpuSequenceNumber);
- env->SetObjectArrayElement(arr, size, obj);
- env->DeleteLocalRef(obj);
+ ScopedLocalRef obj(env, env->NewObject(mPesEventClass, mPesEventInitID, streamId, dataLength,
+ mpuSequenceNumber));
+ env->SetObjectArrayElement(arr, size, obj.get());
}
-void FilterClientCallbackImpl::getTsRecordEvent(jobjectArray &arr, const int size,
+void FilterClientCallbackImpl::getTsRecordEvent(const jobjectArray& arr, const int size,
const DemuxFilterEvent &event) {
JNIEnv *env = AndroidRuntime::getJNIEnv();
@@ -764,13 +754,12 @@
jlong pts = tsRecordEvent.pts;
jint firstMbInSlice = tsRecordEvent.firstMbInSlice;
- jobject obj = env->NewObject(mTsRecordEventClass, mTsRecordEventInitID, jpid, ts, sc,
- byteNumber, pts, firstMbInSlice);
- env->SetObjectArrayElement(arr, size, obj);
- env->DeleteLocalRef(obj);
+ ScopedLocalRef obj(env, env->NewObject(mTsRecordEventClass, mTsRecordEventInitID, jpid, ts, sc,
+ byteNumber, pts, firstMbInSlice));
+ env->SetObjectArrayElement(arr, size, obj.get());
}
-void FilterClientCallbackImpl::getMmtpRecordEvent(jobjectArray &arr, const int size,
+void FilterClientCallbackImpl::getMmtpRecordEvent(const jobjectArray& arr, const int size,
const DemuxFilterEvent &event) {
JNIEnv *env = AndroidRuntime::getJNIEnv();
@@ -783,13 +772,13 @@
jint firstMbInSlice = mmtpRecordEvent.firstMbInSlice;
jlong tsIndexMask = mmtpRecordEvent.tsIndexMask;
- jobject obj = env->NewObject(mMmtpRecordEventClass, mMmtpRecordEventInitID, scHevcIndexMask,
- byteNumber, mpuSequenceNumber, pts, firstMbInSlice, tsIndexMask);
- env->SetObjectArrayElement(arr, size, obj);
- env->DeleteLocalRef(obj);
+ ScopedLocalRef obj(env, env->NewObject(mMmtpRecordEventClass, mMmtpRecordEventInitID,
+ scHevcIndexMask, byteNumber, mpuSequenceNumber, pts,
+ firstMbInSlice, tsIndexMask));
+ env->SetObjectArrayElement(arr, size, obj.get());
}
-void FilterClientCallbackImpl::getDownloadEvent(jobjectArray &arr, const int size,
+void FilterClientCallbackImpl::getDownloadEvent(const jobjectArray& arr, const int size,
const DemuxFilterEvent &event) {
JNIEnv *env = AndroidRuntime::getJNIEnv();
@@ -801,25 +790,25 @@
jint lastItemFragmentIndex = downloadEvent.lastItemFragmentIndex;
jint dataLength = downloadEvent.dataLength;
- jobject obj = env->NewObject(mDownloadEventClass, mDownloadEventInitID, itemId, downloadId,
- mpuSequenceNumber, itemFragmentIndex, lastItemFragmentIndex,
- dataLength);
- env->SetObjectArrayElement(arr, size, obj);
- env->DeleteLocalRef(obj);
+ ScopedLocalRef obj(env, env->NewObject(mDownloadEventClass, mDownloadEventInitID, itemId,
+ downloadId, mpuSequenceNumber, itemFragmentIndex,
+ lastItemFragmentIndex, dataLength));
+ env->SetObjectArrayElement(arr, size, obj.get());
}
-void FilterClientCallbackImpl::getIpPayloadEvent(jobjectArray &arr, const int size,
+void FilterClientCallbackImpl::getIpPayloadEvent(const jobjectArray& arr, const int size,
const DemuxFilterEvent &event) {
JNIEnv *env = AndroidRuntime::getJNIEnv();
- const DemuxFilterIpPayloadEvent &ipPayloadEvent = event.get<DemuxFilterEvent::Tag::ipPayload>();
+ const DemuxFilterIpPayloadEvent &ipPayloadEvent =
+ event.get<DemuxFilterEvent::Tag::ipPayload>();
jint dataLength = ipPayloadEvent.dataLength;
- jobject obj = env->NewObject(mIpPayloadEventClass, mIpPayloadEventInitID, dataLength);
- env->SetObjectArrayElement(arr, size, obj);
- env->DeleteLocalRef(obj);
+ ScopedLocalRef obj(env, env->NewObject(mIpPayloadEventClass, mIpPayloadEventInitID,
+ dataLength));
+ env->SetObjectArrayElement(arr, size, obj.get());
}
-void FilterClientCallbackImpl::getTemiEvent(jobjectArray &arr, const int size,
+void FilterClientCallbackImpl::getTemiEvent(const jobjectArray& arr, const int size,
const DemuxFilterEvent &event) {
JNIEnv *env = AndroidRuntime::getJNIEnv();
@@ -828,110 +817,108 @@
jbyte descrTag = temiEvent.descrTag;
std::vector<uint8_t> descrData = temiEvent.descrData;
- jbyteArray array = env->NewByteArray(descrData.size());
- env->SetByteArrayRegion(array, 0, descrData.size(), reinterpret_cast<jbyte *>(&descrData[0]));
+ ScopedLocalRef array(env, env->NewByteArray(descrData.size()));
+ env->SetByteArrayRegion(array.get(), 0, descrData.size(),
+ reinterpret_cast<jbyte *>(&descrData[0]));
- jobject obj = env->NewObject(mTemiEventClass, mTemiEventInitID, pts, descrTag, array);
- env->SetObjectArrayElement(arr, size, obj);
- env->DeleteLocalRef(array);
- env->DeleteLocalRef(obj);
+ ScopedLocalRef obj(env, env->NewObject(mTemiEventClass, mTemiEventInitID, pts, descrTag,
+ array.get()));
+ env->SetObjectArrayElement(arr, size, obj.get());
}
-void FilterClientCallbackImpl::getScramblingStatusEvent(jobjectArray &arr, const int size,
+void FilterClientCallbackImpl::getScramblingStatusEvent(const jobjectArray& arr, const int size,
const DemuxFilterEvent &event) {
JNIEnv *env = AndroidRuntime::getJNIEnv();
const DemuxFilterMonitorEvent &scramblingStatus =
event.get<DemuxFilterEvent::Tag::monitorEvent>()
.get<DemuxFilterMonitorEvent::Tag::scramblingStatus>();
- jobject obj = env->NewObject(mScramblingStatusEventClass, mScramblingStatusEventInitID,
- scramblingStatus);
- env->SetObjectArrayElement(arr, size, obj);
- env->DeleteLocalRef(obj);
+ ScopedLocalRef obj(env, env->NewObject(mScramblingStatusEventClass,
+ mScramblingStatusEventInitID,
+ scramblingStatus));
+ env->SetObjectArrayElement(arr, size, obj.get());
}
-void FilterClientCallbackImpl::getIpCidChangeEvent(jobjectArray &arr, const int size,
+void FilterClientCallbackImpl::getIpCidChangeEvent(const jobjectArray& arr, const int size,
const DemuxFilterEvent &event) {
JNIEnv *env = AndroidRuntime::getJNIEnv();
const DemuxFilterMonitorEvent &cid = event.get<DemuxFilterEvent::Tag::monitorEvent>()
.get<DemuxFilterMonitorEvent::Tag::cid>();
- jobject obj = env->NewObject(mIpCidChangeEventClass, mIpCidChangeEventInitID, cid);
- env->SetObjectArrayElement(arr, size, obj);
- env->DeleteLocalRef(obj);
+ ScopedLocalRef obj(env, env->NewObject(mIpCidChangeEventClass, mIpCidChangeEventInitID, cid));
+ env->SetObjectArrayElement(arr, size, obj.get());
}
-void FilterClientCallbackImpl::getRestartEvent(jobjectArray &arr, const int size,
+void FilterClientCallbackImpl::getRestartEvent(const jobjectArray& arr, const int size,
const DemuxFilterEvent &event) {
JNIEnv *env = AndroidRuntime::getJNIEnv();
const int32_t &startId = event.get<DemuxFilterEvent::Tag::startId>();
- jobject obj = env->NewObject(mRestartEventClass, mRestartEventInitID, startId);
- env->SetObjectArrayElement(arr, size, obj);
- env->DeleteLocalRef(obj);
+ ScopedLocalRef obj(env, env->NewObject(mRestartEventClass, mRestartEventInitID, startId));
+ env->SetObjectArrayElement(arr, size, obj.get());
}
void FilterClientCallbackImpl::onFilterEvent(const vector<DemuxFilterEvent> &events) {
ALOGV("FilterClientCallbackImpl::onFilterEvent");
JNIEnv *env = AndroidRuntime::getJNIEnv();
- jobjectArray array;
+ ScopedLocalRef<jobjectArray> array(env);
if (!events.empty()) {
- array = env->NewObjectArray(events.size(), mEventClass, nullptr);
+ array.reset(env->NewObjectArray(events.size(), mEventClass, nullptr));
}
for (int i = 0, arraySize = 0; i < events.size(); i++) {
const DemuxFilterEvent &event = events[i];
switch (event.getTag()) {
case DemuxFilterEvent::Tag::media: {
- getMediaEvent(array, arraySize, event);
+ getMediaEvent(array.get(), arraySize, event);
arraySize++;
break;
}
case DemuxFilterEvent::Tag::section: {
- getSectionEvent(array, arraySize, event);
+ getSectionEvent(array.get(), arraySize, event);
arraySize++;
break;
}
case DemuxFilterEvent::Tag::pes: {
- getPesEvent(array, arraySize, event);
+ getPesEvent(array.get(), arraySize, event);
arraySize++;
break;
}
case DemuxFilterEvent::Tag::tsRecord: {
- getTsRecordEvent(array, arraySize, event);
+ getTsRecordEvent(array.get(), arraySize, event);
arraySize++;
break;
}
case DemuxFilterEvent::Tag::mmtpRecord: {
- getMmtpRecordEvent(array, arraySize, event);
+ getMmtpRecordEvent(array.get(), arraySize, event);
arraySize++;
break;
}
case DemuxFilterEvent::Tag::download: {
- getDownloadEvent(array, arraySize, event);
+ getDownloadEvent(array.get(), arraySize, event);
arraySize++;
break;
}
case DemuxFilterEvent::Tag::ipPayload: {
- getIpPayloadEvent(array, arraySize, event);
+ getIpPayloadEvent(array.get(), arraySize, event);
arraySize++;
break;
}
case DemuxFilterEvent::Tag::temi: {
- getTemiEvent(array, arraySize, event);
+ getTemiEvent(array.get(), arraySize, event);
arraySize++;
break;
}
case DemuxFilterEvent::Tag::monitorEvent: {
switch (event.get<DemuxFilterEvent::Tag::monitorEvent>().getTag()) {
case DemuxFilterMonitorEvent::Tag::scramblingStatus: {
- getScramblingStatusEvent(array, arraySize, event);
+ getScramblingStatusEvent(array.get(), arraySize, event);
arraySize++;
break;
}
case DemuxFilterMonitorEvent::Tag::cid: {
- getIpCidChangeEvent(array, arraySize, event);
+ getIpCidChangeEvent(array.get(), arraySize, event);
arraySize++;
break;
}
@@ -943,7 +930,7 @@
break;
}
case DemuxFilterEvent::Tag::startId: {
- getRestartEvent(array, arraySize, event);
+ getRestartEvent(array.get(), arraySize, event);
arraySize++;
break;
}
@@ -953,32 +940,29 @@
}
}
}
- jobject filter(env->NewLocalRef(mFilterObj));
- if (!env->IsSameObject(filter, nullptr)) {
+ ScopedLocalRef filter(env, env->NewLocalRef(mFilterObj));
+ if (!env->IsSameObject(filter.get(), nullptr)) {
jmethodID methodID = gFields.onFilterEventID;
if (mSharedFilter) {
methodID = gFields.onSharedFilterEventID;
}
- env->CallVoidMethod(filter, methodID, array);
- env->DeleteLocalRef(filter);
+ env->CallVoidMethod(filter.get(), methodID, array.get());
} else {
ALOGE("FilterClientCallbackImpl::onFilterEvent:"
"Filter object has been freed. Ignoring callback.");
}
- env->DeleteLocalRef(array);
}
void FilterClientCallbackImpl::onFilterStatus(const DemuxFilterStatus status) {
ALOGV("FilterClientCallbackImpl::onFilterStatus");
JNIEnv *env = AndroidRuntime::getJNIEnv();
- jobject filter(env->NewLocalRef(mFilterObj));
- if (!env->IsSameObject(filter, nullptr)) {
+ ScopedLocalRef filter(env, env->NewLocalRef(mFilterObj));
+ if (!env->IsSameObject(filter.get(), nullptr)) {
jmethodID methodID = gFields.onFilterStatusID;
if (mSharedFilter) {
methodID = gFields.onSharedFilterStatusID;
}
- env->CallVoidMethod(filter, methodID, (jint)static_cast<uint8_t>(status));
- env->DeleteLocalRef(filter);
+ env->CallVoidMethod(filter.get(), methodID, (jint)static_cast<uint8_t>(status));
} else {
ALOGE("FilterClientCallbackImpl::onFilterStatus:"
"Filter object has been freed. Ignoring callback.");
@@ -1115,13 +1099,12 @@
std::scoped_lock<std::mutex> lock(mMutex);
for (const auto& mapEntry : mListenersMap) {
ALOGV("JTuner:%p, jweak:%p", mapEntry.first, mapEntry.second);
- jobject frontend(env->NewLocalRef(mapEntry.second));
- if (!env->IsSameObject(frontend, nullptr)) {
+ ScopedLocalRef frontend(env, env->NewLocalRef(mapEntry.second));
+ if (!env->IsSameObject(frontend.get(), nullptr)) {
env->CallVoidMethod(
- frontend,
+ frontend.get(),
gFields.onFrontendEventID,
(jint)frontendEventType);
- env->DeleteLocalRef(frontend);
} else {
ALOGW("FrontendClientCallbackImpl::onEvent:"
"Frontend object has been freed. Ignoring callback.");
@@ -1133,20 +1116,18 @@
FrontendScanMessageType type, const FrontendScanMessage& message) {
ALOGV("FrontendClientCallbackImpl::onScanMessage, type=%d", type);
JNIEnv *env = AndroidRuntime::getJNIEnv();
- jclass clazz = env->FindClass("android/media/tv/tuner/Tuner");
+ ScopedLocalRef clazz(env, env->FindClass("android/media/tv/tuner/Tuner"));
std::scoped_lock<std::mutex> lock(mMutex);
for (const auto& mapEntry : mListenersMap) {
- jobject frontend(env->NewLocalRef(mapEntry.second));
- if (env->IsSameObject(frontend, nullptr)) {
+ ScopedLocalRef frontend(env, env->NewLocalRef(mapEntry.second));
+ if (env->IsSameObject(frontend.get(), nullptr)) {
ALOGE("FrontendClientCallbackImpl::onScanMessage:"
"Tuner object has been freed. Ignoring callback.");
continue;
}
- executeOnScanMessage(env, clazz, frontend, type, message);
- env->DeleteLocalRef(frontend);
+ executeOnScanMessage(env, clazz.get(), frontend.get(), type, message);
}
- env->DeleteLocalRef(clazz);
}
void FrontendClientCallbackImpl::executeOnScanMessage(
@@ -1183,20 +1164,19 @@
}
case FrontendScanMessageType::FREQUENCY: {
std::vector<int64_t> v = message.get<FrontendScanMessage::Tag::frequencies>();
- jlongArray freqs = env->NewLongArray(v.size());
- env->SetLongArrayRegion(freqs, 0, v.size(), reinterpret_cast<jlong *>(&v[0]));
+ ScopedLocalRef freqs(env, env->NewLongArray(v.size()));
+ env->SetLongArrayRegion(freqs.get(), 0, v.size(), reinterpret_cast<jlong *>(&v[0]));
env->CallVoidMethod(frontend, env->GetMethodID(clazz, "onFrequenciesReport", "([J)V"),
- freqs);
- env->DeleteLocalRef(freqs);
+ freqs.get());
break;
}
case FrontendScanMessageType::SYMBOL_RATE: {
std::vector<int32_t> v = message.get<FrontendScanMessage::Tag::symbolRates>();
- jintArray symbolRates = env->NewIntArray(v.size());
- env->SetIntArrayRegion(symbolRates, 0, v.size(), reinterpret_cast<jint *>(&v[0]));
+ ScopedLocalRef symbolRates(env, env->NewIntArray(v.size()));
+ env->SetIntArrayRegion(symbolRates.get(), 0, v.size(),
+ reinterpret_cast<jint *>(&v[0]));
env->CallVoidMethod(frontend, env->GetMethodID(clazz, "onSymbolRates", "([I)V"),
- symbolRates);
- env->DeleteLocalRef(symbolRates);
+ symbolRates.get());
break;
}
case FrontendScanMessageType::HIERARCHY: {
@@ -1211,27 +1191,29 @@
}
case FrontendScanMessageType::PLP_IDS: {
std::vector<int32_t> jintV = message.get<FrontendScanMessage::Tag::plpIds>();
- jintArray plpIds = env->NewIntArray(jintV.size());
- env->SetIntArrayRegion(plpIds, 0, jintV.size(), reinterpret_cast<jint *>(&jintV[0]));
- env->CallVoidMethod(frontend, env->GetMethodID(clazz, "onPlpIds", "([I)V"), plpIds);
- env->DeleteLocalRef(plpIds);
+ ScopedLocalRef plpIds(env, env->NewIntArray(jintV.size()));
+ env->SetIntArrayRegion(plpIds.get(), 0, jintV.size(),
+ reinterpret_cast<jint *>(&jintV[0]));
+ env->CallVoidMethod(frontend, env->GetMethodID(clazz, "onPlpIds", "([I)V"),
+ plpIds.get());
break;
}
case FrontendScanMessageType::GROUP_IDS: {
std::vector<int32_t> jintV = message.get<FrontendScanMessage::groupIds>();
- jintArray groupIds = env->NewIntArray(jintV.size());
- env->SetIntArrayRegion(groupIds, 0, jintV.size(), reinterpret_cast<jint *>(&jintV[0]));
- env->CallVoidMethod(frontend, env->GetMethodID(clazz, "onGroupIds", "([I)V"), groupIds);
- env->DeleteLocalRef(groupIds);
+ ScopedLocalRef groupIds(env, env->NewIntArray(jintV.size()));
+ env->SetIntArrayRegion(groupIds.get(), 0, jintV.size(),
+ reinterpret_cast<jint *>(&jintV[0]));
+ env->CallVoidMethod(frontend, env->GetMethodID(clazz, "onGroupIds", "([I)V"),
+ groupIds.get());
break;
}
case FrontendScanMessageType::INPUT_STREAM_IDS: {
std::vector<int32_t> jintV = message.get<FrontendScanMessage::inputStreamIds>();
- jintArray streamIds = env->NewIntArray(jintV.size());
- env->SetIntArrayRegion(streamIds, 0, jintV.size(), reinterpret_cast<jint *>(&jintV[0]));
+ ScopedLocalRef streamIds(env, env->NewIntArray(jintV.size()));
+ env->SetIntArrayRegion(streamIds.get(), 0, jintV.size(),
+ reinterpret_cast<jint *>(&jintV[0]));
env->CallVoidMethod(frontend, env->GetMethodID(clazz, "onInputStreamIds", "([I)V"),
- streamIds);
- env->DeleteLocalRef(streamIds);
+ streamIds.get());
break;
}
case FrontendScanMessageType::STANDARD: {
@@ -1254,26 +1236,25 @@
break;
}
case FrontendScanMessageType::ATSC3_PLP_INFO: {
- jclass plpClazz = env->FindClass("android/media/tv/tuner/frontend/Atsc3PlpInfo");
- jmethodID init = env->GetMethodID(plpClazz, "<init>", "(IZ)V");
+ ScopedLocalRef plpClazz(env,
+ env->FindClass("android/media/tv/tuner/frontend/Atsc3PlpInfo"));
+ jmethodID init = env->GetMethodID(plpClazz.get(), "<init>", "(IZ)V");
std::vector<FrontendScanAtsc3PlpInfo> plpInfos =
message.get<FrontendScanMessage::atsc3PlpInfos>();
- jobjectArray array = env->NewObjectArray(plpInfos.size(), plpClazz, nullptr);
+ ScopedLocalRef array(env,
+ env->NewObjectArray(plpInfos.size(), plpClazz.get(), nullptr));
for (int i = 0; i < plpInfos.size(); i++) {
const FrontendScanAtsc3PlpInfo &info = plpInfos[i];
jint plpId = info.plpId;
jboolean lls = info.bLlsFlag;
- jobject obj = env->NewObject(plpClazz, init, plpId, lls);
- env->SetObjectArrayElement(array, i, obj);
- env->DeleteLocalRef(obj);
+ ScopedLocalRef obj(env, env->NewObject(plpClazz.get(), init, plpId, lls));
+ env->SetObjectArrayElement(array.get(), i, obj.get());
}
env->CallVoidMethod(frontend,
env->GetMethodID(clazz, "onAtsc3PlpInfos",
"([Landroid/media/tv/tuner/frontend/"
"Atsc3PlpInfo;)V"),
- array);
- env->DeleteLocalRef(array);
- env->DeleteLocalRef(plpClazz);
+ array.get());
break;
}
case FrontendScanMessageType::MODULATION: {
@@ -1341,11 +1322,12 @@
}
case FrontendScanMessageType::DVBT_CELL_IDS: {
std::vector<int32_t> jintV = message.get<FrontendScanMessage::dvbtCellIds>();
- jintArray cellIds = env->NewIntArray(jintV.size());
- env->SetIntArrayRegion(cellIds, 0, jintV.size(), reinterpret_cast<jint *>(&jintV[0]));
- env->CallVoidMethod(frontend, env->GetMethodID(clazz, "onDvbtCellIdsReported", "([I)V"),
- cellIds);
- env->DeleteLocalRef(cellIds);
+ ScopedLocalRef cellIds(env, env->NewIntArray(jintV.size()));
+ env->SetIntArrayRegion(cellIds.get(), 0, jintV.size(),
+ reinterpret_cast<jint *>(&jintV[0]));
+ env->CallVoidMethod(frontend,
+ env->GetMethodID(clazz, "onDvbtCellIdsReported", "([I)V"),
+ cellIds.get());
break;
}
default:
@@ -1434,7 +1416,8 @@
JNIEnv *env = AndroidRuntime::getJNIEnv();
jclass arrayListClazz = env->FindClass("java/util/ArrayList");
jmethodID arrayListAdd = env->GetMethodID(arrayListClazz, "add", "(Ljava/lang/Object;)Z");
- jobject obj = env->NewObject(arrayListClazz, env->GetMethodID(arrayListClazz, "<init>", "()V"));
+ jobject obj = env->NewObject(arrayListClazz,
+ env->GetMethodID(arrayListClazz, "<init>", "()V"));
jclass integerClazz = env->FindClass("java/lang/Integer");
jmethodID intInit = env->GetMethodID(integerClazz, "<init>", "(I)V");
@@ -1672,7 +1655,7 @@
jclass clazz = env->FindClass("android/media/tv/tuner/frontend/FrontendInfo");
jmethodID infoInit =
env->GetMethodID(clazz, "<init>",
- "(IIJJIIJI[ILandroid/media/tv/tuner/frontend/FrontendCapabilities;)V");
+ "(IIJJIIJI[ILandroid/media/tv/tuner/frontend/FrontendCapabilities;)V");
jint type = (jint)feInfo->type;
jlong minFrequency = feInfo->minFrequency;
@@ -1812,9 +1795,8 @@
jmethodID init = env->GetMethodID(clazz, "<init>", "(II)V");
jobjectArray valObj = env->NewObjectArray(size, clazz, nullptr);
for (int i = 0; i < size; i++) {
- jobject readinessObj = env->NewObject(clazz, init, intTypes[i], readiness[i]);
- env->SetObjectArrayElement(valObj, i, readinessObj);
- env->DeleteLocalRef(readinessObj);
+ ScopedLocalRef readinessObj(env, env->NewObject(clazz, init, intTypes[i], readiness[i]));
+ env->SetObjectArrayElement(valObj, i, readinessObj.get());
}
return valObj;
}
@@ -2260,79 +2242,72 @@
switch (s.getTag()) {
case FrontendStatus::Tag::isDemodLocked: {
jfieldID field = env->GetFieldID(clazz, "mIsDemodLocked", "Ljava/lang/Boolean;");
- jobject newBooleanObj = env->NewObject(booleanClazz, initBoolean,
- s.get<FrontendStatus::Tag::isDemodLocked>());
- env->SetObjectField(statusObj, field, newBooleanObj);
- env->DeleteLocalRef(newBooleanObj);
+ ScopedLocalRef newBooleanObj(env,
+ env->NewObject(booleanClazz, initBoolean,
+ s.get<FrontendStatus::Tag::isDemodLocked>()));
+ env->SetObjectField(statusObj, field, newBooleanObj.get());
break;
}
case FrontendStatus::Tag::snr: {
jfieldID field = env->GetFieldID(clazz, "mSnr", "Ljava/lang/Integer;");
- jobject newIntegerObj =
- env->NewObject(intClazz, initInt, s.get<FrontendStatus::Tag::snr>());
- env->SetObjectField(statusObj, field, newIntegerObj);
- env->DeleteLocalRef(newIntegerObj);
+ ScopedLocalRef newIntegerObj(env,
+ env->NewObject(intClazz, initInt, s.get<FrontendStatus::Tag::snr>()));
+ env->SetObjectField(statusObj, field, newIntegerObj.get());
break;
}
case FrontendStatus::Tag::ber: {
jfieldID field = env->GetFieldID(clazz, "mBer", "Ljava/lang/Integer;");
- jobject newIntegerObj =
- env->NewObject(intClazz, initInt, s.get<FrontendStatus::Tag::ber>());
- env->SetObjectField(statusObj, field, newIntegerObj);
- env->DeleteLocalRef(newIntegerObj);
+ ScopedLocalRef newIntegerObj(env,
+ env->NewObject(intClazz, initInt, s.get<FrontendStatus::Tag::ber>()));
+ env->SetObjectField(statusObj, field, newIntegerObj.get());
break;
}
case FrontendStatus::Tag::per: {
jfieldID field = env->GetFieldID(clazz, "mPer", "Ljava/lang/Integer;");
- jobject newIntegerObj =
- env->NewObject(intClazz, initInt, s.get<FrontendStatus::Tag::per>());
- env->SetObjectField(statusObj, field, newIntegerObj);
- env->DeleteLocalRef(newIntegerObj);
+ ScopedLocalRef newIntegerObj(env,
+ env->NewObject(intClazz, initInt, s.get<FrontendStatus::Tag::per>()));
+ env->SetObjectField(statusObj, field, newIntegerObj.get());
break;
}
case FrontendStatus::Tag::preBer: {
jfieldID field = env->GetFieldID(clazz, "mPerBer", "Ljava/lang/Integer;");
- jobject newIntegerObj =
- env->NewObject(intClazz, initInt, s.get<FrontendStatus::Tag::preBer>());
- env->SetObjectField(statusObj, field, newIntegerObj);
- env->DeleteLocalRef(newIntegerObj);
+ ScopedLocalRef newIntegerObj(env,
+ env->NewObject(intClazz, initInt, s.get<FrontendStatus::Tag::preBer>()));
+ env->SetObjectField(statusObj, field, newIntegerObj.get());
break;
}
case FrontendStatus::Tag::signalQuality: {
jfieldID field = env->GetFieldID(clazz, "mSignalQuality", "Ljava/lang/Integer;");
- jobject newIntegerObj = env->NewObject(intClazz, initInt,
- s.get<FrontendStatus::Tag::signalQuality>());
- env->SetObjectField(statusObj, field, newIntegerObj);
- env->DeleteLocalRef(newIntegerObj);
+ ScopedLocalRef newIntegerObj(env,
+ env->NewObject(intClazz, initInt,
+ s.get<FrontendStatus::Tag::signalQuality>()));
+ env->SetObjectField(statusObj, field, newIntegerObj.get());
break;
}
case FrontendStatus::Tag::signalStrength: {
jfieldID field = env->GetFieldID(clazz, "mSignalStrength", "Ljava/lang/Integer;");
- jobject newIntegerObj =
+ ScopedLocalRef newIntegerObj(env,
env->NewObject(intClazz, initInt,
- s.get<FrontendStatus::Tag::signalStrength>());
- env->SetObjectField(statusObj, field, newIntegerObj);
- env->DeleteLocalRef(newIntegerObj);
+ s.get<FrontendStatus::Tag::signalStrength>()));
+ env->SetObjectField(statusObj, field, newIntegerObj.get());
break;
}
case FrontendStatus::Tag::symbolRate: {
jfieldID field = env->GetFieldID(clazz, "mSymbolRate", "Ljava/lang/Integer;");
- jobject newIntegerObj =
- env->NewObject(intClazz, initInt, s.get<FrontendStatus::Tag::symbolRate>());
- env->SetObjectField(statusObj, field, newIntegerObj);
- env->DeleteLocalRef(newIntegerObj);
+ ScopedLocalRef newIntegerObj(env,
+ env->NewObject(intClazz, initInt,
+ s.get<FrontendStatus::Tag::symbolRate>()));
+ env->SetObjectField(statusObj, field, newIntegerObj.get());
break;
}
case FrontendStatus::Tag::innerFec: {
jfieldID field = env->GetFieldID(clazz, "mInnerFec", "Ljava/lang/Long;");
- jclass longClazz = env->FindClass("java/lang/Long");
- jmethodID initLong = env->GetMethodID(longClazz, "<init>", "(J)V");
- jobject newLongObj =
- env->NewObject(longClazz, initLong,
- static_cast<long>(s.get<FrontendStatus::Tag::innerFec>()));
- env->SetObjectField(statusObj, field, newLongObj);
- env->DeleteLocalRef(newLongObj);
- env->DeleteLocalRef(longClazz);
+ ScopedLocalRef longClazz(env, env->FindClass("java/lang/Long"));
+ jmethodID initLong = env->GetMethodID(longClazz.get(), "<init>", "(J)V");
+ ScopedLocalRef newLongObj(env,
+ env->NewObject(longClazz.get(), initLong,
+ static_cast<long>(s.get<FrontendStatus::Tag::innerFec>())));
+ env->SetObjectField(statusObj, field, newLongObj.get());
break;
}
case FrontendStatus::Tag::modulationStatus: {
@@ -2373,139 +2348,128 @@
}
}
if (valid) {
- jobject newIntegerObj = env->NewObject(intClazz, initInt, intModulation);
- env->SetObjectField(statusObj, field, newIntegerObj);
- env->DeleteLocalRef(newIntegerObj);
+ ScopedLocalRef newIntegerObj(env,
+ env->NewObject(intClazz, initInt, intModulation));
+ env->SetObjectField(statusObj, field, newIntegerObj.get());
}
break;
}
case FrontendStatus::Tag::inversion: {
jfieldID field = env->GetFieldID(clazz, "mInversion", "Ljava/lang/Integer;");
- jobject newIntegerObj =
+ ScopedLocalRef newIntegerObj(env,
env->NewObject(intClazz, initInt,
- static_cast<jint>(s.get<FrontendStatus::Tag::inversion>()));
- env->SetObjectField(statusObj, field, newIntegerObj);
- env->DeleteLocalRef(newIntegerObj);
+ static_cast<jint>(s.get<FrontendStatus::Tag::inversion>())));
+ env->SetObjectField(statusObj, field, newIntegerObj.get());
break;
}
case FrontendStatus::Tag::lnbVoltage: {
jfieldID field = env->GetFieldID(clazz, "mLnbVoltage", "Ljava/lang/Integer;");
- jobject newIntegerObj =
+ ScopedLocalRef newIntegerObj(env,
env->NewObject(intClazz, initInt,
- static_cast<jint>(s.get<FrontendStatus::Tag::lnbVoltage>()));
- env->SetObjectField(statusObj, field, newIntegerObj);
- env->DeleteLocalRef(newIntegerObj);
+ static_cast<jint>(s.get<FrontendStatus::Tag::lnbVoltage>())));
+ env->SetObjectField(statusObj, field, newIntegerObj.get());
break;
}
case FrontendStatus::Tag::plpId: {
jfieldID field = env->GetFieldID(clazz, "mPlpId", "Ljava/lang/Integer;");
- jobject newIntegerObj =
- env->NewObject(intClazz, initInt, s.get<FrontendStatus::Tag::plpId>());
- env->SetObjectField(statusObj, field, newIntegerObj);
- env->DeleteLocalRef(newIntegerObj);
+ ScopedLocalRef newIntegerObj(env,
+ env->NewObject(intClazz, initInt, s.get<FrontendStatus::Tag::plpId>()));
+ env->SetObjectField(statusObj, field, newIntegerObj.get());
break;
}
case FrontendStatus::Tag::isEWBS: {
jfieldID field = env->GetFieldID(clazz, "mIsEwbs", "Ljava/lang/Boolean;");
- jobject newBooleanObj = env->NewObject(booleanClazz, initBoolean,
- s.get<FrontendStatus::Tag::isEWBS>());
- env->SetObjectField(statusObj, field, newBooleanObj);
- env->DeleteLocalRef(newBooleanObj);
+ ScopedLocalRef newBooleanObj(env, env->NewObject(booleanClazz, initBoolean,
+ s.get<FrontendStatus::Tag::isEWBS>()));
+ env->SetObjectField(statusObj, field, newBooleanObj.get());
break;
}
case FrontendStatus::Tag::agc: {
jfieldID field = env->GetFieldID(clazz, "mAgc", "Ljava/lang/Integer;");
- jobject newIntegerObj =
- env->NewObject(intClazz, initInt, s.get<FrontendStatus::Tag::agc>());
- env->SetObjectField(statusObj, field, newIntegerObj);
- env->DeleteLocalRef(newIntegerObj);
+ ScopedLocalRef newIntegerObj(env,
+ env->NewObject(intClazz, initInt, s.get<FrontendStatus::Tag::agc>()));
+ env->SetObjectField(statusObj, field, newIntegerObj.get());
break;
}
case FrontendStatus::Tag::isLnaOn: {
jfieldID field = env->GetFieldID(clazz, "mIsLnaOn", "Ljava/lang/Boolean;");
- jobject newBooleanObj = env->NewObject(booleanClazz, initBoolean,
- s.get<FrontendStatus::Tag::isLnaOn>());
- env->SetObjectField(statusObj, field, newBooleanObj);
- env->DeleteLocalRef(newBooleanObj);
+ ScopedLocalRef newBooleanObj(env, env->NewObject(booleanClazz, initBoolean,
+ s.get<FrontendStatus::Tag::isLnaOn>()));
+ env->SetObjectField(statusObj, field, newBooleanObj.get());
break;
}
case FrontendStatus::Tag::isLayerError: {
jfieldID field = env->GetFieldID(clazz, "mIsLayerErrors", "[Z");
vector<bool> layerErr = s.get<FrontendStatus::Tag::isLayerError>();
- jbooleanArray valObj = env->NewBooleanArray(layerErr.size());
+ ScopedLocalRef valObj(env, env->NewBooleanArray(layerErr.size()));
for (size_t i = 0; i < layerErr.size(); i++) {
jboolean x = layerErr[i];
- env->SetBooleanArrayRegion(valObj, i, 1, &x);
+ env->SetBooleanArrayRegion(valObj.get(), i, 1, &x);
}
- env->SetObjectField(statusObj, field, valObj);
- env->DeleteLocalRef(valObj);
+ env->SetObjectField(statusObj, field, valObj.get());
break;
}
case FrontendStatus::Tag::mer: {
jfieldID field = env->GetFieldID(clazz, "mMer", "Ljava/lang/Integer;");
- jobject newIntegerObj =
- env->NewObject(intClazz, initInt, s.get<FrontendStatus::Tag::mer>());
- env->SetObjectField(statusObj, field, newIntegerObj);
- env->DeleteLocalRef(newIntegerObj);
+ ScopedLocalRef newIntegerObj(env,
+ env->NewObject(intClazz, initInt, s.get<FrontendStatus::Tag::mer>()));
+ env->SetObjectField(statusObj, field, newIntegerObj.get());
break;
}
case FrontendStatus::Tag::freqOffset: {
jfieldID field = env->GetFieldID(clazz, "mFreqOffset", "Ljava/lang/Long;");
- jobject newLongObj = env->NewObject(longClazz, initLong,
- s.get<FrontendStatus::Tag::freqOffset>());
- env->SetObjectField(statusObj, field, newLongObj);
- env->DeleteLocalRef(newLongObj);
+ ScopedLocalRef newLongObj(env, env->NewObject(longClazz, initLong,
+ s.get<FrontendStatus::Tag::freqOffset>()));
+ env->SetObjectField(statusObj, field, newLongObj.get());
break;
}
case FrontendStatus::Tag::hierarchy: {
jfieldID field = env->GetFieldID(clazz, "mHierarchy", "Ljava/lang/Integer;");
- jobject newIntegerObj =
+ ScopedLocalRef newIntegerObj(env,
env->NewObject(intClazz, initInt,
- static_cast<jint>(s.get<FrontendStatus::Tag::hierarchy>()));
- env->SetObjectField(statusObj, field, newIntegerObj);
- env->DeleteLocalRef(newIntegerObj);
+ static_cast<jint>(s.get<FrontendStatus::Tag::hierarchy>())));
+ env->SetObjectField(statusObj, field, newIntegerObj.get());
break;
}
case FrontendStatus::Tag::isRfLocked: {
jfieldID field = env->GetFieldID(clazz, "mIsRfLocked", "Ljava/lang/Boolean;");
- jobject newBooleanObj = env->NewObject(booleanClazz, initBoolean,
- s.get<FrontendStatus::Tag::isRfLocked>());
- env->SetObjectField(statusObj, field, newBooleanObj);
- env->DeleteLocalRef(newBooleanObj);
+ ScopedLocalRef newBooleanObj(env, env->NewObject(booleanClazz, initBoolean,
+ s.get<FrontendStatus::Tag::isRfLocked>()));
+ env->SetObjectField(statusObj, field, newBooleanObj.get());
break;
}
case FrontendStatus::Tag::plpInfo: {
jfieldID field = env->GetFieldID(clazz, "mPlpInfo",
"[Landroid/media/tv/tuner/frontend/FrontendStatus$Atsc3PlpTuningInfo;");
- jclass plpClazz = env->FindClass(
- "android/media/tv/tuner/frontend/FrontendStatus$Atsc3PlpTuningInfo");
- jmethodID initPlp = env->GetMethodID(plpClazz, "<init>", "(IZI)V");
+ ScopedLocalRef plpClazz(env, env->FindClass(
+ "android/media/tv/tuner/frontend/FrontendStatus$Atsc3PlpTuningInfo"));
+ jmethodID initPlp = env->GetMethodID(plpClazz.get(), "<init>", "(IZI)V");
- vector<FrontendStatusAtsc3PlpInfo> plpInfos = s.get<FrontendStatus::Tag::plpInfo>();
- jobjectArray valObj = env->NewObjectArray(plpInfos.size(), plpClazz, nullptr);
+ vector<FrontendStatusAtsc3PlpInfo> plpInfos =
+ s.get<FrontendStatus::Tag::plpInfo>();
+ ScopedLocalRef valObj(env, env->NewObjectArray(plpInfos.size(), plpClazz.get(),
+ nullptr));
for (int i = 0; i < plpInfos.size(); i++) {
const FrontendStatusAtsc3PlpInfo &info = plpInfos[i];
jint plpId = info.plpId;
jboolean isLocked = info.isLocked;
jint uec = info.uec;
- jobject plpObj = env->NewObject(plpClazz, initPlp, plpId, isLocked, uec);
- env->SetObjectArrayElement(valObj, i, plpObj);
- env->DeleteLocalRef(plpObj);
+ ScopedLocalRef plpObj(env, env->NewObject(plpClazz.get(), initPlp, plpId,
+ isLocked, uec));
+ env->SetObjectArrayElement(valObj.get(), i, plpObj.get());
}
- env->SetObjectField(statusObj, field, valObj);
- env->DeleteLocalRef(valObj);
- env->DeleteLocalRef(plpClazz);
+ env->SetObjectField(statusObj, field, valObj.get());
break;
}
case FrontendStatus::Tag::modulations: {
jfieldID field = env->GetFieldID(clazz, "mModulationsExt", "[I");
std::vector<FrontendModulation> v = s.get<FrontendStatus::Tag::modulations>();
- jintArray valObj = env->NewIntArray(v.size());
+ ScopedLocalRef valObj(env, env->NewIntArray(v.size()));
bool valid = false;
jint m[1];
for (int i = 0; i < v.size(); i++) {
@@ -2514,63 +2478,63 @@
case FrontendModulation::Tag::dvbc: {
m[0] = static_cast<jint>(
modulation.get<FrontendModulation::Tag::dvbc>());
- env->SetIntArrayRegion(valObj, i, 1, m);
+ env->SetIntArrayRegion(valObj.get(), i, 1, m);
valid = true;
break;
}
case FrontendModulation::Tag::dvbs: {
m[0] = static_cast<jint>(
modulation.get<FrontendModulation::Tag::dvbs>());
- env->SetIntArrayRegion(valObj, i, 1, m);
+ env->SetIntArrayRegion(valObj.get(), i, 1, m);
valid = true;
break;
}
case FrontendModulation::Tag::dvbt: {
m[0] = static_cast<jint>(
modulation.get<FrontendModulation::Tag::dvbt>());
- env->SetIntArrayRegion(valObj, i, 1, m);
+ env->SetIntArrayRegion(valObj.get(), i, 1, m);
valid = true;
break;
}
case FrontendModulation::Tag::isdbs: {
m[0] = static_cast<jint>(
modulation.get<FrontendModulation::Tag::isdbs>());
- env->SetIntArrayRegion(valObj, i, 1, m);
+ env->SetIntArrayRegion(valObj.get(), i, 1, m);
valid = true;
break;
}
case FrontendModulation::Tag::isdbs3: {
m[0] = static_cast<jint>(
modulation.get<FrontendModulation::Tag::isdbs3>());
- env->SetIntArrayRegion(valObj, i, 1, m);
+ env->SetIntArrayRegion(valObj.get(), i, 1, m);
valid = true;
break;
}
case FrontendModulation::Tag::isdbt: {
m[0] = static_cast<jint>(
modulation.get<FrontendModulation::Tag::isdbt>());
- env->SetIntArrayRegion(valObj, i, 1, m);
+ env->SetIntArrayRegion(valObj.get(), i, 1, m);
valid = true;
break;
}
case FrontendModulation::Tag::atsc: {
m[0] = static_cast<jint>(
modulation.get<FrontendModulation::Tag::atsc>());
- env->SetIntArrayRegion(valObj, i, 1, m);
+ env->SetIntArrayRegion(valObj.get(), i, 1, m);
valid = true;
break;
}
case FrontendModulation::Tag::atsc3: {
m[0] = static_cast<jint>(
modulation.get<FrontendModulation::Tag::atsc3>());
- env->SetIntArrayRegion(valObj, i, 1, m);
+ env->SetIntArrayRegion(valObj.get(), i, 1, m);
valid = true;
break;
}
case FrontendModulation::Tag::dtmb: {
m[0] = static_cast<jint>(
modulation.get<FrontendModulation::Tag::dtmb>());
- env->SetIntArrayRegion(valObj, i, 1, m);
+ env->SetIntArrayRegion(valObj.get(), i, 1, m);
valid = true;
break;
}
@@ -2579,31 +2543,28 @@
}
}
if (valid) {
- env->SetObjectField(statusObj, field, valObj);
+ env->SetObjectField(statusObj, field, valObj.get());
}
- env->DeleteLocalRef(valObj);
break;
}
case FrontendStatus::Tag::bers: {
jfieldID field = env->GetFieldID(clazz, "mBers", "[I");
std::vector<int32_t> v = s.get<FrontendStatus::Tag::bers>();
- jintArray valObj = env->NewIntArray(v.size());
- env->SetIntArrayRegion(valObj, 0, v.size(), reinterpret_cast<jint *>(&v[0]));
+ ScopedLocalRef valObj(env, env->NewIntArray(v.size()));
+ env->SetIntArrayRegion(valObj.get(), 0, v.size(), reinterpret_cast<jint *>(&v[0]));
- env->SetObjectField(statusObj, field, valObj);
- env->DeleteLocalRef(valObj);
+ env->SetObjectField(statusObj, field, valObj.get());
break;
}
case FrontendStatus::Tag::codeRates: {
jfieldID field = env->GetFieldID(clazz, "mCodeRates", "[I");
std::vector<FrontendInnerFec> v = s.get<FrontendStatus::Tag::codeRates>();
- jintArray valObj = env->NewIntArray(v.size());
- env->SetIntArrayRegion(valObj, 0, v.size(), reinterpret_cast<jint *>(&v[0]));
+ ScopedLocalRef valObj(env, env->NewIntArray(v.size()));
+ env->SetIntArrayRegion(valObj.get(), 0, v.size(), reinterpret_cast<jint *>(&v[0]));
- env->SetObjectField(statusObj, field, valObj);
- env->DeleteLocalRef(valObj);
+ env->SetObjectField(statusObj, field, valObj.get());
break;
}
case FrontendStatus::Tag::bandwidth: {
@@ -2642,9 +2603,9 @@
break;
}
if (valid) {
- jobject newIntegerObj = env->NewObject(intClazz, initInt, intBandwidth);
- env->SetObjectField(statusObj, field, newIntegerObj);
- env->DeleteLocalRef(newIntegerObj);
+ ScopedLocalRef newIntegerObj(env, env->NewObject(intClazz, initInt,
+ intBandwidth));
+ env->SetObjectField(statusObj, field, newIntegerObj.get());
}
break;
}
@@ -2655,8 +2616,8 @@
bool valid = true;
switch (interval.getTag()) {
case FrontendGuardInterval::Tag::dvbt: {
- intInterval =
- static_cast<jint>(interval.get<FrontendGuardInterval::Tag::dvbt>());
+ intInterval = static_cast<jint>(
+ interval.get<FrontendGuardInterval::Tag::dvbt>());
break;
}
case FrontendGuardInterval::Tag::isdbt: {
@@ -2665,8 +2626,8 @@
break;
}
case FrontendGuardInterval::Tag::dtmb: {
- intInterval =
- static_cast<jint>(interval.get<FrontendGuardInterval::Tag::dtmb>());
+ intInterval = static_cast<jint>(
+ interval.get<FrontendGuardInterval::Tag::dtmb>());
break;
}
default:
@@ -2674,14 +2635,15 @@
break;
}
if (valid) {
- jobject newIntegerObj = env->NewObject(intClazz, initInt, intInterval);
- env->SetObjectField(statusObj, field, newIntegerObj);
- env->DeleteLocalRef(newIntegerObj);
+ ScopedLocalRef newIntegerObj(env, env->NewObject(intClazz, initInt,
+ intInterval));
+ env->SetObjectField(statusObj, field, newIntegerObj.get());
}
break;
}
case FrontendStatus::Tag::transmissionMode: {
- jfieldID field = env->GetFieldID(clazz, "mTransmissionMode", "Ljava/lang/Integer;");
+ jfieldID field = env->GetFieldID(clazz, "mTransmissionMode",
+ "Ljava/lang/Integer;");
const FrontendTransmissionMode &transmissionMode =
s.get<FrontendStatus::Tag::transmissionMode>();
jint intTransmissionMode;
@@ -2707,32 +2669,30 @@
break;
}
if (valid) {
- jobject newIntegerObj = env->NewObject(intClazz, initInt, intTransmissionMode);
- env->SetObjectField(statusObj, field, newIntegerObj);
- env->DeleteLocalRef(newIntegerObj);
+ ScopedLocalRef newIntegerObj(env, env->NewObject(intClazz, initInt,
+ intTransmissionMode));
+ env->SetObjectField(statusObj, field, newIntegerObj.get());
}
break;
}
case FrontendStatus::Tag::uec: {
jfieldID field = env->GetFieldID(clazz, "mUec", "Ljava/lang/Integer;");
- jobject newIntegerObj =
- env->NewObject(intClazz, initInt, s.get<FrontendStatus::Tag::uec>());
- env->SetObjectField(statusObj, field, newIntegerObj);
- env->DeleteLocalRef(newIntegerObj);
+ ScopedLocalRef newIntegerObj(env,
+ env->NewObject(intClazz, initInt, s.get<FrontendStatus::Tag::uec>()));
+ env->SetObjectField(statusObj, field, newIntegerObj.get());
break;
}
case FrontendStatus::Tag::systemId: {
jfieldID field = env->GetFieldID(clazz, "mSystemId", "Ljava/lang/Integer;");
- jobject newIntegerObj =
- env->NewObject(intClazz, initInt, s.get<FrontendStatus::Tag::systemId>());
- env->SetObjectField(statusObj, field, newIntegerObj);
- env->DeleteLocalRef(newIntegerObj);
+ ScopedLocalRef newIntegerObj(env,
+ env->NewObject(intClazz, initInt, s.get<FrontendStatus::Tag::systemId>()));
+ env->SetObjectField(statusObj, field, newIntegerObj.get());
break;
}
case FrontendStatus::Tag::interleaving: {
jfieldID field = env->GetFieldID(clazz, "mInterleaving", "[I");
std::vector<FrontendInterleaveMode> v = s.get<FrontendStatus::Tag::interleaving>();
- jintArray valObj = env->NewIntArray(v.size());
+ ScopedLocalRef valObj(env, env->NewIntArray(v.size()));
bool valid = false;
jint in[1];
for (int i = 0; i < v.size(); i++) {
@@ -2741,28 +2701,28 @@
case FrontendInterleaveMode::Tag::atsc3: {
in[0] = static_cast<jint>(
interleaving.get<FrontendInterleaveMode::Tag::atsc3>());
- env->SetIntArrayRegion(valObj, i, 1, in);
+ env->SetIntArrayRegion(valObj.get(), i, 1, in);
valid = true;
break;
}
case FrontendInterleaveMode::Tag::dvbc: {
in[0] = static_cast<jint>(
interleaving.get<FrontendInterleaveMode::Tag::dvbc>());
- env->SetIntArrayRegion(valObj, i, 1, in);
+ env->SetIntArrayRegion(valObj.get(), i, 1, in);
valid = true;
break;
}
case FrontendInterleaveMode::Tag::dtmb: {
in[0] = static_cast<jint>(
interleaving.get<FrontendInterleaveMode::Tag::dtmb>());
- env->SetIntArrayRegion(valObj, i, 1, in);
+ env->SetIntArrayRegion(valObj.get(), i, 1, in);
valid = true;
break;
}
case FrontendInterleaveMode::Tag::isdbt: {
in[0] = static_cast<jint>(
interleaving.get<FrontendInterleaveMode::Tag::isdbt>());
- env->SetIntArrayRegion(valObj, i, 1, in);
+ env->SetIntArrayRegion(valObj.get(), i, 1, in);
valid = true;
break;
}
@@ -2771,31 +2731,28 @@
}
}
if (valid) {
- env->SetObjectField(statusObj, field, valObj);
+ env->SetObjectField(statusObj, field, valObj.get());
}
- env->DeleteLocalRef(valObj);
break;
}
case FrontendStatus::Tag::isdbtSegment: {
jfieldID field = env->GetFieldID(clazz, "mIsdbtSegment", "[I");
std::vector<int32_t> v = s.get<FrontendStatus::Tag::isdbtSegment>();
- jintArray valObj = env->NewIntArray(v.size());
- env->SetIntArrayRegion(valObj, 0, v.size(), reinterpret_cast<jint*>(&v[0]));
+ ScopedLocalRef valObj(env, env->NewIntArray(v.size()));
+ env->SetIntArrayRegion(valObj.get(), 0, v.size(), reinterpret_cast<jint*>(&v[0]));
- env->SetObjectField(statusObj, field, valObj);
- env->DeleteLocalRef(valObj);
+ env->SetObjectField(statusObj, field, valObj.get());
break;
}
case FrontendStatus::Tag::tsDataRate: {
jfieldID field = env->GetFieldID(clazz, "mTsDataRate", "[I");
std::vector<int32_t> v = s.get<FrontendStatus::Tag::tsDataRate>();
- jintArray valObj = env->NewIntArray(v.size());
- env->SetIntArrayRegion(valObj, 0, v.size(), reinterpret_cast<jint *>(&v[0]));
+ ScopedLocalRef valObj(env, env->NewIntArray(v.size()));
+ env->SetIntArrayRegion(valObj.get(), 0, v.size(), reinterpret_cast<jint *>(&v[0]));
- env->SetObjectField(statusObj, field, valObj);
- env->DeleteLocalRef(valObj);
+ env->SetObjectField(statusObj, field, valObj.get());
break;
}
case FrontendStatus::Tag::rollOff: {
@@ -2813,7 +2770,8 @@
break;
}
case FrontendRollOff::Tag::isdbs3: {
- intRollOff = static_cast<jint>(rollOff.get<FrontendRollOff::Tag::isdbs3>());
+ intRollOff = static_cast<jint>(
+ rollOff.get<FrontendRollOff::Tag::isdbs3>());
break;
}
default:
@@ -2821,141 +2779,135 @@
break;
}
if (valid) {
- jobject newIntegerObj = env->NewObject(intClazz, initInt, intRollOff);
- env->SetObjectField(statusObj, field, newIntegerObj);
- env->DeleteLocalRef(newIntegerObj);
+ ScopedLocalRef newIntegerObj(env, env->NewObject(intClazz, initInt,
+ intRollOff));
+ env->SetObjectField(statusObj, field, newIntegerObj.get());
}
break;
}
case FrontendStatus::Tag::isMiso: {
jfieldID field = env->GetFieldID(clazz, "mIsMisoEnabled", "Ljava/lang/Boolean;");
- jobject newBooleanObj = env->NewObject(booleanClazz, initBoolean,
- s.get<FrontendStatus::Tag::isMiso>());
- env->SetObjectField(statusObj, field, newBooleanObj);
- env->DeleteLocalRef(newBooleanObj);
+ ScopedLocalRef newBooleanObj(env, env->NewObject(booleanClazz, initBoolean,
+ s.get<FrontendStatus::Tag::isMiso>()));
+ env->SetObjectField(statusObj, field, newBooleanObj.get());
break;
}
case FrontendStatus::Tag::isLinear: {
jfieldID field = env->GetFieldID(clazz, "mIsLinear", "Ljava/lang/Boolean;");
- jobject newBooleanObj = env->NewObject(booleanClazz, initBoolean,
- s.get<FrontendStatus::Tag::isLinear>());
- env->SetObjectField(statusObj, field, newBooleanObj);
- env->DeleteLocalRef(newBooleanObj);
+ ScopedLocalRef newBooleanObj(env, env->NewObject(booleanClazz, initBoolean,
+ s.get<FrontendStatus::Tag::isLinear>()));
+ env->SetObjectField(statusObj, field, newBooleanObj.get());
break;
}
case FrontendStatus::Tag::isShortFrames: {
jfieldID field = env->GetFieldID(clazz, "mIsShortFrames", "Ljava/lang/Boolean;");
- jobject newBooleanObj = env->NewObject(booleanClazz, initBoolean,
- s.get<FrontendStatus::Tag::isShortFrames>());
- env->SetObjectField(statusObj, field, newBooleanObj);
- env->DeleteLocalRef(newBooleanObj);
+ ScopedLocalRef newBooleanObj(env,
+ env->NewObject(booleanClazz, initBoolean,
+ s.get<FrontendStatus::Tag::isShortFrames>()));
+ env->SetObjectField(statusObj, field, newBooleanObj.get());
break;
}
case FrontendStatus::Tag::isdbtMode: {
jfieldID field = env->GetFieldID(clazz, "mIsdbtMode", "Ljava/lang/Integer;");
- jobject newIntegerObj =
- env->NewObject(intClazz, initInt, s.get<FrontendStatus::Tag::isdbtMode>());
- env->SetObjectField(statusObj, field, newIntegerObj);
- env->DeleteLocalRef(newIntegerObj);
+ ScopedLocalRef newIntegerObj(env,
+ env->NewObject(intClazz, initInt,
+ s.get<FrontendStatus::Tag::isdbtMode>()));
+ env->SetObjectField(statusObj, field, newIntegerObj.get());
break;
}
case FrontendStatus::Tag::partialReceptionFlag: {
jfieldID field =
- env->GetFieldID(clazz, "mIsdbtPartialReceptionFlag", "Ljava/lang/Integer;");
- jobject newIntegerObj =
+ env->GetFieldID(clazz, "mIsdbtPartialReceptionFlag",
+ "Ljava/lang/Integer;");
+ ScopedLocalRef newIntegerObj(env,
env->NewObject(intClazz, initInt,
- s.get<FrontendStatus::Tag::partialReceptionFlag>());
- env->SetObjectField(statusObj, field, newIntegerObj);
- env->DeleteLocalRef(newIntegerObj);
+ s.get<FrontendStatus::Tag::partialReceptionFlag>()));
+ env->SetObjectField(statusObj, field, newIntegerObj.get());
break;
}
case FrontendStatus::Tag::streamIdList: {
jfieldID field = env->GetFieldID(clazz, "mStreamIds", "[I");
std::vector<int32_t> ids = s.get<FrontendStatus::Tag::streamIdList>();
- jintArray valObj = env->NewIntArray(v.size());
- env->SetIntArrayRegion(valObj, 0, v.size(), reinterpret_cast<jint *>(&ids[0]));
+ ScopedLocalRef valObj(env, env->NewIntArray(v.size()));
+ env->SetIntArrayRegion(valObj.get(), 0, v.size(),
+ reinterpret_cast<jint *>(&ids[0]));
- env->SetObjectField(statusObj, field, valObj);
- env->DeleteLocalRef(valObj);
+ env->SetObjectField(statusObj, field, valObj.get());
break;
}
case FrontendStatus::Tag::dvbtCellIds: {
jfieldID field = env->GetFieldID(clazz, "mDvbtCellIds", "[I");
std::vector<int32_t> ids = s.get<FrontendStatus::Tag::dvbtCellIds>();
- jintArray valObj = env->NewIntArray(v.size());
- env->SetIntArrayRegion(valObj, 0, v.size(), reinterpret_cast<jint *>(&ids[0]));
+ ScopedLocalRef valObj(env, env->NewIntArray(v.size()));
+ env->SetIntArrayRegion(valObj.get(), 0, v.size(),
+ reinterpret_cast<jint *>(&ids[0]));
- env->SetObjectField(statusObj, field, valObj);
- env->DeleteLocalRef(valObj);
+ env->SetObjectField(statusObj, field, valObj.get());
break;
}
case FrontendStatus::Tag::allPlpInfo: {
jfieldID field = env->GetFieldID(clazz, "mAllPlpInfo",
- "[Landroid/media/tv/tuner/frontend/Atsc3PlpInfo;");
- jclass plpClazz = env->FindClass("android/media/tv/tuner/frontend/Atsc3PlpInfo");
- jmethodID initPlp = env->GetMethodID(plpClazz, "<init>", "(IZ)V");
+ "[Landroid/media/tv/tuner/frontend/Atsc3PlpInfo;");
+ ScopedLocalRef plpClazz(env,
+ env->FindClass("android/media/tv/tuner/frontend/Atsc3PlpInfo"));
+ jmethodID initPlp = env->GetMethodID(plpClazz.get(), "<init>", "(IZ)V");
vector<FrontendScanAtsc3PlpInfo> plpInfos =
s.get<FrontendStatus::Tag::allPlpInfo>();
- jobjectArray valObj = env->NewObjectArray(plpInfos.size(), plpClazz, nullptr);
+ ScopedLocalRef valObj(env, env->NewObjectArray(plpInfos.size(), plpClazz.get(),
+ nullptr));
for (int i = 0; i < plpInfos.size(); i++) {
- jobject plpObj = env->NewObject(plpClazz, initPlp, plpInfos[i].plpId,
- plpInfos[i].bLlsFlag);
- env->SetObjectArrayElement(valObj, i, plpObj);
- env->DeleteLocalRef(plpObj);
+ ScopedLocalRef plpObj(env, env->NewObject(plpClazz.get(), initPlp,
+ plpInfos[i].plpId,
+ plpInfos[i].bLlsFlag));
+ env->SetObjectArrayElement(valObj.get(), i, plpObj.get());
}
- env->SetObjectField(statusObj, field, valObj);
- env->DeleteLocalRef(valObj);
- env->DeleteLocalRef(plpClazz);
+ env->SetObjectField(statusObj, field, valObj.get());
break;
}
case FrontendStatus::Tag::iptvContentUrl: {
jfieldID field = env->GetFieldID(clazz, "mIptvContentUrl", "Ljava/lang/String;");
std::string iptvContentUrl = s.get<FrontendStatus::Tag::iptvContentUrl>();
- jstring iptvContentUrlUtf8 = env->NewStringUTF(iptvContentUrl.c_str());
- env->SetObjectField(statusObj, field, iptvContentUrlUtf8);
- env->DeleteLocalRef(iptvContentUrlUtf8);
+ ScopedLocalRef iptvContentUrlUtf8(env, env->NewStringUTF(iptvContentUrl.c_str()));
+ env->SetObjectField(statusObj, field, iptvContentUrlUtf8.get());
break;
}
case FrontendStatus::Tag::iptvPacketsLost: {
jfieldID field = env->GetFieldID(clazz, "mIptvPacketsLost", "Ljava/lang/Long;");
- jobject newLongObj =
+ ScopedLocalRef newLongObj(env,
env->NewObject(longClazz, initLong,
- s.get<FrontendStatus::Tag::iptvPacketsLost>());
- env->SetObjectField(statusObj, field, newLongObj);
- env->DeleteLocalRef(newLongObj);
+ s.get<FrontendStatus::Tag::iptvPacketsLost>()));
+ env->SetObjectField(statusObj, field, newLongObj.get());
break;
}
case FrontendStatus::Tag::iptvPacketsReceived: {
- jfieldID field = env->GetFieldID(clazz, "mIptvPacketsReceived", "Ljava/lang/Long;");
- jobject newLongObj =
+ jfieldID field = env->GetFieldID(clazz, "mIptvPacketsReceived",
+ "Ljava/lang/Long;");
+ ScopedLocalRef newLongObj(env,
env->NewObject(longClazz, initLong,
- s.get<FrontendStatus::Tag::iptvPacketsReceived>());
- env->SetObjectField(statusObj, field, newLongObj);
- env->DeleteLocalRef(newLongObj);
+ s.get<FrontendStatus::Tag::iptvPacketsReceived>()));
+ env->SetObjectField(statusObj, field, newLongObj.get());
break;
}
case FrontendStatus::Tag::iptvWorstJitterMs: {
jfieldID field = env->GetFieldID(clazz, "mIptvWorstJitterMs",
"Ljava/lang/Integer;");
- jobject newIntegerObj =
+ ScopedLocalRef newIntegerObj(env,
env->NewObject(intClazz, initInt,
- s.get<FrontendStatus::Tag::iptvWorstJitterMs>());
- env->SetObjectField(statusObj, field, newIntegerObj);
- env->DeleteLocalRef(newIntegerObj);
+ s.get<FrontendStatus::Tag::iptvWorstJitterMs>()));
+ env->SetObjectField(statusObj, field, newIntegerObj.get());
break;
}
case FrontendStatus::Tag::iptvAverageJitterMs: {
jfieldID field = env->GetFieldID(clazz, "mIptvAverageJitterMs",
"Ljava/lang/Integer;");
- jobject newIntegerObj =
+ ScopedLocalRef newIntegerObj(env,
env->NewObject(intClazz, initInt,
- s.get<FrontendStatus::Tag::iptvAverageJitterMs>());
- env->SetObjectField(statusObj, field, newIntegerObj);
- env->DeleteLocalRef(newIntegerObj);
+ s.get<FrontendStatus::Tag::iptvAverageJitterMs>()));
+ env->SetObjectField(statusObj, field, newIntegerObj.get());
break;
}
}
@@ -3089,21 +3041,22 @@
vector<FrontendAtsc3PlpSettings> plps = vector<FrontendAtsc3PlpSettings>(len);
// parse PLP settings
for (int i = 0; i < len; i++) {
- jobject plp = env->GetObjectArrayElement(plpSettings, i);
- int32_t plpId = env->GetIntField(plp, env->GetFieldID(plpClazz, "mPlpId", "I"));
+ ScopedLocalRef plp(env, env->GetObjectArrayElement(plpSettings, i));
+ int32_t plpId = env->GetIntField(plp.get(), env->GetFieldID(plpClazz, "mPlpId", "I"));
FrontendAtsc3Modulation modulation =
static_cast<FrontendAtsc3Modulation>(
- env->GetIntField(plp, env->GetFieldID(plpClazz, "mModulation", "I")));
+ env->GetIntField(plp.get(), env->GetFieldID(plpClazz, "mModulation",
+ "I")));
FrontendAtsc3TimeInterleaveMode interleaveMode =
static_cast<FrontendAtsc3TimeInterleaveMode>(
env->GetIntField(
- plp, env->GetFieldID(plpClazz, "mInterleaveMode", "I")));
+ plp.get(), env->GetFieldID(plpClazz, "mInterleaveMode", "I")));
FrontendAtsc3CodeRate codeRate =
static_cast<FrontendAtsc3CodeRate>(
- env->GetIntField(plp, env->GetFieldID(plpClazz, "mCodeRate", "I")));
+ env->GetIntField(plp.get(), env->GetFieldID(plpClazz, "mCodeRate", "I")));
FrontendAtsc3Fec fec =
static_cast<FrontendAtsc3Fec>(
- env->GetIntField(plp, env->GetFieldID(plpClazz, "mFec", "I")));
+ env->GetIntField(plp.get(), env->GetFieldID(plpClazz, "mFec", "I")));
FrontendAtsc3PlpSettings frontendAtsc3PlpSettings {
.plpId = plpId,
.modulation = modulation,
@@ -3112,7 +3065,6 @@
.fec = fec,
};
plps[i] = frontendAtsc3PlpSettings;
- env->DeleteLocalRef(plp);
}
return plps;
}
@@ -3457,18 +3409,17 @@
"android/media/tv/tuner/frontend/IsdbtFrontendSettings$IsdbtLayerSettings");
frontendIsdbtSettings.layerSettings.resize(len);
for (int i = 0; i < len; i++) {
- jobject layer = env->GetObjectArrayElement(layerSettings, i);
+ ScopedLocalRef layer(env, env->GetObjectArrayElement(layerSettings, i));
frontendIsdbtSettings.layerSettings[i].modulation = static_cast<FrontendIsdbtModulation>(
- env->GetIntField(layer, env->GetFieldID(layerClazz, "mModulation", "I")));
+ env->GetIntField(layer.get(), env->GetFieldID(layerClazz, "mModulation", "I")));
frontendIsdbtSettings.layerSettings[i].timeInterleave =
static_cast<FrontendIsdbtTimeInterleaveMode>(
- env->GetIntField(layer,
+ env->GetIntField(layer.get(),
env->GetFieldID(layerClazz, "mTimeInterleaveMode", "I")));
frontendIsdbtSettings.layerSettings[i].coderate = static_cast<FrontendIsdbtCoderate>(
- env->GetIntField(layer, env->GetFieldID(layerClazz, "mCodeRate", "I")));
+ env->GetIntField(layer.get(), env->GetFieldID(layerClazz, "mCodeRate", "I")));
frontendIsdbtSettings.layerSettings[i].numOfSegment =
- env->GetIntField(layer, env->GetFieldID(layerClazz, "mNumOfSegments", "I"));
- env->DeleteLocalRef(layer);
+ env->GetIntField(layer.get(), env->GetFieldID(layerClazz, "mNumOfSegments", "I"));
}
frontendSettings.set<FrontendSettings::Tag::isdbt>(frontendIsdbtSettings);
@@ -3498,7 +3449,8 @@
env->GetIntField(settings, env->GetFieldID(clazz, "mGuardInterval", "I")));
FrontendDtmbTimeInterleaveMode interleaveMode =
static_cast<FrontendDtmbTimeInterleaveMode>(
- env->GetIntField(settings, env->GetFieldID(clazz, "mTimeInterleaveMode", "I")));
+ env->GetIntField(settings, env->GetFieldID(clazz, "mTimeInterleaveMode",
+ "I")));
FrontendDtmbSettings frontendDtmbSettings{
.frequency = freq,
@@ -3515,7 +3467,8 @@
return frontendSettings;
}
-static DemuxIpAddress getDemuxIpAddress(JNIEnv *env, const jobject& config, const char* className) {
+static DemuxIpAddress getDemuxIpAddress(JNIEnv *env, const jobject& config,
+ const char* className) {
jclass clazz = env->FindClass(className);
jbyteArray jsrcIpAddress = static_cast<jbyteArray>(
diff --git a/media/jni/android_media_tv_Tuner.h b/media/jni/android_media_tv_Tuner.h
index 6b1b6b1..01c998d 100644
--- a/media/jni/android_media_tv_Tuner.h
+++ b/media/jni/android_media_tv_Tuner.h
@@ -163,17 +163,19 @@
jmethodID mRestartEventInitID;
jfieldID mMediaEventFieldContextID;
bool mSharedFilter;
- void getSectionEvent(jobjectArray& arr, const int size, const DemuxFilterEvent& event);
- void getMediaEvent(jobjectArray& arr, const int size, const DemuxFilterEvent& event);
- void getPesEvent(jobjectArray& arr, const int size, const DemuxFilterEvent& event);
- void getTsRecordEvent(jobjectArray& arr, const int size, const DemuxFilterEvent& event);
- void getMmtpRecordEvent(jobjectArray& arr, const int size, const DemuxFilterEvent& event);
- void getDownloadEvent(jobjectArray& arr, const int size, const DemuxFilterEvent& event);
- void getIpPayloadEvent(jobjectArray& arr, const int size, const DemuxFilterEvent& event);
- void getTemiEvent(jobjectArray& arr, const int size, const DemuxFilterEvent& event);
- void getScramblingStatusEvent(jobjectArray& arr, const int size, const DemuxFilterEvent& event);
- void getIpCidChangeEvent(jobjectArray& arr, const int size, const DemuxFilterEvent& event);
- void getRestartEvent(jobjectArray& arr, const int size, const DemuxFilterEvent& event);
+ void getSectionEvent(const jobjectArray& arr, const int size, const DemuxFilterEvent& event);
+ void getMediaEvent(const jobjectArray& arr, const int size, const DemuxFilterEvent& event);
+ void getPesEvent(const jobjectArray& arr, const int size, const DemuxFilterEvent& event);
+ void getTsRecordEvent(const jobjectArray& arr, const int size, const DemuxFilterEvent& event);
+ void getMmtpRecordEvent(const jobjectArray& arr, const int size, const DemuxFilterEvent& event);
+ void getDownloadEvent(const jobjectArray& arr, const int size, const DemuxFilterEvent& event);
+ void getIpPayloadEvent(const jobjectArray& arr, const int size, const DemuxFilterEvent& event);
+ void getTemiEvent(const jobjectArray& arr, const int size, const DemuxFilterEvent& event);
+ void getScramblingStatusEvent(const jobjectArray& arr, const int size,
+ const DemuxFilterEvent& event);
+ void getIpCidChangeEvent(const jobjectArray& arr, const int size,
+ const DemuxFilterEvent& event);
+ void getRestartEvent(const jobjectArray& arr, const int size, const DemuxFilterEvent& event);
};
struct JTuner;
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/SettingsPager.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/SettingsPager.kt
index aa5ce30..79635a0 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/SettingsPager.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/SettingsPager.kt
@@ -21,14 +21,13 @@
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.PagerState
+import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.material3.TabRow
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.SideEffect
-import androidx.compose.runtime.State
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
@@ -50,7 +49,7 @@
Column {
val coroutineScope = rememberCoroutineScope()
- val pagerState by rememberPageStateFixed()
+ val pagerState = rememberPageStateFixed()
TabRow(
selectedTabIndex = pagerState.currentPage,
@@ -89,17 +88,30 @@
*/
@Composable
@OptIn(ExperimentalFoundationApi::class)
-private fun rememberPageStateFixed(): State<PagerState> {
+private fun rememberPageStateFixed(): PagerState {
var currentPage by rememberSaveable { mutableStateOf(0) }
- val pagerStateHolder = remember { mutableStateOf(PagerState(currentPage)) }
- LaunchedEffect(LocalConfiguration.current.orientation) {
+ var targetPage by rememberSaveable { mutableStateOf(-1) }
+ val pagerState = rememberPagerState()
+ val configuration = LocalConfiguration.current
+ var lastScreenWidthDp by rememberSaveable { mutableStateOf(-1) }
+ val screenWidthDp = configuration.screenWidthDp
+ LaunchedEffect(screenWidthDp) {
// Reset pager state to fix an issue after configuration change.
- // When we declare android:configChanges="orientation" in the manifest, the pager state is
- // in a weird state after configuration change.
- pagerStateHolder.value = PagerState(currentPage)
+ // When we declare android:configChanges in the manifest, the pager state is in a weird
+ // state after configuration change.
+ targetPage = currentPage
+ lastScreenWidthDp = screenWidthDp
+ }
+ LaunchedEffect(targetPage) {
+ if (targetPage != -1) {
+ pagerState.scrollToPage(targetPage)
+ targetPage = -1
+ }
}
SideEffect {
- currentPage = pagerStateHolder.value.currentPage
+ if (lastScreenWidthDp == screenWidthDp) {
+ currentPage = pagerState.currentPage
+ }
}
- return pagerStateHolder
+ return pagerState
}
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 8b3fd41..43f98c3 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -837,6 +837,8 @@
<uses-permission android:name="android.permission.USE_ATTESTATION_VERIFICATION_SERVICE" />
<!-- Permission required for GTS test - GtsCredentialsTestCases -->
<uses-permission android:name="android.permission.LAUNCH_CREDENTIAL_SELECTOR" />
+ <!-- Permission required for CTS test IntentRedirectionTest -->
+ <uses-permission android:name="android.permission.QUERY_CLONED_APPS" />
<application
android:label="@string/app_label"
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt
index c6c3019..6f6d0f9 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt
@@ -62,7 +62,7 @@
override fun destinationScenes(): StateFlow<Map<UserAction, SceneModel>> =
MutableStateFlow<Map<UserAction, SceneModel>>(
mapOf(
- UserAction.Back to SceneModel(SceneKey.LockScreen),
+ UserAction.Back to SceneModel(SceneKey.Lockscreen),
)
)
.asStateFlow()
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockScreenScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt
similarity index 91%
rename from packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockScreenScene.kt
rename to packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt
index ad33eb5..ab7bc26 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockScreenScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt
@@ -33,7 +33,7 @@
import com.android.systemui.common.ui.compose.Icon
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
-import com.android.systemui.keyguard.ui.viewmodel.LockScreenSceneViewModel
+import com.android.systemui.keyguard.ui.viewmodel.LockscreenSceneViewModel
import com.android.systemui.scene.shared.model.Direction
import com.android.systemui.scene.shared.model.SceneKey
import com.android.systemui.scene.shared.model.SceneModel
@@ -48,13 +48,13 @@
/** The lock screen scene shows when the device is locked. */
@SysUISingleton
-class LockScreenScene
+class LockscreenScene
@Inject
constructor(
@Application private val applicationScope: CoroutineScope,
- private val viewModel: LockScreenSceneViewModel,
+ private val viewModel: LockscreenSceneViewModel,
) : ComposableScene {
- override val key = SceneKey.LockScreen
+ override val key = SceneKey.Lockscreen
override fun destinationScenes(): StateFlow<Map<UserAction, SceneModel>> =
viewModel.upDestinationSceneKey
@@ -69,7 +69,7 @@
override fun Content(
modifier: Modifier,
) {
- LockScreenScene(
+ LockscreenScene(
viewModel = viewModel,
modifier = modifier,
)
@@ -86,8 +86,8 @@
}
@Composable
-private fun LockScreenScene(
- viewModel: LockScreenSceneViewModel,
+private fun LockscreenScene(
+ viewModel: LockscreenSceneViewModel,
modifier: Modifier = Modifier,
) {
// TODO(b/280879610): implement the real UI.
@@ -99,7 +99,7 @@
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier.align(Alignment.Center)
) {
- Text("Lock screen", style = MaterialTheme.typography.headlineMedium)
+ Text("Lockscreen", style = MaterialTheme.typography.headlineMedium)
Row(
horizontalArrangement = Arrangement.spacedBy(8.dp),
) {
diff --git a/packages/SystemUI/res/layout/keyguard_bottom_area.xml b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
index e9acf3f..a3a7135 100644
--- a/packages/SystemUI/res/layout/keyguard_bottom_area.xml
+++ b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
@@ -59,55 +59,44 @@
</LinearLayout>
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:layout_gravity="bottom"
- android:layout_marginHorizontal="@dimen/keyguard_affordance_horizontal_offset"
+ <com.android.systemui.animation.view.LaunchableImageView
+ android:id="@+id/start_button"
+ android:layout_height="@dimen/keyguard_affordance_fixed_height"
+ android:layout_width="@dimen/keyguard_affordance_fixed_width"
+ android:layout_gravity="start|bottom"
+ android:layout_marginStart="@dimen/keyguard_affordance_horizontal_offset"
android:layout_marginBottom="@dimen/keyguard_affordance_vertical_offset"
- android:gravity="bottom"
- >
+ android:scaleType="fitCenter"
+ android:padding="@dimen/keyguard_affordance_fixed_padding"
+ android:tint="?android:attr/textColorPrimary"
+ android:background="@drawable/keyguard_bottom_affordance_bg"
+ android:foreground="@drawable/keyguard_bottom_affordance_selected_border"
+ android:visibility="invisible" />
- <com.android.systemui.animation.view.LaunchableImageView
- android:id="@+id/start_button"
- android:layout_height="@dimen/keyguard_affordance_fixed_height"
- android:layout_width="@dimen/keyguard_affordance_fixed_width"
- android:scaleType="fitCenter"
- android:padding="@dimen/keyguard_affordance_fixed_padding"
- android:tint="?android:attr/textColorPrimary"
- android:background="@drawable/keyguard_bottom_affordance_bg"
- android:foreground="@drawable/keyguard_bottom_affordance_selected_border"
- android:visibility="invisible" />
+ <com.android.systemui.animation.view.LaunchableImageView
+ android:id="@+id/end_button"
+ android:layout_height="@dimen/keyguard_affordance_fixed_height"
+ android:layout_width="@dimen/keyguard_affordance_fixed_width"
+ android:layout_gravity="end|bottom"
+ android:layout_marginEnd="@dimen/keyguard_affordance_horizontal_offset"
+ android:layout_marginBottom="@dimen/keyguard_affordance_vertical_offset"
+ android:scaleType="fitCenter"
+ android:padding="@dimen/keyguard_affordance_fixed_padding"
+ android:tint="?android:attr/textColorPrimary"
+ android:background="@drawable/keyguard_bottom_affordance_bg"
+ android:foreground="@drawable/keyguard_bottom_affordance_selected_border"
+ android:visibility="invisible" />
- <FrameLayout
- android:layout_width="0dp"
- android:layout_weight="1"
- android:layout_height="wrap_content"
- android:paddingHorizontal="24dp"
- >
- <include
- android:id="@+id/keyguard_settings_button"
- layout="@layout/keyguard_settings_popup_menu"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:visibility="gone"
- />
- </FrameLayout>
-
- <com.android.systemui.animation.view.LaunchableImageView
- android:id="@+id/end_button"
- android:layout_height="@dimen/keyguard_affordance_fixed_height"
- android:layout_width="@dimen/keyguard_affordance_fixed_width"
- android:scaleType="fitCenter"
- android:padding="@dimen/keyguard_affordance_fixed_padding"
- android:tint="?android:attr/textColorPrimary"
- android:background="@drawable/keyguard_bottom_affordance_bg"
- android:foreground="@drawable/keyguard_bottom_affordance_selected_border"
- android:visibility="invisible" />
-
- </LinearLayout>
+ <include
+ android:id="@+id/keyguard_settings_button"
+ layout="@layout/keyguard_settings_popup_menu"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="bottom|center"
+ android:layout_marginBottom="@dimen/keyguard_affordance_vertical_offset"
+ android:layout_marginHorizontal="@dimen/keyguard_affordance_horizontal_offset"
+ android:visibility="gone"
+ />
<FrameLayout
android:id="@+id/overlay_container"
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index 5cc0547..4b02171 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -599,7 +599,6 @@
*/
public void startAppearAnimation(SecurityMode securityMode) {
setTranslationY(0f);
- setAlpha(1f);
updateChildren(0 /* translationY */, 1f /* alpha */);
mViewMode.startAppearAnimation(securityMode);
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
index 5b1edc7..b5e5420 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
@@ -674,7 +674,6 @@
public void startAppearAnimation() {
if (mCurrentSecurityMode != SecurityMode.None) {
- setAlpha(1f);
mView.startAppearAnimation(mCurrentSecurityMode);
getCurrentSecurityController(controller -> controller.startAppearAnimation());
}
@@ -1112,7 +1111,7 @@
*/
public void setExpansion(float fraction) {
float scaledFraction = BouncerPanelExpansionCalculator.showBouncerProgress(fraction);
- mView.setAlpha(MathUtils.constrain(1 - scaledFraction, 0f, 1f));
+ setAlpha(MathUtils.constrain(1 - scaledFraction, 0f, 1f));
mView.setTranslationY(scaledFraction * mTranslationY);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/authentication/data/repository/AuthenticationRepository.kt b/packages/SystemUI/src/com/android/systemui/authentication/data/repository/AuthenticationRepository.kt
index cd195f6..9d9a87d 100644
--- a/packages/SystemUI/src/com/android/systemui/authentication/data/repository/AuthenticationRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/authentication/data/repository/AuthenticationRepository.kt
@@ -33,7 +33,7 @@
* A device that is not yet unlocked requires unlocking by completing an authentication
* challenge according to the current authentication method.
*
- * Note that this state has no real bearing on whether the lock screen is showing or dismissed.
+ * Note that this state has no real bearing on whether the lockscreen is showing or dismissed.
*/
val isUnlocked: StateFlow<Boolean>
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt
index 57ce580..8264fed 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt
@@ -73,7 +73,7 @@
is AuthenticationMethodModel.Swipe ->
sceneInteractor.setCurrentScene(
containerName,
- SceneModel(SceneKey.LockScreen),
+ SceneModel(SceneKey.Lockscreen),
)
else -> Unit
}
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
index 340ed2e..5d403e1 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
@@ -613,7 +613,8 @@
// 1700 - clipboard
@JvmField val CLIPBOARD_REMOTE_BEHAVIOR = releasedFlag(1701, "clipboard_remote_behavior")
// TODO(b/278714186) Tracking Bug
- @JvmField val CLIPBOARD_IMAGE_TIMEOUT = unreleasedFlag(1702, "clipboard_image_timeout")
+ @JvmField val CLIPBOARD_IMAGE_TIMEOUT =
+ unreleasedFlag(1702, "clipboard_image_timeout", teamfood = true)
// TODO(b/279405451): Tracking Bug
@JvmField
val CLIPBOARD_SHARED_TRANSITIONS = unreleasedFlag(1703, "clipboard_shared_transitions")
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
index bd6dfe3..f96f337 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
@@ -258,12 +258,10 @@
*/
private var surfaceBehindAlpha = 1f
- private var wallpaperAlpha = 1f
-
@VisibleForTesting
var surfaceBehindAlphaAnimator = ValueAnimator.ofFloat(0f, 1f)
- var wallpaperAlphaAnimator = ValueAnimator.ofFloat(0f, 1f)
+ var wallpaperCannedUnlockAnimator = ValueAnimator.ofFloat(0f, 1f)
/**
* Matrix applied to [surfaceBehindRemoteAnimationTarget], which is the surface of the
@@ -330,6 +328,7 @@
if (surfaceBehindAlpha == 0f) {
Log.d(TAG, "surfaceBehindAlphaAnimator#onAnimationEnd")
surfaceBehindRemoteAnimationTargets = null
+ wallpaperTargets = null
keyguardViewMediator.get().finishSurfaceBehindRemoteAnimation(
false /* cancelled */)
} else {
@@ -340,23 +339,17 @@
})
}
- with(wallpaperAlphaAnimator) {
+ with(wallpaperCannedUnlockAnimator) {
duration = LAUNCHER_ICONS_ANIMATION_DURATION_MS
interpolator = Interpolators.ALPHA_OUT
addUpdateListener { valueAnimator: ValueAnimator ->
- wallpaperAlpha = valueAnimator.animatedValue as Float
- setWallpaperAppearAmount(wallpaperAlpha)
+ setWallpaperAppearAmount(valueAnimator.animatedValue as Float)
}
addListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator) {
- Log.d(TAG, "wallpaperAlphaAnimator#onAnimationEnd, animation ended ")
- if (wallpaperAlpha == 1f) {
- wallpaperTargets = null
- keyguardViewMediator.get().finishExitRemoteAnimation()
- } else {
- Log.d(TAG, "wallpaperAlphaAnimator#onAnimationEnd, " +
- "animation was cancelled: skipping finishAnimation()")
- }
+ Log.d(TAG, "wallpaperCannedUnlockAnimator#onAnimationEnd")
+ keyguardViewMediator.get().exitKeyguardAndFinishSurfaceBehindRemoteAnimation(
+ false /* cancelled */)
}
})
}
@@ -387,11 +380,6 @@
context.resources.getDimensionPixelSize(R.dimen.rounded_corner_radius).toFloat()
}
- fun isAnyKeyguyardAnimatorPlaying(): Boolean {
- return surfaceBehindAlphaAnimator.isStarted ||
- wallpaperAlphaAnimator.isStarted || surfaceBehindEntryAnimator.isStarted
- }
-
/**
* Add a listener to be notified of various stages of the unlock animation.
*/
@@ -536,8 +524,6 @@
wallpaperTargets = wallpapers
surfaceBehindRemoteAnimationStartTime = startTime
- fadeInWallpaper()
-
// If we specifically requested that the surface behind be made visible (vs. it being made
// visible because we're unlocking), then we're in the middle of a swipe-to-unlock touch
// gesture and the surface behind the keyguard should be made visible so that we can animate
@@ -599,7 +585,9 @@
// Finish the keyguard remote animation if the dismiss amount has crossed the threshold.
// Check it here in case there is no more change to the dismiss amount after the last change
// that starts the keyguard animation. @see #updateKeyguardViewMediatorIfThresholdsReached()
- finishKeyguardExitRemoteAnimationIfReachThreshold()
+ if (!playingCannedUnlockAnimation) {
+ finishKeyguardExitRemoteAnimationIfReachThreshold()
+ }
}
/**
@@ -650,7 +638,7 @@
* transition if possible.
*/
private fun unlockToLauncherWithInWindowAnimations() {
- setSurfaceBehindAppearAmount(1f)
+ setSurfaceBehindAppearAmount(1f, wallpapers = false)
try {
// Begin the animation, waiting for the shade to animate out.
@@ -676,19 +664,8 @@
// visible, hide our smartspace.
lockscreenSmartspace?.visibility = View.INVISIBLE
- // As soon as the shade has animated out of the way, finish the keyguard exit animation. The
- // in-window animations in the Launcher window will end on their own.
- handler.postDelayed({
- if (keyguardViewMediator.get().isShowingAndNotOccluded &&
- !keyguardStateController.isKeyguardGoingAway) {
- Log.e(TAG, "Finish keyguard exit animation delayed Runnable ran, but we are " +
- "showing and not going away.")
- return@postDelayed
- }
-
- keyguardViewMediator.get().exitKeyguardAndFinishSurfaceBehindRemoteAnimation(
- false /* cancelled */)
- }, CANNED_UNLOCK_START_DELAY)
+ // Start an animation for the wallpaper, which will finish keyguard exit when it completes.
+ fadeInWallpaper()
}
/**
@@ -809,7 +786,16 @@
* animations and swipe gestures to animate the surface's entry (and exit, if the swipe is
* cancelled).
*/
- fun setSurfaceBehindAppearAmount(amount: Float) {
+ fun setSurfaceBehindAppearAmount(amount: Float, wallpapers: Boolean = true) {
+ val animationAlpha = when {
+ // If we're snapping the keyguard back, immediately begin fading it out.
+ keyguardStateController.isSnappingKeyguardBackAfterSwipe -> amount
+ // If the screen has turned back off, the unlock animation is going to be cancelled,
+ // so set the surface alpha to 0f so it's no longer visible.
+ !powerManager.isInteractive -> 0f
+ else -> surfaceBehindAlpha
+ }
+
surfaceBehindRemoteAnimationTargets?.forEach { surfaceBehindRemoteAnimationTarget ->
val surfaceHeight: Int = surfaceBehindRemoteAnimationTarget.screenSpaceBounds.height()
@@ -839,16 +825,6 @@
surfaceHeight * SURFACE_BEHIND_SCALE_PIVOT_Y
)
-
- val animationAlpha = when {
- // If we're snapping the keyguard back, immediately begin fading it out.
- keyguardStateController.isSnappingKeyguardBackAfterSwipe -> amount
- // If the screen has turned back off, the unlock animation is going to be cancelled,
- // so set the surface alpha to 0f so it's no longer visible.
- !powerManager.isInteractive -> 0f
- else -> surfaceBehindAlpha
- }
-
// SyncRtSurfaceTransactionApplier cannot apply transaction when the target view is
// unable to draw
val sc: SurfaceControl? = surfaceBehindRemoteAnimationTarget.leash
@@ -863,28 +839,27 @@
} else {
applyParamsToSurface(
SyncRtSurfaceTransactionApplier.SurfaceParams.Builder(
- surfaceBehindRemoteAnimationTarget.leash)
- .withMatrix(surfaceBehindMatrix)
- .withCornerRadius(roundedCornerRadius)
- .withAlpha(animationAlpha)
- .build()
+ surfaceBehindRemoteAnimationTarget.leash)
+ .withMatrix(surfaceBehindMatrix)
+ .withCornerRadius(roundedCornerRadius)
+ .withAlpha(animationAlpha)
+ .build()
)
}
}
+
+ if (wallpapers) {
+ setWallpaperAppearAmount(amount)
+ }
}
- /**
- * Modify the opacity of a wallpaper window.
- */
fun setWallpaperAppearAmount(amount: Float) {
- wallpaperTargets?.forEach { wallpaper ->
- val animationAlpha = when {
- // If the screen has turned back off, the unlock animation is going to be cancelled,
- // so set the surface alpha to 0f so it's no longer visible.
- !powerManager.isInteractive -> 0f
- else -> amount
- }
+ val animationAlpha = when {
+ !powerManager.isInteractive -> 0f
+ else -> amount
+ }
+ wallpaperTargets?.forEach { wallpaper ->
// SyncRtSurfaceTransactionApplier cannot apply transaction when the target view is
// unable to draw
val sc: SurfaceControl? = wallpaper.leash
@@ -923,6 +898,7 @@
setSurfaceBehindAppearAmount(1f)
surfaceBehindAlphaAnimator.cancel()
surfaceBehindEntryAnimator.cancel()
+ wallpaperCannedUnlockAnimator.cancel()
try {
launcherUnlockController?.setUnlockAmount(1f, false /* forceIfAnimating */)
} catch (e: RemoteException) {
@@ -931,6 +907,7 @@
// That target is no longer valid since the animation finished, null it out.
surfaceBehindRemoteAnimationTargets = null
+ wallpaperTargets = null
playingCannedUnlockAnimation = false
willUnlockWithInWindowLauncherAnimations = false
@@ -972,8 +949,8 @@
private fun fadeInWallpaper() {
Log.d(TAG, "fadeInWallpaper")
- wallpaperAlphaAnimator.cancel()
- wallpaperAlphaAnimator.start()
+ wallpaperCannedUnlockAnimator.cancel()
+ wallpaperCannedUnlockAnimator.start()
}
private fun fadeOutSurfaceBehind() {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 51af8fb..45e4623 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -3009,19 +3009,6 @@
mSurfaceBehindRemoteAnimationRequested = false;
mSurfaceBehindRemoteAnimationRunning = false;
mKeyguardStateController.notifyKeyguardGoingAway(false);
- finishExitRemoteAnimation();
- }
-
- void finishExitRemoteAnimation() {
- if (mKeyguardUnlockAnimationControllerLazy.get().isAnyKeyguyardAnimatorPlaying()
- || mKeyguardStateController.isDismissingFromSwipe()) {
- // If the animation is ongoing, or we are not done with the swipe gesture,
- // it's too early to terminate the animation
- Log.d(TAG, "finishAnimation not executing now because "
- + "not all animations have finished");
- return;
- }
- Log.d(TAG, "finishAnimation executing");
if (mSurfaceBehindRemoteAnimationFinishedCallback != null) {
try {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/LockScreenSceneInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/LockscreenSceneInteractor.kt
similarity index 87%
rename from packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/LockScreenSceneInteractor.kt
rename to packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/LockscreenSceneInteractor.kt
index 6170180..d0bc25f 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/LockScreenSceneInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/LockscreenSceneInteractor.kt
@@ -36,8 +36,8 @@
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
-/** Hosts business and application state accessing logic for the lock screen scene. */
-class LockScreenSceneInteractor
+/** Hosts business and application state accessing logic for the lockscreen scene. */
+class LockscreenSceneInteractor
@AssistedInject
constructor(
@Application applicationScope: CoroutineScope,
@@ -59,7 +59,7 @@
initialValue = !authenticationInteractor.isUnlocked.value,
)
- /** Whether it's currently possible to swipe up to dismiss the lock screen. */
+ /** Whether it's currently possible to swipe up to dismiss the lockscreen. */
val isSwipeToDismissEnabled: StateFlow<Boolean> =
combine(
authenticationInteractor.isUnlocked,
@@ -81,9 +81,9 @@
)
init {
- // LOCKING SHOWS LOCK SCREEN.
+ // LOCKING SHOWS Lockscreen.
//
- // Move to the lock screen scene if the device becomes locked while in any scene.
+ // Move to the lockscreen scene if the device becomes locked while in any scene.
applicationScope.launch {
authenticationInteractor.isUnlocked
.map { !it }
@@ -92,7 +92,7 @@
if (isLocked) {
sceneInteractor.setCurrentScene(
containerName = containerName,
- scene = SceneModel(SceneKey.LockScreen),
+ scene = SceneModel(SceneKey.Lockscreen),
)
}
}
@@ -101,7 +101,7 @@
// BYPASS UNLOCK.
//
// Moves to the gone scene if bypass is enabled and the device becomes unlocked while in the
- // lock screen scene.
+ // lockscreen scene.
applicationScope.launch {
combine(
authenticationInteractor.isBypassEnabled,
@@ -110,7 +110,7 @@
::Triple,
)
.collect { (isBypassEnabled, isUnlocked, currentScene) ->
- if (isBypassEnabled && isUnlocked && currentScene.key == SceneKey.LockScreen) {
+ if (isBypassEnabled && isUnlocked && currentScene.key == SceneKey.Lockscreen) {
sceneInteractor.setCurrentScene(
containerName = containerName,
scene = SceneModel(SceneKey.Gone),
@@ -119,9 +119,9 @@
}
}
- // SWIPE TO DISMISS LOCK SCREEN.
+ // SWIPE TO DISMISS Lockscreen.
//
- // If switched from the lock screen to the gone scene and the auth method was a swipe,
+ // If switched from the lockscreen to the gone scene and the auth method was a swipe,
// unlocks the device.
applicationScope.launch {
combine(
@@ -133,7 +133,7 @@
val (previousScene, currentScene) = scenes
if (
authMethod is AuthenticationMethodModel.Swipe &&
- previousScene.key == SceneKey.LockScreen &&
+ previousScene.key == SceneKey.Lockscreen &&
currentScene.key == SceneKey.Gone
) {
authenticationInteractor.unlockDevice()
@@ -141,9 +141,9 @@
}
}
- // DISMISS LOCK SCREEN IF AUTH METHOD IS REMOVED.
+ // DISMISS Lockscreen IF AUTH METHOD IS REMOVED.
//
- // If the auth method becomes None while on the lock screen scene, dismisses the lock
+ // If the auth method becomes None while on the lockscreen scene, dismisses the lock
// screen.
applicationScope.launch {
combine(
@@ -153,7 +153,7 @@
)
.collect { (authMethod, scene) ->
if (
- scene.key == SceneKey.LockScreen &&
+ scene.key == SceneKey.Lockscreen &&
authMethod == AuthenticationMethodModel.None
) {
sceneInteractor.setCurrentScene(
@@ -165,8 +165,8 @@
}
}
- /** Attempts to dismiss the lock screen. This will cause the bouncer to show, if needed. */
- fun dismissLockScreen() {
+ /** Attempts to dismiss the lockscreen. This will cause the bouncer to show, if needed. */
+ fun dismissLockscreen() {
bouncerInteractor.showOrUnlockDevice(containerName = containerName)
}
@@ -181,6 +181,6 @@
interface Factory {
fun create(
containerName: String,
- ): LockScreenSceneInteractor
+ ): LockscreenSceneInteractor
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractor.kt
index 233146a5..54bc349 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractor.kt
@@ -40,6 +40,7 @@
import com.android.systemui.keyguard.data.repository.KeyguardBouncerRepository
import com.android.systemui.keyguard.data.repository.TrustRepository
import com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants
+import com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants.EXPANSION_HIDDEN
import com.android.systemui.keyguard.shared.model.BouncerShowMessageModel
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.shared.system.SysUiStatsLog
@@ -196,6 +197,7 @@
cancelShowRunnable()
repository.setPrimaryShowingSoon(false)
repository.setPrimaryShow(false)
+ repository.setPanelExpansion(EXPANSION_HIDDEN)
primaryBouncerCallbackInteractor.dispatchVisibilityChanged(View.INVISIBLE)
Trace.endSection()
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
index 0db4ab1..555a09b 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
@@ -124,7 +124,9 @@
setUpUdfps(rootView)
- setUpClock(rootView)
+ if (!shouldHideClock) {
+ setUpClock(rootView)
+ }
rootView.measure(
View.MeasureSpec.makeMeasureSpec(
@@ -352,28 +354,23 @@
clockController.clock = clock
colorOverride?.let { clock.events.onSeedColorChanged(it) }
- if (!shouldHideClock) {
- clock.largeClock.events.onTargetRegionChanged(
- KeyguardClockSwitch.getLargeClockRegion(parentView)
- )
- clockView?.let { parentView.removeView(it) }
- clockView =
- clock.largeClock.view.apply {
- if (shouldHighlightSelectedAffordance) {
- alpha = DIM_ALPHA
- }
- parentView.addView(this)
- visibility = View.VISIBLE
+ clock.largeClock.events.onTargetRegionChanged(
+ KeyguardClockSwitch.getLargeClockRegion(parentView)
+ )
+
+ clockView?.let { parentView.removeView(it) }
+ clockView =
+ clock.largeClock.view.apply {
+ if (shouldHighlightSelectedAffordance) {
+ alpha = DIM_ALPHA
}
- } else {
- clockView?.visibility = View.GONE
- }
+ parentView.addView(this)
+ visibility = View.VISIBLE
+ }
// Hide smart space if the clock has weather display; otherwise show it
- val hasCustomWeatherDataDisplay =
- clock.largeClock.config.hasCustomWeatherDataDisplay == true
- hideSmartspace(hasCustomWeatherDataDisplay)
+ hideSmartspace(clock.largeClock.config.hasCustomWeatherDataDisplay)
}
companion object {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockScreenSceneViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt
similarity index 88%
rename from packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockScreenSceneViewModel.kt
rename to packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt
index 08b9613..f212a55 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockScreenSceneViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt
@@ -20,7 +20,7 @@
import com.android.systemui.common.shared.model.ContentDescription
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.dagger.qualifiers.Application
-import com.android.systemui.keyguard.domain.interactor.LockScreenSceneInteractor
+import com.android.systemui.keyguard.domain.interactor.LockscreenSceneInteractor
import com.android.systemui.scene.shared.model.SceneKey
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
@@ -31,17 +31,17 @@
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
-/** Models UI state and handles user input for the lock screen scene. */
-class LockScreenSceneViewModel
+/** Models UI state and handles user input for the lockscreen scene. */
+class LockscreenSceneViewModel
@AssistedInject
constructor(
@Application applicationScope: CoroutineScope,
- interactorFactory: LockScreenSceneInteractor.Factory,
+ interactorFactory: LockscreenSceneInteractor.Factory,
@Assisted containerName: String,
) {
- private val interactor: LockScreenSceneInteractor = interactorFactory.create(containerName)
+ private val interactor: LockscreenSceneInteractor = interactorFactory.create(containerName)
- /** The icon for the "lock" button on the lock screen. */
+ /** The icon for the "lock" button on the lockscreen. */
val lockButtonIcon: StateFlow<Icon> =
interactor.isDeviceLocked
.map { isLocked -> lockIcon(isLocked = isLocked) }
@@ -63,12 +63,12 @@
/** Notifies that the lock button on the lock screen was clicked. */
fun onLockButtonClicked() {
- interactor.dismissLockScreen()
+ interactor.dismissLockscreen()
}
/** Notifies that some content on the lock screen was clicked. */
fun onContentClicked() {
- interactor.dismissLockScreen()
+ interactor.dismissLockscreen()
}
private fun upDestinationSceneKey(
@@ -103,6 +103,6 @@
interface Factory {
fun create(
containerName: String,
- ): LockScreenSceneViewModel
+ ): LockscreenSceneViewModel
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModel.kt
index 6525a98..36dec1d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModel.kt
@@ -16,7 +16,7 @@
package com.android.systemui.qs.ui.viewmodel
-import com.android.systemui.keyguard.domain.interactor.LockScreenSceneInteractor
+import com.android.systemui.keyguard.domain.interactor.LockscreenSceneInteractor
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
@@ -25,15 +25,15 @@
class QuickSettingsSceneViewModel
@AssistedInject
constructor(
- lockScreenSceneInteractorFactory: LockScreenSceneInteractor.Factory,
+ lockscreenSceneInteractorFactory: LockscreenSceneInteractor.Factory,
@Assisted containerName: String,
) {
- private val lockScreenSceneInteractor: LockScreenSceneInteractor =
- lockScreenSceneInteractorFactory.create(containerName)
+ private val lockscreenSceneInteractor: LockscreenSceneInteractor =
+ lockscreenSceneInteractorFactory.create(containerName)
/** Notifies that some content in quick settings was clicked. */
fun onContentClicked() {
- lockScreenSceneInteractor.dismissLockScreen()
+ lockscreenSceneInteractor.dismissLockscreen()
}
@AssistedFactory
diff --git a/packages/SystemUI/src/com/android/systemui/scene/shared/model/SceneKey.kt b/packages/SystemUI/src/com/android/systemui/scene/shared/model/SceneKey.kt
index 9ef439d..e7811e3 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/shared/model/SceneKey.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/shared/model/SceneKey.kt
@@ -32,8 +32,8 @@
*/
object Gone : SceneKey("gone")
- /** The lock screen is the scene that shows when the device is locked. */
- object LockScreen : SceneKey("lockscreen")
+ /** The lockscreen is the scene that shows when the device is locked. */
+ object Lockscreen : SceneKey("lockscreen")
/**
* The shade is the scene whose primary purpose is to show a scrollable list of notifications.
diff --git a/packages/SystemUI/src/com/android/systemui/shade/DebugDrawable.java b/packages/SystemUI/src/com/android/systemui/shade/DebugDrawable.java
index 2336673..9235fcc 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/DebugDrawable.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/DebugDrawable.java
@@ -84,7 +84,7 @@
Color.YELLOW, "calculatePanelHeightShade()");
drawDebugInfo(canvas,
(int) mQsController.calculateNotificationsTopPadding(
- mNotificationPanelViewController.isExpanding(),
+ mNotificationPanelViewController.isExpandingOrCollapsing(),
mNotificationPanelViewController.getKeyguardNotificationStaticPadding(),
mNotificationPanelViewController.getExpandedFraction()),
Color.MAGENTA, "calculateNotificationsTopPadding()");
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index af12bc2..752c982 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -233,7 +233,6 @@
import javax.inject.Provider;
import kotlin.Unit;
-
import kotlinx.coroutines.CoroutineDispatcher;
@CentralSurfacesComponent.CentralSurfacesScope
@@ -415,7 +414,11 @@
private final KeyguardClockPositionAlgorithm.Result
mClockPositionResult =
new KeyguardClockPositionAlgorithm.Result();
- private boolean mIsExpanding;
+ /**
+ * Indicates shade (or just QS) is expanding or collapsing but doesn't fully cover KEYGUARD
+ * state when shade can be expanded with swipe down or swipe down from the top to full QS.
+ */
+ private boolean mIsExpandingOrCollapsing;
/**
* Indicates drag starting height when swiping down or up on heads-up notifications.
@@ -1862,7 +1865,7 @@
@Override
public void expandToNotifications() {
- if (mSplitShadeEnabled && (isShadeFullyExpanded() || isExpanding())) {
+ if (mSplitShadeEnabled && (isShadeFullyExpanded() || isExpandingOrCollapsing())) {
return;
}
if (mQsController.getExpanded()) {
@@ -2109,6 +2112,9 @@
? QUICK_SETTINGS : (
mKeyguardStateController.canDismissLockScreen() ? UNLOCK : BOUNCER_UNLOCK);
if (!isFalseTouch(x, y, interactionType)) {
+ mShadeLog.logFlingExpands(vel, vectorVel, interactionType,
+ this.mFlingAnimationUtils.getMinVelocityPxPerSecond(),
+ mExpandedFraction > 0.5f, mAllowExpandForSmallExpansion);
if (Math.abs(vectorVel) < this.mFlingAnimationUtils.getMinVelocityPxPerSecond()) {
expands = shouldExpandWhenNotFlinging();
} else {
@@ -2269,7 +2275,7 @@
void requestScrollerTopPaddingUpdate(boolean animate) {
mNotificationStackScrollLayoutController.updateTopPadding(
- mQsController.calculateNotificationsTopPadding(mIsExpanding,
+ mQsController.calculateNotificationsTopPadding(mIsExpandingOrCollapsing,
getKeyguardNotificationStaticPadding(), mExpandedFraction), animate);
if (isKeyguardShowing()
&& mKeyguardBypassController.getBypassEnabled()) {
@@ -2322,7 +2328,7 @@
}
int maxHeight;
if (mQsController.isExpandImmediate() || mQsController.getExpanded()
- || mIsExpanding && mQsController.getExpandedWhenExpandingStarted()
+ || mIsExpandingOrCollapsing && mQsController.getExpandedWhenExpandingStarted()
|| mPulsing || mSplitShadeEnabled) {
maxHeight = mQsController.calculatePanelHeightExpanded(
mClockPositionResult.stackScrollerPadding);
@@ -2342,8 +2348,11 @@
return maxHeight;
}
- public boolean isExpanding() {
- return mIsExpanding;
+ @Override
+ public boolean isExpandingOrCollapsing() {
+ float lockscreenExpansionProgress = mQsController.getLockscreenShadeDragProgress();
+ return mIsExpandingOrCollapsing
+ || (0 < lockscreenExpansionProgress && lockscreenExpansionProgress < 1);
}
private void onHeightUpdated(float expandedHeight) {
@@ -2355,7 +2364,7 @@
mExpandedFraction, isExpanded(), mTracking, mExpansionDragDownAmountPx);
}
if (!mQsController.getExpanded() || mQsController.isExpandImmediate()
- || mIsExpanding && mQsController.getExpandedWhenExpandingStarted()) {
+ || mIsExpandingOrCollapsing && mQsController.getExpandedWhenExpandingStarted()) {
// Updating the clock position will set the top padding which might
// trigger a new panel height and re-position the clock.
// This is a circular dependency and should be avoided, otherwise we'll have
@@ -2493,7 +2502,7 @@
mNotificationStackScrollLayoutController.onExpansionStopped();
mHeadsUpManager.onExpandingFinished();
mConversationNotificationManager.onNotificationPanelExpandStateChanged(isFullyCollapsed());
- mIsExpanding = false;
+ mIsExpandingOrCollapsing = false;
mMediaHierarchyManager.setCollapsingShadeFromQS(false);
mMediaHierarchyManager.setQsExpanded(mQsController.getExpanded());
if (isFullyCollapsed()) {
@@ -3199,7 +3208,7 @@
ipw.print("mDisplayTopInset="); ipw.println(mDisplayTopInset);
ipw.print("mDisplayRightInset="); ipw.println(mDisplayRightInset);
ipw.print("mDisplayLeftInset="); ipw.println(mDisplayLeftInset);
- ipw.print("mIsExpanding="); ipw.println(mIsExpanding);
+ ipw.print("mIsExpandingOrCollapsing="); ipw.println(mIsExpandingOrCollapsing);
ipw.print("mHeadsUpStartHeight="); ipw.println(mHeadsUpStartHeight);
ipw.print("mListenForHeadsUp="); ipw.println(mListenForHeadsUp);
ipw.print("mNavigationBarBottomHeight="); ipw.println(mNavigationBarBottomHeight);
@@ -3431,7 +3440,7 @@
void notifyExpandingStarted() {
if (!mExpanding) {
mExpanding = true;
- mIsExpanding = true;
+ mIsExpandingOrCollapsing = true;
mQsController.onExpandingStarted(mQsController.getFullyExpanded());
}
}
@@ -3492,7 +3501,7 @@
* gesture), we always play haptic.
*/
private void maybeVibrateOnOpening(boolean openingWithTouch) {
- if (mVibrateOnOpening) {
+ if (mVibrateOnOpening && mBarState != KEYGUARD && mBarState != SHADE_LOCKED) {
if (!openingWithTouch || !mHasVibratedOnOpen) {
mVibratorHelper.vibrate(VibrationEffect.EFFECT_TICK);
mHasVibratedOnOpen = true;
@@ -3792,7 +3801,7 @@
} else if (mBarState == SHADE_LOCKED) {
return true;
} else {
- // case of two finger swipe from the top of keyguard
+ // case of swipe from the top of keyguard to expanded QS
return mQsController.computeExpansionFraction() == 1;
}
}
@@ -4044,7 +4053,7 @@
* shade QS are always expanded
*/
private void closeQsIfPossible() {
- boolean openOrOpening = isShadeFullyExpanded() || isExpanding();
+ boolean openOrOpening = isShadeFullyExpanded() || isExpandingOrCollapsing();
if (!(mSplitShadeEnabled && openOrOpening)) {
mQsController.closeQs();
}
@@ -4767,7 +4776,7 @@
// If pulse is expanding already, let's give it the touch. There are situations
// where the panel starts expanding even though we're also pulsing
- boolean pulseShouldGetTouch = (!mIsExpanding
+ boolean pulseShouldGetTouch = (!mIsExpandingOrCollapsing
&& !mQsController.shouldQuickSettingsIntercept(mDownX, mDownY, 0))
|| mPulseExpansionHandler.isExpanding();
if (pulseShouldGetTouch && mPulseExpansionHandler.onTouchEvent(event)) {
@@ -4933,7 +4942,7 @@
mShadeLog.logHasVibrated(mHasVibratedOnOpen, mExpandedFraction);
}
addMovement(event);
- if (!isFullyCollapsed() && !isOnKeyguard()) {
+ if (!isFullyCollapsed()) {
maybeVibrateOnOpening(true /* openingWithTouch */);
}
float h = y - mInitialExpandY;
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeController.java b/packages/SystemUI/src/com/android/systemui/shade/ShadeController.java
index e08bc33..d0a3cbb 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeController.java
@@ -78,6 +78,11 @@
boolean isShadeFullyOpen();
/**
+ * Returns whether shade or QS are currently opening or collapsing.
+ */
+ boolean isExpandingOrCollapsing();
+
+ /**
* Add a runnable for NotificationPanelView to post when the panel is expanded.
*
* @param action the action to post
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerImpl.java b/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerImpl.java
index c71467b..d00dab6 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerImpl.java
@@ -164,6 +164,11 @@
}
@Override
+ public boolean isExpandingOrCollapsing() {
+ return mNotificationPanelViewController.isExpandingOrCollapsing();
+ }
+
+ @Override
public void postOnShadeExpanded(Runnable executable) {
mNotificationPanelViewController.addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeLogger.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeLogger.kt
index 25073c1b..2b772e3 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeLogger.kt
@@ -253,6 +253,31 @@
)
}
+ fun logFlingExpands(
+ vel: Float,
+ vectorVel: Float,
+ interactionType: Int,
+ minVelocityPxPerSecond: Float,
+ expansionOverHalf: Boolean,
+ allowExpandForSmallExpansion: Boolean
+ ) {
+ buffer.log(
+ TAG,
+ LogLevel.VERBOSE,
+ {
+ int1 = interactionType
+ long1 = vel.toLong()
+ long2 = vectorVel.toLong()
+ double1 = minVelocityPxPerSecond.toDouble()
+ bool1 = expansionOverHalf
+ bool2 = allowExpandForSmallExpansion
+ },
+ { "NPVC flingExpands called with vel: $long1, vectorVel: $long2, " +
+ "interactionType: $int1, minVelocityPxPerSecond: $double1 " +
+ "expansionOverHalf: $bool1, allowExpandForSmallExpansion: $bool2" }
+ )
+ }
+
fun flingQs(flingType: Int, isClick: Boolean) {
buffer.log(
TAG,
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeViewController.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeViewController.kt
index d5a9e95..f75047c 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeViewController.kt
@@ -48,7 +48,7 @@
fun expandToNotifications()
/** Returns whether the shade is expanding or collapsing itself or quick settings. */
- val isExpanding: Boolean
+ val isExpandingOrCollapsing: Boolean
/**
* Returns whether the shade height is greater than zero (i.e. partially or fully expanded),
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt
index dcae258..8a96a47 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt
@@ -17,7 +17,7 @@
package com.android.systemui.shade.ui.viewmodel
import com.android.systemui.dagger.qualifiers.Application
-import com.android.systemui.keyguard.domain.interactor.LockScreenSceneInteractor
+import com.android.systemui.keyguard.domain.interactor.LockscreenSceneInteractor
import com.android.systemui.scene.shared.model.SceneKey
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
@@ -33,11 +33,11 @@
@AssistedInject
constructor(
@Application private val applicationScope: CoroutineScope,
- lockScreenSceneInteractorFactory: LockScreenSceneInteractor.Factory,
+ lockscreenSceneInteractorFactory: LockscreenSceneInteractor.Factory,
@Assisted private val containerName: String,
) {
- private val lockScreenInteractor: LockScreenSceneInteractor =
- lockScreenSceneInteractorFactory.create(containerName)
+ private val lockScreenInteractor: LockscreenSceneInteractor =
+ lockscreenSceneInteractorFactory.create(containerName)
/** The key of the scene we should switch to when swiping up. */
val upDestinationSceneKey: StateFlow<SceneKey> =
@@ -54,13 +54,13 @@
/** Notifies that some content in the shade was clicked. */
fun onContentClicked() {
- lockScreenInteractor.dismissLockScreen()
+ lockScreenInteractor.dismissLockscreen()
}
private fun upDestinationSceneKey(
isLocked: Boolean,
): SceneKey {
- return if (isLocked) SceneKey.LockScreen else SceneKey.Gone
+ return if (isLocked) SceneKey.Lockscreen else SceneKey.Gone
}
@AssistedFactory
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
index ae7c216..b0f3f59 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
@@ -93,6 +93,12 @@
private boolean mAppearing;
private float mPulseHeight = MAX_PULSE_HEIGHT;
+ /**
+ * The ExpandableNotificationRow that is pulsing, or the one that was pulsing
+ * when the device started to transition from AOD to LockScreen.
+ */
+ private ExpandableNotificationRow mPulsingRow;
+
/** Fraction of lockscreen to shade animation (on lockscreen swipe down). */
private float mFractionToShade;
@@ -564,6 +570,19 @@
return mPulsing && entry.isAlerting();
}
+ public void setPulsingRow(ExpandableNotificationRow row) {
+ mPulsingRow = row;
+ }
+
+ /**
+ * @param row The row to check
+ * @return true if row is the pulsing row when the device started to transition from AOD to lock
+ * screen
+ */
+ public boolean isPulsingRow(ExpandableView row) {
+ return mPulsingRow == row;
+ }
+
public boolean isPanelTracking() {
return mPanelTracking;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
index 92d767a..6f1c378 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
@@ -548,7 +548,7 @@
ExpandableViewState viewState = view.getViewState();
viewState.location = ExpandableViewState.LOCATION_UNKNOWN;
- final float expansionFraction = getExpansionFractionWithoutShelf(
+ float expansionFraction = getExpansionFractionWithoutShelf(
algorithmState, ambientState);
// Add gap between sections.
@@ -619,6 +619,11 @@
updateViewWithShelf(view, viewState, shelfStart);
}
}
+ // Avoid pulsing notification flicker during AOD to LS
+ // A pulsing notification is already expanded, no need to expand it again with animation
+ if (ambientState.isPulsingRow(view)) {
+ expansionFraction = 1.0f;
+ }
// Clip height of view right before shelf.
viewState.height = (int) (getMaxAllowedChildHeight(view) * expansionFraction);
}
@@ -700,9 +705,11 @@
&& !(child instanceof FooterView);
}
- private void updatePulsingStates(StackScrollAlgorithmState algorithmState,
+ @VisibleForTesting
+ void updatePulsingStates(StackScrollAlgorithmState algorithmState,
AmbientState ambientState) {
int childCount = algorithmState.visibleChildren.size();
+ ExpandableNotificationRow pulsingRow = null;
for (int i = 0; i < childCount; i++) {
View child = algorithmState.visibleChildren.get(i);
if (!(child instanceof ExpandableNotificationRow)) {
@@ -714,6 +721,19 @@
}
ExpandableViewState viewState = row.getViewState();
viewState.hidden = false;
+ pulsingRow = row;
+ }
+
+ // Set AmbientState#pulsingRow to the current pulsing row when on AOD.
+ // Set AmbientState#pulsingRow=null when on lockscreen, since AmbientState#pulsingRow
+ // is only used for skipping the unfurl animation for (the notification that was already
+ // showing at full height on AOD) during the AOD=>lockscreen transition, where
+ // dozeAmount=[1f, 0f). We also need to reset the pulsingRow once it is no longer used
+ // because it will interfere with future unfurling animations - for example, during the
+ // LS=>AOD animation, the pulsingRow may stay at full height when it should squish with the
+ // rest of the stack.
+ if (ambientState.getDozeAmount() == 0.0f || ambientState.getDozeAmount() == 1.0f) {
+ ambientState.setPulsingRow(pulsingRow);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java
index 37e77766..0ccc819 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java
@@ -339,7 +339,7 @@
mHeadsUpManager.unpinAll(true /* userUnpinned */);
mMetricsLogger.count("panel_open", 1);
} else if (!mQsController.getExpanded()
- && !mShadeViewController.isExpanding()) {
+ && !mShadeViewController.isExpandingOrCollapsing()) {
mQsController.flingQs(0 /* velocity */,
ShadeViewController.FLING_EXPAND);
mMetricsLogger.count("panel_open_qs", 1);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
index 263566e..5c99f34 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -1224,6 +1224,7 @@
// By default turning off the screen also closes the shade.
// We want to make sure that the shade status is kept after folding/unfolding.
boolean isShadeOpen = mShadeController.isShadeFullyOpen();
+ boolean isShadeExpandingOrCollapsing = mShadeController.isExpandingOrCollapsing();
boolean leaveOpen = isShadeOpen && !willGoToSleep && mState == SHADE;
if (DEBUG) {
Log.d(TAG, String.format(
@@ -1231,14 +1232,15 @@
+ "isFolded=%s, "
+ "willGoToSleep=%s, "
+ "isShadeOpen=%s, "
+ + "isShadeExpandingOrCollapsing=%s, "
+ "leaveOpen=%s",
- isFolded, willGoToSleep, isShadeOpen, leaveOpen));
+ isFolded, willGoToSleep, isShadeOpen, isShadeExpandingOrCollapsing, leaveOpen));
}
if (leaveOpen) {
// below makes shade stay open when going from folded to unfolded
mStatusBarStateController.setLeaveOpenOnKeyguardHide(true);
}
- if (mState != SHADE && isShadeOpen) {
+ if (mState != SHADE && (isShadeOpen || isShadeExpandingOrCollapsing)) {
// When device state changes on KEYGUARD/SHADE_LOCKED we don't want to keep the state of
// the shade and instead we open clean state of keyguard with shade closed.
// Normally some parts of QS state (like expanded/collapsed) are persisted and
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index f2fbd7d..414a2ba 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -488,7 +488,7 @@
final boolean hideBouncerOverDream =
mDreamOverlayStateController.isOverlayActive()
&& (mShadeViewController.isExpanded()
- || mShadeViewController.isExpanding());
+ || mShadeViewController.isExpandingOrCollapsing());
final boolean isUserTrackingStarted =
event.getFraction() != EXPANSION_HIDDEN && event.getTracking();
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
index 1559c64..d2e5a45 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
@@ -18,6 +18,7 @@
import static com.android.keyguard.KeyguardSecurityContainer.MODE_DEFAULT;
import static com.android.keyguard.KeyguardSecurityContainer.MODE_ONE_HANDED;
+import static com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants.EXPANSION_VISIBLE;
import static com.google.common.truth.Truth.assertThat;
@@ -691,6 +692,14 @@
verify(mSideFpsController).hide(SideFpsUiRequestSource.PRIMARY_BOUNCER);
}
+ @Test
+ public void setExpansion_setsAlpha() {
+ mKeyguardSecurityContainerController.setExpansion(EXPANSION_VISIBLE);
+
+ verify(mView).setAlpha(1f);
+ verify(mView).setTranslationY(0f);
+ }
+
private KeyguardSecurityContainer.SwipeListener getRegisteredSwipeListener() {
mKeyguardSecurityContainerController.onViewAttached();
verify(mView).setSwipeListener(mSwipeListenerArgumentCaptor.capture());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt
index 0a9618c..688c2db 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt
@@ -114,7 +114,6 @@
@After
fun tearDown() {
keyguardUnlockAnimationController.notifyFinishedKeyguardExitAnimation(true)
- keyguardUnlockAnimationController.wallpaperAlphaAnimator.cancel()
}
/**
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/LockScreenSceneInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/LockscreenSceneInteractorTest.kt
similarity index 95%
rename from packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/LockScreenSceneInteractorTest.kt
rename to packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/LockscreenSceneInteractorTest.kt
index c2c528a..d622f1c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/LockScreenSceneInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/LockscreenSceneInteractorTest.kt
@@ -36,7 +36,7 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@RunWith(JUnit4::class)
-class LockScreenSceneInteractorTest : SysuiTestCase() {
+class LockscreenSceneInteractorTest : SysuiTestCase() {
private val testScope = TestScope()
private val utils = SceneTestUtils(this, testScope)
@@ -96,9 +96,9 @@
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
authenticationInteractor.lockDevice()
authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
- assertThat(currentScene).isEqualTo(SceneModel(SceneKey.LockScreen))
+ assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Lockscreen))
- underTest.dismissLockScreen()
+ underTest.dismissLockscreen()
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
}
@@ -109,9 +109,9 @@
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
authenticationInteractor.unlockDevice()
authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
- assertThat(currentScene).isEqualTo(SceneModel(SceneKey.LockScreen))
+ assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Lockscreen))
- underTest.dismissLockScreen()
+ underTest.dismissLockscreen()
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Gone))
}
@@ -122,9 +122,9 @@
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
authenticationInteractor.lockDevice()
authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
- assertThat(currentScene).isEqualTo(SceneModel(SceneKey.LockScreen))
+ assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Lockscreen))
- underTest.dismissLockScreen()
+ underTest.dismissLockscreen()
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Gone))
}
@@ -142,7 +142,7 @@
authenticationInteractor.lockDevice()
- assertThat(currentScene).isEqualTo(SceneModel(SceneKey.LockScreen))
+ assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Lockscreen))
}
@Test
@@ -150,11 +150,11 @@
testScope.runTest {
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
authenticationInteractor.lockDevice()
- sceneInteractor.setCurrentScene(CONTAINER_1, SceneModel(SceneKey.LockScreen))
+ sceneInteractor.setCurrentScene(CONTAINER_1, SceneModel(SceneKey.Lockscreen))
if (!authenticationInteractor.isBypassEnabled.value) {
authenticationInteractor.toggleBypassEnabled()
}
- assertThat(currentScene).isEqualTo(SceneModel(SceneKey.LockScreen))
+ assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Lockscreen))
authenticationInteractor.biometricUnlock()
@@ -166,22 +166,22 @@
testScope.runTest {
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
authenticationInteractor.lockDevice()
- sceneInteractor.setCurrentScene(CONTAINER_1, SceneModel(SceneKey.LockScreen))
+ sceneInteractor.setCurrentScene(CONTAINER_1, SceneModel(SceneKey.Lockscreen))
if (authenticationInteractor.isBypassEnabled.value) {
authenticationInteractor.toggleBypassEnabled()
}
- assertThat(currentScene).isEqualTo(SceneModel(SceneKey.LockScreen))
+ assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Lockscreen))
authenticationInteractor.biometricUnlock()
- assertThat(currentScene).isEqualTo(SceneModel(SceneKey.LockScreen))
+ assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Lockscreen))
}
@Test
fun switchFromLockScreenToGone_authMethodSwipe_unlocksDevice() =
testScope.runTest {
val isUnlocked by collectLastValue(authenticationInteractor.isUnlocked)
- sceneInteractor.setCurrentScene(CONTAINER_1, SceneModel(SceneKey.LockScreen))
+ sceneInteractor.setCurrentScene(CONTAINER_1, SceneModel(SceneKey.Lockscreen))
authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
assertThat(isUnlocked).isFalse()
@@ -194,7 +194,7 @@
fun switchFromLockScreenToGone_authMethodNotSwipe_doesNotUnlockDevice() =
testScope.runTest {
val isUnlocked by collectLastValue(authenticationInteractor.isUnlocked)
- sceneInteractor.setCurrentScene(CONTAINER_1, SceneModel(SceneKey.LockScreen))
+ sceneInteractor.setCurrentScene(CONTAINER_1, SceneModel(SceneKey.Lockscreen))
authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
assertThat(isUnlocked).isFalse()
@@ -223,9 +223,9 @@
fun authMethodChangedToNone_onLockScreenScene_dismissesLockScreen() =
testScope.runTest {
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
- sceneInteractor.setCurrentScene(CONTAINER_1, SceneModel(SceneKey.LockScreen))
+ sceneInteractor.setCurrentScene(CONTAINER_1, SceneModel(SceneKey.Lockscreen))
authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
- assertThat(currentScene).isEqualTo(SceneModel(SceneKey.LockScreen))
+ assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Lockscreen))
authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.None)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorTest.kt
index 5d39794..b5cb44a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorTest.kt
@@ -159,6 +159,7 @@
verify(repository).setPrimaryShow(false)
verify(mPrimaryBouncerCallbackInteractor).dispatchVisibilityChanged(View.INVISIBLE)
verify(repository).setPrimaryStartDisappearAnimation(null)
+ verify(repository).setPanelExpansion(EXPANSION_HIDDEN)
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockScreenSceneViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt
similarity index 96%
rename from packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockScreenSceneViewModelTest.kt
rename to packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt
index 9e8be3e..8ba3f0f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockScreenSceneViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt
@@ -22,7 +22,7 @@
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.keyguard.domain.interactor.LockScreenSceneInteractor
+import com.android.systemui.keyguard.domain.interactor.LockscreenSceneInteractor
import com.android.systemui.scene.SceneTestUtils
import com.android.systemui.scene.SceneTestUtils.Companion.CONTAINER_1
import com.android.systemui.scene.shared.model.SceneKey
@@ -39,7 +39,7 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@RunWith(JUnit4::class)
-class LockScreenSceneViewModelTest : SysuiTestCase() {
+class LockscreenSceneViewModelTest : SysuiTestCase() {
private val testScope = TestScope()
private val utils = SceneTestUtils(this, testScope)
@@ -50,11 +50,11 @@
)
private val underTest =
- LockScreenSceneViewModel(
+ LockscreenSceneViewModel(
applicationScope = testScope.backgroundScope,
interactorFactory =
- object : LockScreenSceneInteractor.Factory {
- override fun create(containerName: String): LockScreenSceneInteractor {
+ object : LockscreenSceneInteractor.Factory {
+ override fun create(containerName: String): LockscreenSceneInteractor {
return utils.lockScreenSceneInteractor(
authenticationInteractor = authenticationInteractor,
sceneInteractor = sceneInteractor,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt
index 3f838e6..105387d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt
@@ -20,7 +20,7 @@
import com.android.systemui.SysuiTestCase
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.keyguard.domain.interactor.LockScreenSceneInteractor
+import com.android.systemui.keyguard.domain.interactor.LockscreenSceneInteractor
import com.android.systemui.scene.SceneTestUtils
import com.android.systemui.scene.SceneTestUtils.Companion.CONTAINER_1
import com.android.systemui.scene.shared.model.SceneKey
@@ -49,9 +49,9 @@
private val underTest =
QuickSettingsSceneViewModel(
- lockScreenSceneInteractorFactory =
- object : LockScreenSceneInteractor.Factory {
- override fun create(containerName: String): LockScreenSceneInteractor {
+ lockscreenSceneInteractorFactory =
+ object : LockscreenSceneInteractor.Factory {
+ override fun create(containerName: String): LockscreenSceneInteractor {
return utils.lockScreenSceneInteractor(
authenticationInteractor = authenticationInteractor,
sceneInteractor = sceneInteractor,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryTest.kt
index 6c7017bac..de15c77 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryTest.kt
@@ -45,7 +45,7 @@
listOf(
SceneKey.QuickSettings,
SceneKey.Shade,
- SceneKey.LockScreen,
+ SceneKey.Lockscreen,
SceneKey.Bouncer,
SceneKey.Gone,
)
@@ -62,7 +62,7 @@
fun currentScene() = runTest {
val underTest = utils.fakeSceneContainerRepository()
val currentScene by collectLastValue(underTest.currentScene("container1"))
- assertThat(currentScene).isEqualTo(SceneModel(SceneKey.LockScreen))
+ assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Lockscreen))
underTest.setCurrentScene("container1", SceneModel(SceneKey.Shade))
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Shade))
@@ -88,7 +88,7 @@
utils.fakeSceneContainerConfig("container1"),
utils.fakeSceneContainerConfig(
"container2",
- listOf(SceneKey.QuickSettings, SceneKey.LockScreen)
+ listOf(SceneKey.QuickSettings, SceneKey.Lockscreen)
),
)
)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt
index cf99e3b..ee4f6c2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt
@@ -46,7 +46,7 @@
@Test
fun sceneTransitions() = runTest {
val currentScene by collectLastValue(underTest.currentScene("container1"))
- assertThat(currentScene).isEqualTo(SceneModel(SceneKey.LockScreen))
+ assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Lockscreen))
underTest.setCurrentScene("container1", SceneModel(SceneKey.Shade))
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Shade))
diff --git a/packages/SystemUI/tests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelTest.kt
index 6105c87..cd2f5af 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelTest.kt
@@ -63,7 +63,7 @@
@Test
fun sceneTransition() = runTest {
val currentScene by collectLastValue(underTest.currentScene)
- assertThat(currentScene).isEqualTo(SceneModel(SceneKey.LockScreen))
+ assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Lockscreen))
underTest.setCurrentScene(SceneModel(SceneKey.Shade))
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Shade))
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
index 48e0b53..c5495e1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
@@ -902,6 +902,13 @@
}
@Test
+ public void isExpandingOrCollapsing_returnsTrue_whenQsLockscreenDragInProgress() {
+ when(mQsController.getLockscreenShadeDragProgress()).thenReturn(0.5f);
+ assertThat(mNotificationPanelViewController.isExpandingOrCollapsing()).isTrue();
+ }
+
+
+ @Test
public void getMaxPanelTransitionDistance_inSplitShade_withHeadsUp_returnsBiggerValue() {
enableSplitShade(true);
mNotificationPanelViewController.expandToQs();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt
index 2e7f83d..69d03d9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt
@@ -20,7 +20,7 @@
import com.android.systemui.SysuiTestCase
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.keyguard.domain.interactor.LockScreenSceneInteractor
+import com.android.systemui.keyguard.domain.interactor.LockscreenSceneInteractor
import com.android.systemui.scene.SceneTestUtils
import com.android.systemui.scene.SceneTestUtils.Companion.CONTAINER_1
import com.android.systemui.scene.shared.model.SceneKey
@@ -50,9 +50,9 @@
private val underTest =
ShadeSceneViewModel(
applicationScope = testScope.backgroundScope,
- lockScreenSceneInteractorFactory =
- object : LockScreenSceneInteractor.Factory {
- override fun create(containerName: String): LockScreenSceneInteractor {
+ lockscreenSceneInteractorFactory =
+ object : LockscreenSceneInteractor.Factory {
+ override fun create(containerName: String): LockscreenSceneInteractor {
return utils.lockScreenSceneInteractor(
authenticationInteractor = authenticationInteractor,
sceneInteractor = sceneInteractor,
@@ -74,7 +74,7 @@
authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
authenticationInteractor.lockDevice()
- assertThat(upTransitionSceneKey).isEqualTo(SceneKey.LockScreen)
+ assertThat(upTransitionSceneKey).isEqualTo(SceneKey.Lockscreen)
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
index 7f20f1e..e12d179 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
@@ -716,6 +716,94 @@
.isLessThan(px(R.dimen.heads_up_pinned_elevation))
}
+ @Test
+ fun aodToLockScreen_hasPulsingNotification_pulsingNotificationRowDoesNotChange() {
+ // Given: Before AOD to LockScreen, there was a pulsing notification
+ val pulsingNotificationView = createPulsingViewMock()
+ val algorithmState = StackScrollAlgorithm.StackScrollAlgorithmState()
+ algorithmState.visibleChildren.add(pulsingNotificationView)
+ ambientState.setPulsingRow(pulsingNotificationView)
+
+ // When: during AOD to LockScreen, any dozeAmount between (0, 1.0) is equivalent as a middle
+ // stage; here we use 0.5 for testing.
+ // stackScrollAlgorithm.updatePulsingStates is called
+ ambientState.dozeAmount = 0.5f
+ stackScrollAlgorithm.updatePulsingStates(algorithmState, ambientState)
+
+ // Then: ambientState.pulsingRow should still be pulsingNotificationView
+ assertTrue(ambientState.isPulsingRow(pulsingNotificationView))
+ }
+
+ @Test
+ fun deviceOnAod_hasPulsingNotification_recordPulsingNotificationRow() {
+ // Given: Device is on AOD, there is a pulsing notification
+ // ambientState.pulsingRow is null before stackScrollAlgorithm.updatePulsingStates
+ ambientState.dozeAmount = 1.0f
+ val pulsingNotificationView = createPulsingViewMock()
+ val algorithmState = StackScrollAlgorithm.StackScrollAlgorithmState()
+ algorithmState.visibleChildren.add(pulsingNotificationView)
+ ambientState.setPulsingRow(null)
+
+ // When: stackScrollAlgorithm.updatePulsingStates is called
+ stackScrollAlgorithm.updatePulsingStates(algorithmState, ambientState)
+
+ // Then: ambientState.pulsingRow should record the pulsingNotificationView
+ assertTrue(ambientState.isPulsingRow(pulsingNotificationView))
+ }
+
+ @Test
+ fun deviceOnLockScreen_hasPulsingNotificationBefore_clearPulsingNotificationRowRecord() {
+ // Given: Device finished AOD to LockScreen, there was a pulsing notification, and
+ // ambientState.pulsingRow was not null before AOD to LockScreen
+ // pulsingNotificationView.showingPulsing() returns false since the device is on LockScreen
+ ambientState.dozeAmount = 0.0f
+ val pulsingNotificationView = createPulsingViewMock()
+ whenever(pulsingNotificationView.showingPulsing()).thenReturn(false)
+ val algorithmState = StackScrollAlgorithm.StackScrollAlgorithmState()
+ algorithmState.visibleChildren.add(pulsingNotificationView)
+ ambientState.setPulsingRow(pulsingNotificationView)
+
+ // When: stackScrollAlgorithm.updatePulsingStates is called
+ stackScrollAlgorithm.updatePulsingStates(algorithmState, ambientState)
+
+ // Then: ambientState.pulsingRow should be null
+ assertTrue(ambientState.isPulsingRow(null))
+ }
+
+ @Test
+ fun aodToLockScreen_hasPulsingNotification_pulsingNotificationRowShowAtFullHeight() {
+ // Given: Before AOD to LockScreen, there was a pulsing notification
+ val pulsingNotificationView = createPulsingViewMock()
+ val algorithmState = StackScrollAlgorithm.StackScrollAlgorithmState()
+ algorithmState.visibleChildren.add(pulsingNotificationView)
+ ambientState.setPulsingRow(pulsingNotificationView)
+
+ // When: during AOD to LockScreen, any dozeAmount between (0, 1.0) is equivalent as a middle
+ // stage; here we use 0.5 for testing. The expansionFraction is also 0.5.
+ // stackScrollAlgorithm.resetViewStates is called.
+ ambientState.dozeAmount = 0.5f
+ setExpansionFractionWithoutShelfDuringAodToLockScreen(
+ ambientState,
+ algorithmState,
+ fraction = 0.5f
+ )
+ stackScrollAlgorithm.resetViewStates(ambientState, 0)
+
+ // Then: pulsingNotificationView should show at full height
+ assertEquals(
+ stackScrollAlgorithm.getMaxAllowedChildHeight(pulsingNotificationView),
+ pulsingNotificationView.viewState.height
+ )
+
+ // After: reset dozeAmount and expansionFraction
+ ambientState.dozeAmount = 0f
+ setExpansionFractionWithoutShelfDuringAodToLockScreen(
+ ambientState,
+ algorithmState,
+ fraction = 1f
+ )
+ }
+
private fun createHunViewMock(
isShadeOpen: Boolean,
fullyVisible: Boolean,
@@ -744,6 +832,29 @@
headsUpIsVisible = fullyVisible
}
+ private fun createPulsingViewMock(
+ ) =
+ mock<ExpandableNotificationRow>().apply {
+ whenever(this.viewState).thenReturn(ExpandableViewState())
+ whenever(this.showingPulsing()).thenReturn(true)
+ }
+
+ private fun setExpansionFractionWithoutShelfDuringAodToLockScreen(
+ ambientState: AmbientState,
+ algorithmState: StackScrollAlgorithm.StackScrollAlgorithmState,
+ fraction: Float
+ ) {
+ // showingShelf: false
+ algorithmState.firstViewInShelf = null
+ // scrimPadding: 0, because device is on lock screen
+ ambientState.setStatusBarState(StatusBarState.KEYGUARD)
+ ambientState.dozeAmount = 0.0f
+ // set stackEndHeight and stackHeight
+ // ExpansionFractionWithoutShelf == stackHeight / stackEndHeight
+ ambientState.stackEndHeight = 100f
+ ambientState.stackHeight = ambientState.stackEndHeight * fraction
+ }
+
private fun resetViewStates_expansionChanging_notificationAlphaUpdated(
expansionFraction: Float,
expectedAlpha: Float,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
index c83769d..cf6d5b5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
@@ -335,6 +335,7 @@
private final FakeFeatureFlags mFeatureFlags = new FakeFeatureFlags();
private final InitController mInitController = new InitController();
private final DumpManager mDumpManager = new DumpManager();
+ private final ScreenLifecycle mScreenLifecycle = new ScreenLifecycle(mDumpManager);
@Before
public void setup() throws Exception {
@@ -487,7 +488,7 @@
mUserSwitcherController,
mBatteryController,
mColorExtractor,
- new ScreenLifecycle(mDumpManager),
+ mScreenLifecycle,
mWakefulnessLifecycle,
mStatusBarStateController,
Optional.of(mBubbles),
@@ -554,6 +555,7 @@
return mViewRootImpl;
}
};
+ mScreenLifecycle.addObserver(mCentralSurfaces.mScreenObserver);
mCentralSurfaces.initShadeVisibilityListener();
when(mViewRootImpl.getOnBackInvokedDispatcher())
.thenReturn(mOnBackInvokedDispatcher);
@@ -1253,6 +1255,32 @@
}
@Test
+ public void deviceStateChange_unfolded_shadeExpanding_onKeyguard_closesQS() {
+ setFoldedStates(FOLD_STATE_FOLDED);
+ setGoToSleepStates(FOLD_STATE_FOLDED);
+ mCentralSurfaces.setBarStateForTest(KEYGUARD);
+ when(mNotificationPanelViewController.isExpandingOrCollapsing()).thenReturn(true);
+
+ setDeviceState(FOLD_STATE_UNFOLDED);
+ mScreenLifecycle.dispatchScreenTurnedOff();
+
+ verify(mQuickSettingsController).closeQs();
+ }
+
+ @Test
+ public void deviceStateChange_unfolded_shadeExpanded_onKeyguard_closesQS() {
+ setFoldedStates(FOLD_STATE_FOLDED);
+ setGoToSleepStates(FOLD_STATE_FOLDED);
+ mCentralSurfaces.setBarStateForTest(KEYGUARD);
+ when(mNotificationPanelViewController.isShadeFullyExpanded()).thenReturn(true);
+
+ setDeviceState(FOLD_STATE_UNFOLDED);
+ mScreenLifecycle.dispatchScreenTurnedOff();
+
+ verify(mQuickSettingsController).closeQs();
+ }
+
+ @Test
public void startActivityDismissingKeyguard_isShowingAndIsOccluded() {
when(mKeyguardStateController.isShowing()).thenReturn(true);
when(mKeyguardStateController.isOccluded()).thenReturn(true);
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneTestUtils.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneTestUtils.kt
index 5a350bb..be3d54a 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneTestUtils.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneTestUtils.kt
@@ -23,7 +23,7 @@
import com.android.systemui.bouncer.data.repo.BouncerRepository
import com.android.systemui.bouncer.domain.interactor.BouncerInteractor
import com.android.systemui.bouncer.ui.viewmodel.BouncerViewModel
-import com.android.systemui.keyguard.domain.interactor.LockScreenSceneInteractor
+import com.android.systemui.keyguard.domain.interactor.LockscreenSceneInteractor
import com.android.systemui.scene.data.model.SceneContainerConfig
import com.android.systemui.scene.data.repository.SceneContainerRepository
import com.android.systemui.scene.domain.interactor.SceneInteractor
@@ -58,7 +58,7 @@
return listOf(
SceneKey.QuickSettings,
SceneKey.Shade,
- SceneKey.LockScreen,
+ SceneKey.Lockscreen,
SceneKey.Bouncer,
SceneKey.Gone,
)
@@ -71,7 +71,7 @@
return SceneContainerConfig(
name = name,
sceneKeys = sceneKeys,
- initialSceneKey = SceneKey.LockScreen,
+ initialSceneKey = SceneKey.Lockscreen,
)
}
@@ -139,8 +139,8 @@
authenticationInteractor: AuthenticationInteractor,
sceneInteractor: SceneInteractor,
bouncerInteractor: BouncerInteractor,
- ): LockScreenSceneInteractor {
- return LockScreenSceneInteractor(
+ ): LockscreenSceneInteractor {
+ return LockscreenSceneInteractor(
applicationScope = applicationScope(),
authenticationInteractor = authenticationInteractor,
bouncerInteractorFactory =
diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
index 71401f4..f4c9d05 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
@@ -209,6 +209,7 @@
private void init() {
setupMessaging(mContext);
+ initAudioHalBluetoothState();
initRoutingStrategyIds();
mPreferredCommunicationDevice = null;
updateActiveCommunicationDevice();
@@ -864,21 +865,174 @@
}
}
- /**
- * Current Bluetooth SCO audio active state indicated by BtHelper via setBluetoothScoOn().
- */
+ // Lock protecting state variable related to Bluetooth audio state
+ private final Object mBluetoothAudioStateLock = new Object();
+
+ // Current Bluetooth SCO audio active state indicated by BtHelper via setBluetoothScoOn().
+ @GuardedBy("mBluetoothAudioStateLock")
private boolean mBluetoothScoOn;
+ // value of BT_SCO parameter currently applied to audio HAL.
+ @GuardedBy("mBluetoothAudioStateLock")
+ private boolean mBluetoothScoOnApplied;
+
+ // A2DP suspend state requested by AudioManager.setA2dpSuspended() API.
+ @GuardedBy("mBluetoothAudioStateLock")
+ private boolean mBluetoothA2dpSuspendedExt;
+ // A2DP suspend state requested by AudioDeviceInventory.
+ @GuardedBy("mBluetoothAudioStateLock")
+ private boolean mBluetoothA2dpSuspendedInt;
+ // value of BT_A2dpSuspendedSCO parameter currently applied to audio HAL.
+
+ @GuardedBy("mBluetoothAudioStateLock")
+ private boolean mBluetoothA2dpSuspendedApplied;
+
+ // LE Audio suspend state requested by AudioManager.setLeAudioSuspended() API.
+ @GuardedBy("mBluetoothAudioStateLock")
+ private boolean mBluetoothLeSuspendedExt;
+ // LE Audio suspend state requested by AudioDeviceInventory.
+ @GuardedBy("mBluetoothAudioStateLock")
+ private boolean mBluetoothLeSuspendedInt;
+ // value of LeAudioSuspended parameter currently applied to audio HAL.
+ @GuardedBy("mBluetoothAudioStateLock")
+ private boolean mBluetoothLeSuspendedApplied;
+
+ private void initAudioHalBluetoothState() {
+ synchronized (mBluetoothAudioStateLock) {
+ mBluetoothScoOnApplied = false;
+ AudioSystem.setParameters("BT_SCO=off");
+ mBluetoothA2dpSuspendedApplied = false;
+ AudioSystem.setParameters("A2dpSuspended=false");
+ mBluetoothLeSuspendedApplied = false;
+ AudioSystem.setParameters("LeAudioSuspended=false");
+ }
+ }
+
+ @GuardedBy("mBluetoothAudioStateLock")
+ private void updateAudioHalBluetoothState() {
+ if (mBluetoothScoOn != mBluetoothScoOnApplied) {
+ if (AudioService.DEBUG_COMM_RTE) {
+ Log.v(TAG, "updateAudioHalBluetoothState() mBluetoothScoOn: "
+ + mBluetoothScoOn + ", mBluetoothScoOnApplied: " + mBluetoothScoOnApplied);
+ }
+ if (mBluetoothScoOn) {
+ if (!mBluetoothA2dpSuspendedApplied) {
+ AudioSystem.setParameters("A2dpSuspended=true");
+ mBluetoothA2dpSuspendedApplied = true;
+ }
+ if (!mBluetoothLeSuspendedApplied) {
+ AudioSystem.setParameters("LeAudioSuspended=true");
+ mBluetoothLeSuspendedApplied = true;
+ }
+ AudioSystem.setParameters("BT_SCO=on");
+ } else {
+ AudioSystem.setParameters("BT_SCO=off");
+ }
+ mBluetoothScoOnApplied = mBluetoothScoOn;
+ }
+ if (!mBluetoothScoOnApplied) {
+ if ((mBluetoothA2dpSuspendedExt || mBluetoothA2dpSuspendedInt)
+ != mBluetoothA2dpSuspendedApplied) {
+ if (AudioService.DEBUG_COMM_RTE) {
+ Log.v(TAG, "updateAudioHalBluetoothState() mBluetoothA2dpSuspendedExt: "
+ + mBluetoothA2dpSuspendedExt
+ + ", mBluetoothA2dpSuspendedInt: " + mBluetoothA2dpSuspendedInt
+ + ", mBluetoothA2dpSuspendedApplied: "
+ + mBluetoothA2dpSuspendedApplied);
+ }
+ mBluetoothA2dpSuspendedApplied =
+ mBluetoothA2dpSuspendedExt || mBluetoothA2dpSuspendedInt;
+ if (mBluetoothA2dpSuspendedApplied) {
+ AudioSystem.setParameters("A2dpSuspended=true");
+ } else {
+ AudioSystem.setParameters("A2dpSuspended=false");
+ }
+ }
+ if ((mBluetoothLeSuspendedExt || mBluetoothLeSuspendedInt)
+ != mBluetoothLeSuspendedApplied) {
+ if (AudioService.DEBUG_COMM_RTE) {
+ Log.v(TAG, "updateAudioHalBluetoothState() mBluetoothLeSuspendedExt: "
+ + mBluetoothLeSuspendedExt
+ + ", mBluetoothLeSuspendedInt: " + mBluetoothLeSuspendedInt
+ + ", mBluetoothLeSuspendedApplied: " + mBluetoothLeSuspendedApplied);
+ }
+ mBluetoothLeSuspendedApplied =
+ mBluetoothLeSuspendedExt || mBluetoothLeSuspendedInt;
+ if (mBluetoothLeSuspendedApplied) {
+ AudioSystem.setParameters("LeAudioSuspended=true");
+ } else {
+ AudioSystem.setParameters("LeAudioSuspended=false");
+ }
+ }
+ }
+ }
/*package*/ void setBluetoothScoOn(boolean on, String eventSource) {
if (AudioService.DEBUG_COMM_RTE) {
Log.v(TAG, "setBluetoothScoOn: " + on + " " + eventSource);
}
- synchronized (mDeviceStateLock) {
+ synchronized (mBluetoothAudioStateLock) {
mBluetoothScoOn = on;
+ updateAudioHalBluetoothState();
postUpdateCommunicationRouteClient(eventSource);
}
}
+ /*package*/ void setA2dpSuspended(boolean enable, boolean internal, String eventSource) {
+ synchronized (mBluetoothAudioStateLock) {
+ if (AudioService.DEBUG_COMM_RTE) {
+ Log.v(TAG, "setA2dpSuspended source: " + eventSource + ", enable: "
+ + enable + ", internal: " + internal
+ + ", mBluetoothA2dpSuspendedInt: " + mBluetoothA2dpSuspendedInt
+ + ", mBluetoothA2dpSuspendedExt: " + mBluetoothA2dpSuspendedExt);
+ }
+ if (internal) {
+ mBluetoothA2dpSuspendedInt = enable;
+ } else {
+ mBluetoothA2dpSuspendedExt = enable;
+ }
+ updateAudioHalBluetoothState();
+ }
+ }
+
+ /*package*/ void clearA2dpSuspended() {
+ if (AudioService.DEBUG_COMM_RTE) {
+ Log.v(TAG, "clearA2dpSuspended");
+ }
+ synchronized (mBluetoothAudioStateLock) {
+ mBluetoothA2dpSuspendedInt = false;
+ mBluetoothA2dpSuspendedExt = false;
+ updateAudioHalBluetoothState();
+ }
+ }
+
+ /*package*/ void setLeAudioSuspended(boolean enable, boolean internal, String eventSource) {
+ synchronized (mBluetoothAudioStateLock) {
+ if (AudioService.DEBUG_COMM_RTE) {
+ Log.v(TAG, "setLeAudioSuspended source: " + eventSource + ", enable: "
+ + enable + ", internal: " + internal
+ + ", mBluetoothLeSuspendedInt: " + mBluetoothA2dpSuspendedInt
+ + ", mBluetoothLeSuspendedExt: " + mBluetoothA2dpSuspendedExt);
+ }
+ if (internal) {
+ mBluetoothLeSuspendedInt = enable;
+ } else {
+ mBluetoothLeSuspendedExt = enable;
+ }
+ updateAudioHalBluetoothState();
+ }
+ }
+
+ /*package*/ void clearLeAudioSuspended() {
+ if (AudioService.DEBUG_COMM_RTE) {
+ Log.v(TAG, "clearLeAudioSuspended");
+ }
+ synchronized (mBluetoothAudioStateLock) {
+ mBluetoothLeSuspendedInt = false;
+ mBluetoothLeSuspendedExt = false;
+ updateAudioHalBluetoothState();
+ }
+ }
+
/*package*/ AudioRoutesInfo startWatchingRoutes(IAudioRoutesObserver observer) {
synchronized (mDeviceStateLock) {
return mDeviceInventory.startWatchingRoutes(observer);
@@ -1985,7 +2139,11 @@
*/
@GuardedBy("mDeviceStateLock")
@Nullable private AudioDeviceAttributes preferredCommunicationDevice() {
- boolean btSCoOn = mBluetoothScoOn && mBtHelper.isBluetoothScoOn();
+ boolean btSCoOn = mBtHelper.isBluetoothScoOn();
+ synchronized (mBluetoothAudioStateLock) {
+ btSCoOn = btSCoOn && mBluetoothScoOn;
+ }
+
if (btSCoOn) {
// Use the SCO device known to BtHelper so that it matches exactly
// what has been communicated to audio policy manager. The device
@@ -2020,12 +2178,6 @@
"updateCommunicationRoute, preferredCommunicationDevice: "
+ preferredCommunicationDevice + " eventSource: " + eventSource)));
- if (preferredCommunicationDevice == null
- || preferredCommunicationDevice.getType() != AudioDeviceInfo.TYPE_BLUETOOTH_SCO) {
- AudioSystem.setParameters("BT_SCO=off");
- } else {
- AudioSystem.setParameters("BT_SCO=on");
- }
if (preferredCommunicationDevice == null) {
AudioDeviceAttributes defaultDevice = getDefaultCommunicationDevice();
if (defaultDevice != null) {
diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
index 58c7326..a561612 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
@@ -1479,7 +1479,7 @@
}
// Reset A2DP suspend state each time a new sink is connected
- mAudioSystem.setParameters("A2dpSuspended=false");
+ mDeviceBroker.clearA2dpSuspended();
// The convention for head tracking sensors associated with A2DP devices is to
// use a UUID derived from the MAC address as follows:
@@ -1752,7 +1752,8 @@
private void makeA2dpDeviceUnavailableLater(String address, int delayMs) {
// prevent any activity on the A2DP audio output to avoid unwanted
// reconnection of the sink.
- mAudioSystem.setParameters("A2dpSuspended=true");
+ mDeviceBroker.setA2dpSuspended(
+ true /*enable*/, true /*internal*/, "makeA2dpDeviceUnavailableLater");
// retrieve DeviceInfo before removing device
final String deviceKey =
DeviceInfo.makeDeviceListKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, address);
@@ -1899,7 +1900,7 @@
"LE Audio device addr=" + address + " now available").printLog(TAG));
}
// Reset LEA suspend state each time a new sink is connected
- mAudioSystem.setParameters("LeAudioSuspended=false");
+ mDeviceBroker.clearLeAudioSuspended();
UUID sensorUuid = UuidUtils.uuidFromAudioDeviceAttributes(ada);
mConnectedDevices.put(DeviceInfo.makeDeviceListKey(device, address),
@@ -1954,7 +1955,8 @@
private void makeLeAudioDeviceUnavailableLater(String address, int device, int delayMs) {
// prevent any activity on the LEA output to avoid unwanted
// reconnection of the sink.
- mAudioSystem.setParameters("LeAudioSuspended=true");
+ mDeviceBroker.setLeAudioSuspended(
+ true /*enable*/, true /*internal*/, "makeLeAudioDeviceUnavailableLater");
// the device will be made unavailable later, so consider it disconnected right away
mConnectedDevices.remove(DeviceInfo.makeDeviceListKey(device, address));
// send the delayed message to make the device unavailable later
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 86b5235..355981a 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -6424,6 +6424,26 @@
mDeviceBroker.setBluetoothScoOn(on, eventSource);
}
+ /** @see AudioManager#setA2dpSuspended(boolean) */
+ @android.annotation.EnforcePermission(android.Manifest.permission.BLUETOOTH_STACK)
+ public void setA2dpSuspended(boolean enable) {
+ super.setA2dpSuspended_enforcePermission();
+ final String eventSource = new StringBuilder("setA2dpSuspended(").append(enable)
+ .append(") from u/pid:").append(Binder.getCallingUid()).append("/")
+ .append(Binder.getCallingPid()).toString();
+ mDeviceBroker.setA2dpSuspended(enable, false /*internal*/, eventSource);
+ }
+
+ /** @see AudioManager#setA2dpSuspended(boolean) */
+ @android.annotation.EnforcePermission(android.Manifest.permission.BLUETOOTH_STACK)
+ public void setLeAudioSuspended(boolean enable) {
+ super.setLeAudioSuspended_enforcePermission();
+ final String eventSource = new StringBuilder("setLeAudioSuspended(").append(enable)
+ .append(") from u/pid:").append(Binder.getCallingUid()).append("/")
+ .append(Binder.getCallingPid()).toString();
+ mDeviceBroker.setLeAudioSuspended(enable, false /*internal*/, eventSource);
+ }
+
/** @see AudioManager#isBluetoothScoOn()
* Note that it doesn't report internal state, but state seen by apps (which may have
* called setBluetoothScoOn() */
diff --git a/services/core/java/com/android/server/audio/BtHelper.java b/services/core/java/com/android/server/audio/BtHelper.java
index bfa6c36e..e46c3cc 100644
--- a/services/core/java/com/android/server/audio/BtHelper.java
+++ b/services/core/java/com/android/server/audio/BtHelper.java
@@ -445,8 +445,8 @@
/*package*/ synchronized void resetBluetoothSco() {
mScoAudioState = SCO_STATE_INACTIVE;
broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_DISCONNECTED);
- AudioSystem.setParameters("A2dpSuspended=false");
- AudioSystem.setParameters("LeAudioSuspended=false");
+ mDeviceBroker.clearA2dpSuspended();
+ mDeviceBroker.clearLeAudioSuspended();
mDeviceBroker.setBluetoothScoOn(false, "resetBluetoothSco");
}
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
index f37ad5e..ca1abd6 100755
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
@@ -1013,11 +1013,10 @@
}
@ServiceThreadOnly
- void addAvbAudioStatusAction(int targetAddress) {
+ void startNewAvbAudioStatusAction(int targetAddress) {
assertRunOnServiceThread();
- if (!hasAction(AbsoluteVolumeAudioStatusAction.class)) {
- addAndStartAction(new AbsoluteVolumeAudioStatusAction(this, targetAddress));
- }
+ removeAction(AbsoluteVolumeAudioStatusAction.class);
+ addAndStartAction(new AbsoluteVolumeAudioStatusAction(this, targetAddress));
}
@ServiceThreadOnly
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index e87ed0a..cede273 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -4341,12 +4341,9 @@
switch (systemAudioDeviceInfo.getDeviceFeatures().getSetAudioVolumeLevelSupport()) {
case DeviceFeatures.FEATURE_SUPPORTED:
if (currentVolumeBehavior != AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE) {
- // If we're currently using adjust-only absolute volume behavior, switch to
- // full volume behavior until we successfully adopt absolute volume behavior
- switchToFullVolumeBehavior();
// Start an action that will call enableAbsoluteVolumeBehavior
// once the System Audio device sends <Report Audio Status>
- localCecDevice.addAvbAudioStatusAction(
+ localCecDevice.startNewAvbAudioStatusAction(
systemAudioDeviceInfo.getLogicalAddress());
}
return;
@@ -4358,10 +4355,13 @@
!= AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY) {
// If we're currently using absolute volume behavior, switch to full volume
// behavior until we successfully adopt adjust-only absolute volume behavior
- switchToFullVolumeBehavior();
+ if (currentVolumeBehavior == AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE) {
+ getAudioManager().setDeviceVolumeBehavior(getAvbAudioOutputDevice(),
+ AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL);
+ }
// Start an action that will call enableAbsoluteVolumeBehavior
// once the System Audio device sends <Report Audio Status>
- localCecDevice.addAvbAudioStatusAction(
+ localCecDevice.startNewAvbAudioStatusAction(
systemAudioDeviceInfo.getLogicalAddress());
}
} else {
@@ -4369,7 +4369,9 @@
}
return;
case DeviceFeatures.FEATURE_SUPPORT_UNKNOWN:
- switchToFullVolumeBehavior();
+ if (currentVolumeBehavior == AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE) {
+ switchToFullVolumeBehavior();
+ }
localCecDevice.querySetAudioVolumeLevelSupport(
systemAudioDeviceInfo.getLogicalAddress());
}
diff --git a/services/core/java/com/android/server/pm/NoFilteringResolver.java b/services/core/java/com/android/server/pm/NoFilteringResolver.java
index ccd5b0e..b87256d 100644
--- a/services/core/java/com/android/server/pm/NoFilteringResolver.java
+++ b/services/core/java/com/android/server/pm/NoFilteringResolver.java
@@ -60,15 +60,9 @@
public static boolean isIntentRedirectionAllowed(Context context,
AppCloningDeviceConfigHelper appCloningDeviceConfigHelper, boolean resolveForStart,
long flags) {
- final long token = Binder.clearCallingIdentity();
- try {
- return context.getResources().getBoolean(R.bool.config_enableAppCloningBuildingBlocks)
- && appCloningDeviceConfigHelper.getEnableAppCloningBuildingBlocks()
+ return isAppCloningBuildingBlocksEnabled(context, appCloningDeviceConfigHelper)
&& (resolveForStart || (((flags & PackageManager.MATCH_CLONE_PROFILE) != 0)
&& hasPermission(context, Manifest.permission.QUERY_CLONED_APPS)));
- } finally {
- Binder.restoreCallingIdentity(token);
- }
}
public NoFilteringResolver(ComponentResolverApi componentResolver,
@@ -146,4 +140,18 @@
return context.checkCallingOrSelfPermission(permission)
== PackageManager.PERMISSION_GRANTED;
}
+
+ /**
+ * Checks if the AppCloningBuildingBlocks flag is enabled.
+ */
+ private static boolean isAppCloningBuildingBlocksEnabled(Context context,
+ AppCloningDeviceConfigHelper appCloningDeviceConfigHelper) {
+ final long token = Binder.clearCallingIdentity();
+ try {
+ return context.getResources().getBoolean(R.bool.config_enableAppCloningBuildingBlocks)
+ && appCloningDeviceConfigHelper.getEnableAppCloningBuildingBlocks();
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
}
diff --git a/services/core/java/com/android/server/policy/AppOpsPolicy.java b/services/core/java/com/android/server/policy/AppOpsPolicy.java
index 7a5664f..2cbe8db 100644
--- a/services/core/java/com/android/server/policy/AppOpsPolicy.java
+++ b/services/core/java/com/android/server/policy/AppOpsPolicy.java
@@ -37,6 +37,7 @@
import android.os.IBinder;
import android.os.PackageTagsList;
import android.os.Process;
+import android.os.SystemProperties;
import android.os.UserHandle;
import android.service.voice.VoiceInteractionManagerInternal;
import android.service.voice.VoiceInteractionManagerInternal.HotwordDetectionServiceIdentity;
@@ -68,6 +69,8 @@
private static final String ACTIVITY_RECOGNITION_TAGS =
"android:activity_recognition_allow_listed_tags";
private static final String ACTIVITY_RECOGNITION_TAGS_SEPARATOR = ";";
+ private static final boolean SYSPROP_HOTWORD_DETECTION_SERVICE_REQUIRED =
+ SystemProperties.getBoolean("ro.hotword.detection_service_required", false);
@NonNull
private final Object mLock = new Object();
@@ -201,8 +204,11 @@
private static boolean isHotwordDetectionServiceRequired(PackageManager pm) {
// The HotwordDetectionService APIs aren't ready yet for Auto or TV.
- return !(pm.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)
- || pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK));
+ if (pm.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)
+ || pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK)) {
+ return false;
+ }
+ return SYSPROP_HOTWORD_DETECTION_SERVICE_REQUIRED;
}
@Override
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 7a43728..9add537 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -3987,6 +3987,8 @@
if (mFallbackWallpaper != null) {
dumpWallpaper(mFallbackWallpaper, pw);
}
+ pw.print("mIsLockscreenLiveWallpaperEnabled=");
+ pw.println(mIsLockscreenLiveWallpaperEnabled);
}
}
}
diff --git a/services/core/java/com/android/server/wm/BLASTSyncEngine.java b/services/core/java/com/android/server/wm/BLASTSyncEngine.java
index 778951a..98ee98b 100644
--- a/services/core/java/com/android/server/wm/BLASTSyncEngine.java
+++ b/services/core/java/com/android/server/wm/BLASTSyncEngine.java
@@ -248,7 +248,10 @@
Slog.e(TAG, "WM sent Transaction to organized, but never received" +
" commit callback. Application ANR likely to follow.");
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
- onCommitted(merged);
+ synchronized (mWm.mGlobalLock) {
+ onCommitted(merged.mNativeObject != 0
+ ? merged : mWm.mTransactionFactory.get());
+ }
}
};
CommitCallback callback = new CommitCallback();
diff --git a/services/core/java/com/android/server/wm/ContentRecordingController.java b/services/core/java/com/android/server/wm/ContentRecordingController.java
index 040da88..4da55e2 100644
--- a/services/core/java/com/android/server/wm/ContentRecordingController.java
+++ b/services/core/java/com/android/server/wm/ContentRecordingController.java
@@ -98,6 +98,13 @@
mSession == null ? null : mSession.getVirtualDisplayId());
incomingDisplayContent = wmService.mRoot.getDisplayContentOrCreate(
incomingSession.getVirtualDisplayId());
+ if (incomingDisplayContent == null) {
+ ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
+ "Content Recording: Incoming session on display %d can't be set since it "
+ + "is already null; the corresponding VirtualDisplay must have "
+ + "already been removed.", incomingSession.getVirtualDisplayId());
+ return;
+ }
incomingDisplayContent.setContentRecordingSession(incomingSession);
// TODO(b/270118861): When user grants consent to re-use, explicitly ask ContentRecorder
// to update, since no config/display change arrives. Mark recording as black.