Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
4 changes: 4 additions & 0 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
include:
- project: ${CI_PROJECT_PATH}
ref: ci_config
file: '.gitlab-ci.yml'
6 changes: 6 additions & 0 deletions .idea/copyright/IONOS_HiDrive_Next.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .idea/copyright/profiles_settings.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 15 additions & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ buildscript {
classpath "org.jacoco:org.jacoco.core:$jacoco_version"
classpath "org.jacoco:org.jacoco.report:$jacoco_version"
classpath "org.jacoco:org.jacoco.agent:$jacoco_version"
classpath 'com.google.gms:google-services:4.4.2'
classpath "com.google.firebase:firebase-crashlytics-gradle:3.0.2"
}
}

Expand All @@ -43,6 +45,7 @@ apply plugin: 'pmd'
apply from: "$rootProject.projectDir/jacoco.gradle"
apply plugin: 'com.github.spotbugs'
apply plugin: 'io.gitlab.arturbosch.detekt'
apply plugin: 'com.google.firebase.crashlytics'

// needed to make renovate run without shot, as shot requires Android SDK
// https://github.com/pedrovgs/Shot/issues/300
Expand All @@ -51,6 +54,9 @@ if (shotTest) {
}
apply plugin: 'com.google.devtools.ksp'

if (getGradle().getStartParameter().getTaskRequests().toString().contains("Gplay")){
apply plugin: 'com.google.gms.google-services'
}

println "Gradle uses Java ${Jvm.current()}"

Expand Down Expand Up @@ -162,8 +168,11 @@ android {
}

gplay {
applicationId 'com.nextcloud.client'
applicationId "com.ionos.hidrivenext"
dimension "default"
versionCode 2
isDefault = true
resConfigs "en", "de", "es", "fr", "nl"
}

huawei {
Expand Down Expand Up @@ -321,6 +330,7 @@ dependencies {
gplayImplementation project(':appscan')
huaweiImplementation project(':appscan')
qaImplementation project(':appscan')
implementation project(':scanbot')

spotbugsPlugins 'com.h3xstream.findsecbugs:findsecbugs-plugin:1.13.0'
spotbugsPlugins 'com.mebigfatguy.fb-contrib:fb-contrib:7.6.4'
Expand Down Expand Up @@ -428,6 +438,10 @@ dependencies {

// splash screen dependency ref: https://developer.android.com/develop/ui/views/launch/splash-screen/migrate
implementation 'androidx.core:core-splashscreen:1.0.1'

implementation(platform("com.google.firebase:firebase-bom:33.7.0"))
implementation "com.google.firebase:firebase-analytics"
implementation "com.google.firebase:firebase-crashlytics"
}

configurations.configureEach {
Expand Down
94 changes: 36 additions & 58 deletions app/src/gplay/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,73 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Nextcloud - Android Client
<?xml version="1.0" encoding="utf-8"?><!--
~ IONOS HiDrive Next - Android Client
~
~ SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
~ SPDX-FileCopyrightText: 2017 Mario Danic <[email protected]>
~ SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-only
-->
~ SPDX-FileCopyrightText: 2025 STRATO GmbH.
~ SPDX-License-Identifier: GPL-2.0
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
xmlns:tools="http://schemas.android.com/tools">

<uses-permission
android:name="android.permission.REQUEST_INSTALL_PACKAGES"
tools:node="remove"/>
<application>

<uses-permission
android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
tools:node="remove"
tools:ignore="ScopedStorage" />

<application
android:name=".MainApp"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:fullBackupContent="@xml/backup_config"
android:theme="@style/Theme.ownCloud.Toolbar"
android:manageSpaceActivity="com.owncloud.android.ui.activity.ManageSpaceActivity">

<meta-data
android:name="firebase_analytics_collection_deactivated"
android:value="true" />
<meta-data
android:name="google_analytics_adid_collection_enabled"
android:value="false" />
<meta-data
android:name="google_analytics_ssaid_collection_enabled"
android:value="false" />
android:name="firebase_analytics_collection_enabled"
android:value="false"
tools:node="merge" />

<receiver
android:name="com.nextcloud.client.widget.DashboardWidgetProvider"
android:enabled="false" />

<activity
android:name=".authentication.ModifiedAuthenticatorActivity"
android:exported="true"
android:launchMode="singleTask"
android:theme="@style/Theme.ownCloud.noActionBar.Login">
<intent-filter>
<action android:name="com.owncloud.android.workaround.accounts.CREATE" />
android:name=".ui.preview.PreviewImageActivity"
android:theme="@style/Theme.ownCloud.PreviewImage"
tools:replace="android:theme" />

<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="@string/login_data_own_scheme" android:host="login"/>
</intent-filter>
</activity>
<activity
android:theme="@style/Theme.ownCloud.noActionBar.Login"
android:name="com.ionos.authorization_method.AuthorizationMethodActivity"
android:exported="false" />

<activity-alias
android:name=".authentication.AuthenticatorActivity"
android:targetActivity=".authentication.ModifiedAuthenticatorActivity"
tools:replace="android:targetActivity"/>
<activity
android:name="com.ionos.privacy.DataProtectionActivity"
android:exported="false" />

<activity
android:name="com.ionos.privacy.PrivacySettingsActivity"
android:exported="false" />

<service
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
android:name=".services.firebase.NCFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
tools:node="merge">
<meta-data
android:name="com.ionos.startup.IonosInitializer"
android:value="androidx.startup" />
</provider>

</application>

</manifest>
</manifest>
Original file line number Diff line number Diff line change
@@ -1,35 +1,29 @@
{
"project_info": {
"project_number": "",
"project_id": ""
"project_number": "695238986129",
"project_id": "ionos-easystorage-dev",
"storage_bucket": "ionos-easystorage-dev.firebasestorage.app"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "",
"mobilesdk_app_id": "1:695238986129:android:21f017261e3d0f7bc0f230",
"android_client_info": {
"package_name": "com.nextcloud.client"
"package_name": "com.ionos.hidrivenext"
}
},
"oauth_client": [],
"api_key": [
{
"current_key": ""
"current_key": "AIzaSyDgq5tBI0SVPspdtVrRx-z-fBR9XsbZeUw"
}
],
"services": {
"analytics_service": {
"status": 1
},
"appinvite_service": {
"status": 1,
"other_platform_oauth_client": []
},
"ads_service": {
"status": 1
}
}
}
],
"configuration_version": "1"
}
}
Binary file added app/src/gplay/ic_launcher-playstore.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -3,117 +3,20 @@
*
* SPDX-FileCopyrightText: 2023 Tobias Kaminsky <[email protected]>
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH
* SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-only
* SPDX-FileCopyrightText: 2025 STRATO GmbH.
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
package com.nextcloud.android.appReview

import androidx.appcompat.app.AppCompatActivity
import com.google.android.gms.tasks.Task
import com.google.android.play.core.review.ReviewInfo
import com.google.android.play.core.review.ReviewManager
import com.google.android.play.core.review.ReviewManagerFactory
import com.nextcloud.appReview.AppReviewShownModel
import com.nextcloud.appReview.InAppReviewHelper
import com.nextcloud.client.preferences.AppPreferences
import com.nextcloud.utils.extensions.getFormattedStringDate
import com.nextcloud.utils.extensions.isCurrentYear
import com.owncloud.android.lib.common.utils.Log_OC

// Reference: https://developer.android.com/guide/playcore/in-app-review
/**
* This class responsible to handle & manage in-app review related methods
*/
class InAppReviewHelperImpl(val appPreferences: AppPreferences) : InAppReviewHelper {

class InAppReviewHelperImpl(appPreferences: AppPreferences) :
InAppReviewHelper {
override fun resetAndIncrementAppRestartCounter() {
val appReviewShownModel = appPreferences.inAppReviewData
val currentTimeMills = System.currentTimeMillis()

if (appReviewShownModel != null) {
if (currentTimeMills.isCurrentYear(appReviewShownModel.firstShowYear)) {
appReviewShownModel.appRestartCount += 1
appPreferences.setInAppReviewData(appReviewShownModel)
} else {
resetReviewShownModel()
}
} else {
resetReviewShownModel()
}
}

private fun resetReviewShownModel() {
val appReviewShownModel = AppReviewShownModel(
System.currentTimeMillis().getFormattedStringDate(YEAR_FORMAT),
1,
0,
null
)
appPreferences.setInAppReviewData(appReviewShownModel)
}

override fun showInAppReview(activity: AppCompatActivity) {
val appReviewShownModel = appPreferences.inAppReviewData
val currentTimeMills = System.currentTimeMillis()

appReviewShownModel?.let {
if (it.appRestartCount >= MIN_APP_RESTARTS_REQ &&
currentTimeMills.isCurrentYear(it.firstShowYear) &&
it.reviewShownCount < MAX_DISPLAY_PER_YEAR
) {
doAppReview(activity)
} else {
Log_OC.d(
TAG,
"Yearly limit has been reached or minimum app restarts are not completed: $appReviewShownModel"
)
}
}
}

private fun doAppReview(activity: AppCompatActivity) {
val manager = ReviewManagerFactory.create(activity)
val request: Task<ReviewInfo> = manager.requestReviewFlow()
request.addOnCompleteListener { task ->
if (task.isSuccessful) {
// We can get the ReviewInfo object
val reviewInfo: ReviewInfo = task.result!!
launchAppReviewFlow(manager, activity, reviewInfo)
} else {
// There was some problem, log or handle the error code.
Log_OC.e(TAG, "Failed to get ReviewInfo: ${task.exception?.message}")
}
}
}

private fun launchAppReviewFlow(manager: ReviewManager, activity: AppCompatActivity, reviewInfo: ReviewInfo) {
val flow = manager.launchReviewFlow(activity, reviewInfo)
flow.addOnCompleteListener { _ ->
// The flow has finished. The API does not indicate whether the user
// reviewed or not, or even whether the review dialog was shown. Thus, no
// matter the result, we continue our app flow.
// Scenarios in which the flow won't shown:
// 1. Showing dialog to frequently
// 2. If quota is reached can be checked in official documentation
// 3. Flow won't be shown if user has already reviewed the app. User has to delete the review from play store to show the review dialog again
// Link for more info: https://stackoverflow.com/a/63342266
Log_OC.d(TAG, "App Review flow is completed")
}

// on successful showing review dialog increment the count and capture the date
val appReviewShownModel = appPreferences.inAppReviewData
appReviewShownModel?.let {
it.appRestartCount = 0
it.reviewShownCount += 1
it.lastReviewShownDate = System.currentTimeMillis().getFormattedStringDate(DATE_TIME_FORMAT)
appPreferences.setInAppReviewData(it)
}
}

companion object {
private val TAG = InAppReviewHelperImpl::class.java.simpleName
const val YEAR_FORMAT = "yyyy"
const val DATE_TIME_FORMAT = "dd-MM-yyyy HH:mm:ss"
const val MIN_APP_RESTARTS_REQ = 10 // minimum app restarts required to ask the review
const val MAX_DISPLAY_PER_YEAR = 15 // maximum times to ask review in a year
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,13 @@
* Nextcloud - Android Client
*
* SPDX-FileCopyrightText: 2019 Chris Narkiewicz <[email protected]>
* SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-only
* SPDX-FileCopyrightText: 2025 STRATO GmbH.
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
package com.nextcloud.client.di;

import com.owncloud.android.authentication.ModifiedAuthenticatorActivity;
import com.owncloud.android.services.firebase.NCFirebaseMessagingService;

import dagger.Module;
import dagger.android.ContributesAndroidInjector;

@Module
abstract class VariantComponentsModule {
@ContributesAndroidInjector
abstract NCFirebaseMessagingService nCFirebaseMessagingService();

@ContributesAndroidInjector
abstract ModifiedAuthenticatorActivity modifiedAuthenticatorActivity();
}
Loading
Loading