Skip to content

Commit c6f10ef

Browse files
committed
Login related customization.
NMC-3250 -> opening login flow in internal webview instead of external browser. NMC-1885: Splash screen customized NMC-571 -- removed usesCleartextTraffic from Manifest. NMC-3773 -- close app on access denied error comes NMC-3964 -- fix app crash on logout for Xiaomi Android 15 devices NMC-3936 & NMC-3813 -- Enabled edge-to-edge for Api level 35. NMC-4351 -- fix redirection to login screen on timeout NMC-4743 -- fix logout crash from trashbin tab
1 parent 022f9c2 commit c6f10ef

File tree

14 files changed

+217
-337
lines changed

14 files changed

+217
-337
lines changed

app/src/androidTest/java/com/nmc/android/ui/LauncherActivityIT.kt

Lines changed: 13 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -6,72 +6,33 @@
66
*/
77
package com.nmc.android.ui
88

9-
import androidx.annotation.UiThread
10-
import androidx.test.core.app.launchActivity
119
import androidx.test.espresso.Espresso.onView
12-
import androidx.test.espresso.IdlingRegistry
1310
import androidx.test.espresso.assertion.ViewAssertions.matches
14-
import androidx.test.espresso.matcher.ViewMatchers
1511
import androidx.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed
16-
import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility
1712
import androidx.test.espresso.matcher.ViewMatchers.withId
13+
import androidx.test.espresso.matcher.ViewMatchers.withText
14+
import androidx.test.ext.junit.rules.ActivityScenarioRule
1815
import androidx.test.ext.junit.runners.AndroidJUnit4
1916
import com.owncloud.android.AbstractIT
2017
import com.owncloud.android.R
21-
import com.owncloud.android.utils.EspressoIdlingResource
22-
import org.junit.After
23-
import org.junit.Before
18+
import org.junit.Rule
2419
import org.junit.Test
2520
import org.junit.runner.RunWith
2621

2722
@RunWith(AndroidJUnit4::class)
2823
class LauncherActivityIT : AbstractIT() {
2924

30-
@Before
31-
fun registerIdlingResource() {
32-
IdlingRegistry.getInstance().register(EspressoIdlingResource.countingIdlingResource)
33-
}
34-
35-
@After
36-
fun unregisterIdlingResource() {
37-
IdlingRegistry.getInstance().unregister(EspressoIdlingResource.countingIdlingResource)
38-
}
39-
40-
@Test
41-
@UiThread
42-
fun testSplashScreenWithEmptyTitlesShouldHideTitles() {
43-
launchActivity<LauncherActivity>().use { scenario ->
44-
scenario.onActivity { _ ->
45-
onIdleSync {
46-
onView(withId(R.id.ivSplash)).check(matches(isCompletelyDisplayed()))
47-
onView(
48-
withId(R.id.splashScreenBold)
49-
).check(matches(withEffectiveVisibility(ViewMatchers.Visibility.GONE)))
50-
onView(
51-
withId(R.id.splashScreenNormal)
52-
).check(matches(withEffectiveVisibility(ViewMatchers.Visibility.GONE)))
53-
}
54-
}
55-
}
56-
}
25+
@get:Rule
26+
val activityRule = ActivityScenarioRule(LauncherActivity::class.java)
5727

5828
@Test
59-
@UiThread
60-
fun testSplashScreenWithTitlesShouldShowTitles() {
61-
launchActivity<LauncherActivity>().use { scenario ->
62-
scenario.onActivity {
63-
onIdleSync {
64-
onView(withId(R.id.ivSplash)).check(matches(isCompletelyDisplayed()))
65-
66-
EspressoIdlingResource.increment()
67-
it.setSplashTitles("Example", "Cloud")
68-
EspressoIdlingResource.decrement()
69-
70-
val onePercentArea = ViewMatchers.isDisplayingAtLeast(1)
71-
onView(withId(R.id.splashScreenBold)).check(matches(onePercentArea))
72-
onView(withId(R.id.splashScreenNormal)).check(matches(onePercentArea))
73-
}
74-
}
75-
}
29+
fun verifyUIElements() {
30+
onView(withId(R.id.ivSplash)).check(matches(isCompletelyDisplayed()))
31+
onView(withId(R.id.splashScreenBold)).check(matches(isCompletelyDisplayed()))
32+
onView(withId(R.id.splashScreenNormal)).check(matches(isCompletelyDisplayed()))
33+
34+
onView(withId(R.id.splashScreenBold)).check(matches(withText("Magenta")))
35+
onView(withId(R.id.splashScreenNormal)).check(matches(withText("CLOUD")))
36+
shortSleep()
7637
}
7738
}

app/src/debug/res/values/setup.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<resources>
3+
<!-- webview_login_url should be empty in debug mode to show login url input screen
4+
this will be useful in switching the environments during testing -->
5+
<string name="webview_login_url" translatable="false" />
6+
</resources>

app/src/main/AndroidManifest.xml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,6 @@
123123
android:supportsRtl="true"
124124
android:enableOnBackInvokedCallback="false"
125125
android:theme="@style/Theme.ownCloud.Toolbar"
126-
android:usesCleartextTraffic="true"
127126
tools:ignore="UnusedAttribute"
128127
tools:replace="android:allowBackup">
129128

app/src/main/java/com/owncloud/android/MainApp.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import android.os.StrictMode;
3838
import android.text.TextUtils;
3939
import android.view.WindowManager;
40+
import android.webkit.WebView;
4041

4142
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
4243
import com.nextcloud.appReview.InAppReviewHelper;
@@ -384,6 +385,8 @@ public void onCreate() {
384385
networkChangeReceiver = new NetworkChangeReceiver(this, connectivityService);
385386
registerNetworkChangeReceiver();
386387

388+
configureWebViewForMultiProcess();
389+
387390
if (!MDMConfig.INSTANCE.sendFilesSupport(this)) {
388391
disableDocumentsStorageProvider();
389392
}
@@ -399,6 +402,18 @@ public void disableDocumentsStorageProvider() {
399402
packageManager.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
400403
}
401404

405+
// NMC-3964 fix
406+
// crash was happening for Xiaomi Android 15 devices
407+
private void configureWebViewForMultiProcess(){
408+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
409+
String processName = getProcessName();
410+
if (processName != null && !processName.equals(getPackageName())) {
411+
// this ensures each process uses a unique directory, preventing conflicts.
412+
WebView.setDataDirectorySuffix(processName);
413+
}
414+
}
415+
}
416+
402417
private final LifecycleEventObserver lifecycleEventObserver = ((lifecycleOwner, event) -> {
403418
if (event == Lifecycle.Event.ON_START) {
404419
Log_OC.d(TAG, "APP IN FOREGROUND");

app/src/main/java/com/owncloud/android/authentication/AccountAuthenticatorActivity.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,15 @@
88

99
import android.accounts.AccountAuthenticatorResponse;
1010
import android.accounts.AccountManager;
11+
import android.graphics.Color;
12+
import android.os.Build;
1113
import android.os.Bundle;
1214

1315
import com.nextcloud.utils.extensions.IntentExtensionsKt;
16+
import com.nextcloud.android.common.ui.util.extensions.WindowExtensionsKt;
1417

18+
import androidx.activity.EdgeToEdge;
19+
import androidx.activity.SystemBarStyle;
1520
import androidx.appcompat.app.AppCompatActivity;
1621

1722
/*
@@ -46,6 +51,14 @@ public final void setAccountAuthenticatorResult(Bundle result) {
4651
*/
4752
@Override
4853
protected void onCreate(Bundle savedInstanceState) {
54+
// NMC-3936 and NMC-3813 fix
55+
boolean isApiLevel35OrHigher = (Build.VERSION.SDK_INT >= 35);
56+
57+
if (isApiLevel35OrHigher) {
58+
enableEdgeToEdge();
59+
WindowExtensionsKt.addSystemBarPaddings(getWindow());
60+
}
61+
4962
super.onCreate(savedInstanceState);
5063

5164
mAccountAuthenticatorResponse =
@@ -58,6 +71,11 @@ protected void onCreate(Bundle savedInstanceState) {
5871
}
5972
}
6073

74+
private void enableEdgeToEdge() {
75+
final var style = SystemBarStyle.auto(Color.TRANSPARENT, Color.TRANSPARENT);
76+
EdgeToEdge.enable(this, style, style);
77+
}
78+
6179
/**
6280
* Sends the result or a Constants.ERROR_CODE_CANCELED error if a result isn't present.
6381
*/

0 commit comments

Comments
 (0)