From 8e31b4e303b87b409bed06b0e74c957a855fd08f Mon Sep 17 00:00:00 2001 From: zHd4 <38856321+zHd4@users.noreply.github.com> Date: Sun, 16 Aug 2026 20:52:27 +0200 Subject: [PATCH 1/3] Remove requiresSession override in SecretsUpdateActivity --- .../app/notesr/activity/security/SecretsUpdateActivity.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/app/src/main/java/app/notesr/activity/security/SecretsUpdateActivity.java b/app/src/main/java/app/notesr/activity/security/SecretsUpdateActivity.java index 8003847a..a6a9d86f 100644 --- a/app/src/main/java/app/notesr/activity/security/SecretsUpdateActivity.java +++ b/app/src/main/java/app/notesr/activity/security/SecretsUpdateActivity.java @@ -42,11 +42,6 @@ protected void onCreate(Bundle savedInstanceState) { startSecretsUpdateService(); } - @Override - protected boolean requiresSession() { - return false; - } - private void startSecretsUpdateService() { AndroidServiceRegistry serviceRegistry = AndroidServiceRegistry .getInstance(getApplicationContext()); From 7344dd2a42dc9458ec7d92e13d83513320a9c98b Mon Sep 17 00:00:00 2001 From: zHd4 <38856321+zHd4@users.noreply.github.com> Date: Sun, 16 Aug 2026 20:52:50 +0200 Subject: [PATCH 2/3] Prevent showing error dialog if SecretsUpdateActivity is finishing --- .../app/notesr/activity/security/SecretsUpdateActivity.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/src/main/java/app/notesr/activity/security/SecretsUpdateActivity.java b/app/src/main/java/app/notesr/activity/security/SecretsUpdateActivity.java index a6a9d86f..2df22532 100644 --- a/app/src/main/java/app/notesr/activity/security/SecretsUpdateActivity.java +++ b/app/src/main/java/app/notesr/activity/security/SecretsUpdateActivity.java @@ -61,6 +61,12 @@ private void onSecretsUpdateComplete() { } private void onSecretsUpdateFailed() { + if (isFinishing() || isDestroyed()) { + startActivity(new Intent(getApplicationContext(), NotesListActivity.class)); + finish(); + return; + } + DialogFactory dialogFactory = new DialogFactory(this); dialogFactory.getThemedAlertDialogBuilder(R.layout.dialog_secrets_update_failed) .setTitle(R.string.error) From 761e219a1f28ab073c32ee3fcae5c9cb3c4809a1 Mon Sep 17 00:00:00 2001 From: zHd4 <38856321+zHd4@users.noreply.github.com> Date: Sun, 16 Aug 2026 20:53:07 +0200 Subject: [PATCH 3/3] Add SecretsUpdateActivityTest --- .../security/SecretsUpdateActivityTest.java | 107 ++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 app/src/androidTest/java/app/notesr/activity/security/SecretsUpdateActivityTest.java diff --git a/app/src/androidTest/java/app/notesr/activity/security/SecretsUpdateActivityTest.java b/app/src/androidTest/java/app/notesr/activity/security/SecretsUpdateActivityTest.java new file mode 100644 index 00000000..3e0008d9 --- /dev/null +++ b/app/src/androidTest/java/app/notesr/activity/security/SecretsUpdateActivityTest.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2026 zHd4 + * SPDX-License-Identifier: MIT + */ + +package app.notesr.activity.security; + +import static org.junit.Assert.assertNotNull; + +import android.app.Activity; +import android.app.Instrumentation; +import android.content.Context; +import android.content.Intent; + +import androidx.localbroadcastmanager.content.LocalBroadcastManager; +import androidx.test.core.app.ActivityScenario; +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import app.notesr.activity.note.list.NotesListActivity; +import app.notesr.service.security.rotation.SecretsUpdateAndroidService; +import app.notesr.core.security.SecretCache; +import app.notesr.service.AndroidServiceRegistry; +import app.notesr.service.AndroidServiceEntry; +import app.notesr.service.security.rotation.SecretsUpdateAndroidServiceStarter; + +@RunWith(AndroidJUnit4.class) +public class SecretsUpdateActivityTest { + + private Context context; + private Instrumentation instrumentation; + + @Before + public void setUp() { + instrumentation = InstrumentationRegistry.getInstrumentation(); + context = instrumentation.getTargetContext(); + + instrumentation.getUiAutomation().adoptShellPermissionIdentity(); + + AndroidServiceRegistry registry = AndroidServiceRegistry.getInstance(context); + AndroidServiceEntry entry = AndroidServiceEntry.builder() + .serviceName(SecretsUpdateAndroidService.class.getSimpleName()) + .serviceClass(SecretsUpdateAndroidService.class) + .starterClass(SecretsUpdateAndroidServiceStarter.class) + .autoStart(true) + .requiresAuth(true) + .build(); + + registry.register(entry); + } + + @After + public void tearDown() { + AndroidServiceRegistry.getInstance(context).unregister(SecretsUpdateAndroidService.class); + SecretCache.clear(); + } + + @Test + public void secretsUpdateCompleteNavigatesToNotesListAndFinishes() { + ActivityScenario scenario = + ActivityScenario.launch(SecretsUpdateActivity.class); + + try (scenario) { + Instrumentation.ActivityMonitor monitor = instrumentation.addMonitor( + NotesListActivity.class.getName(), null, false); + + Intent intent = new Intent(SecretsUpdateAndroidService.BROADCAST_ACTION); + intent.putExtra(SecretsUpdateAndroidService.EXTRA_COMPLETE, true); + + LocalBroadcastManager.getInstance(context) + .sendBroadcast(intent); + + Activity started = instrumentation.waitForMonitorWithTimeout(monitor, 2000); + instrumentation.removeMonitor(monitor); + + assertNotNull("NotesListActivity should be started on secrets update complete", + started); + } + } + + @Test + public void secretsUpdateFailedNavigatesToNotesListActivity() { + ActivityScenario scenario = + ActivityScenario.launch(SecretsUpdateActivity.class); + + try (scenario) { + Instrumentation.ActivityMonitor monitor = instrumentation.addMonitor( + NotesListActivity.class.getName(), null, false); + + Intent intent = new Intent(SecretsUpdateAndroidService.BROADCAST_ACTION); + intent.putExtra(SecretsUpdateAndroidService.EXTRA_FAIL, true); + + LocalBroadcastManager.getInstance(context).sendBroadcast(intent); + + Activity started = instrumentation.waitForMonitorWithTimeout(monitor, 2000); + instrumentation.removeMonitor(monitor); + + assertNotNull("NotesListActivity should be started when secrets update fails", + started); + } + } +}