diff --git a/app/build.gradle b/app/build.gradle index d89b137e29fb..42abf0e87d18 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -50,7 +50,8 @@ if (shotTest) { apply plugin: 'shot' } apply plugin: 'com.google.devtools.ksp' - +// apply marketing SDK for NMC +apply from: "$rootProject.projectDir/nmc_marketing-dependencies.gradle" println "Gradle uses Java ${Jvm.current()}" @@ -427,6 +428,9 @@ dependencies { // splash screen dependency ref: https://developer.android.com/develop/ui/views/launch/splash-screen/migrate implementation 'androidx.core:core-splashscreen:1.0.1' + + // NMC: dependency required to capture Advertising ID for Adjust & MoEngage SDK + implementation 'com.google.android.gms:play-services-ads-identifier:18.0.1' } configurations.configureEach { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 6f89c63ac939..c69fbec4e95c 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -606,6 +606,17 @@ android:name="com.nextcloud.client.etm.EtmActivity" android:exported="false" android:theme="@style/Theme.ownCloud.Toolbar" /> + + + + + + + + (R.id.logs_loading_progress).apply { - viewThemeUtils.platform.themeHorizontalProgressBar(this) + //NMC Customization + ProgressBarThemeUtils.themeHorizontalProgressBar(this, resources.getColor(R.color.primary, null)) } logsAdapter = LogsAdapter(this) diff --git a/app/src/main/java/com/nextcloud/client/preferences/AppPreferences.java b/app/src/main/java/com/nextcloud/client/preferences/AppPreferences.java index b2517b5fa579..ff53897296c9 100644 --- a/app/src/main/java/com/nextcloud/client/preferences/AppPreferences.java +++ b/app/src/main/java/com/nextcloud/client/preferences/AppPreferences.java @@ -339,6 +339,24 @@ default void onDarkThemeModeChanged(DarkMode mode) { void setCurrentAccountName(String accountName); + /** + * Saves the data analysis from privacy settings + * on disabling it we should disable Adjust SDK tracking + * + * @param enableDataAnalysis to enable/disable data analysis + */ + void setDataAnalysis(boolean enableDataAnalysis); + boolean isDataAnalysisEnabled(); + + /** + * Saves the privacy policy action taken by user + * this will maintain the state of current privacy policy action taken + * @see com.nmc.android.ui.LoginPrivacySettingsActivity for actions + * @param userAction taken by user + */ + void setPrivacyPolicyAction(int userAction); + int getPrivacyPolicyAction(); + /** * Gets status of migration to user id, default false * diff --git a/app/src/main/java/com/nextcloud/client/preferences/AppPreferencesImpl.java b/app/src/main/java/com/nextcloud/client/preferences/AppPreferencesImpl.java index 0801d9102745..028b9d7f967e 100644 --- a/app/src/main/java/com/nextcloud/client/preferences/AppPreferencesImpl.java +++ b/app/src/main/java/com/nextcloud/client/preferences/AppPreferencesImpl.java @@ -22,6 +22,7 @@ import com.nextcloud.client.account.UserAccountManager; import com.nextcloud.client.account.UserAccountManagerImpl; import com.nextcloud.client.jobs.LogEntry; +import com.nmc.android.ui.PrivacyUserAction; import com.owncloud.android.datamodel.ArbitraryDataProvider; import com.owncloud.android.datamodel.ArbitraryDataProviderImpl; import com.owncloud.android.datamodel.FileDataStorageManager; @@ -104,6 +105,9 @@ public final class AppPreferencesImpl implements AppPreferences { private static final String LOG_ENTRY = "log_entry"; + private static final String PREF__DATA_ANALYSIS = "data_analysis"; + private static final String PREF__PRIVACY_POLICY_ACTION = "privacy_policy_action"; + private final Context context; private final SharedPreferences preferences; private final UserAccountManager userAccountManager; @@ -610,6 +614,27 @@ public void setCurrentAccountName(String accountName) { preferences.edit().putString(PREF__SELECTED_ACCOUNT_NAME, accountName).apply(); } + @Override + public void setDataAnalysis(boolean enableDataAnalysis) { + preferences.edit().putBoolean(PREF__DATA_ANALYSIS, enableDataAnalysis).apply(); + } + + @Override + public boolean isDataAnalysisEnabled() { + //default value will be true + return preferences.getBoolean(PREF__DATA_ANALYSIS, true); + } + + @Override + public void setPrivacyPolicyAction(int userAction) { + preferences.edit().putInt(PREF__PRIVACY_POLICY_ACTION, userAction).apply(); + } + + @Override + public int getPrivacyPolicyAction() { + return preferences.getInt(PREF__PRIVACY_POLICY_ACTION, PrivacyUserAction.NO_ACTION); + } + @Override public boolean isUserIdMigrated() { return preferences.getBoolean(PREF__MIGRATED_USER_ID, false); diff --git a/app/src/main/java/com/nmc/android/marketTracking/AdjustSdkUtils.kt b/app/src/main/java/com/nmc/android/marketTracking/AdjustSdkUtils.kt new file mode 100644 index 000000000000..2fc80427dc79 --- /dev/null +++ b/app/src/main/java/com/nmc/android/marketTracking/AdjustSdkUtils.kt @@ -0,0 +1,67 @@ +package com.nmc.android.marketTracking + +import android.app.Application +import com.adjust.sdk.Adjust +import com.adjust.sdk.AdjustConfig +import com.adjust.sdk.AdjustEvent +import com.nextcloud.client.preferences.AppPreferences +import com.owncloud.android.BuildConfig + +object AdjustSdkUtils { + private val TAG = AdjustSdkUtils::class.java.simpleName + + const val EVENT_TOKEN_LOGIN = "gb97gb" + const val EVENT_TOKEN_SUCCESSFUL_LOGIN = "gx6g7g" + const val EVENT_TOKEN_FILE_BROWSER_SHARING = "fqtiu7" + const val EVENT_TOKEN_CREATE_SHARING_LINK = "qeyql3" + + /* event names to be tracked on clicking of FAB button which opens BottomSheet to select options */ + const val EVENT_TOKEN_FAB_BOTTOM_FILE_UPLOAD = "4rd8r4" + const val EVENT_TOKEN_FAB_BOTTOM_PHOTO_VIDEO_UPLOAD = "v1g6ly" + const val EVENT_TOKEN_FAB_BOTTOM_DOCUMENT_SCAN = "7fec8n" + const val EVENT_TOKEN_FAB_BOTTOM_CAMERA_UPLOAD = "3czack" + + /* events for settings screen */ + const val EVENT_TOKEN_SETTINGS_LOGOUT = "g6mj9y" + const val EVENT_TOKEN_SETTINGS_RESET = "zi18r0" + const val EVENT_TOKEN_SETTINGS_AUTO_UPLOAD_ON = "vwd9yk" + const val EVENT_TOKEN_SETTINGS_AUTO_UPLOAD_OFF = "e95w5t" + + const val EVENT_TOKEN_BACKUP_MANUAL = "oojr4y" + const val EVENT_TOKEN_BACKUP_AUTO = "7dkhkx" + + @JvmStatic + fun initialiseAdjustSDK(application: Application) { + val config = AdjustConfig( + application, BuildConfig.ADJUST_APP_TOKEN, + getAdjustEnvironment() + ) + Adjust.onCreate(config) + } + + /** + * method to return the sdk environment for Adjust + */ + @JvmStatic + fun getAdjustEnvironment(): String { + //for qa, beta, debug apk we have to use Sandbox env + if (BuildConfig.APPLICATION_ID.contains(".beta") || BuildConfig.DEBUG) { + return AdjustConfig.ENVIRONMENT_SANDBOX + } + + //for release build apart from qa, beta flavours Prod env is used + return AdjustConfig.ENVIRONMENT_PRODUCTION + } + + /** + * method to track events + * tracking event only if data analysis is enabled else don't track it + */ + @JvmStatic + fun trackEvent(eventToken: String, appPreferences: AppPreferences?) { + if (appPreferences?.isDataAnalysisEnabled == true) { + val adjustEvent = AdjustEvent(eventToken) + Adjust.trackEvent(adjustEvent) + } + } +} diff --git a/app/src/main/java/com/nmc/android/marketTracking/TealiumSdkUtils.kt b/app/src/main/java/com/nmc/android/marketTracking/TealiumSdkUtils.kt new file mode 100644 index 000000000000..806cc175eff1 --- /dev/null +++ b/app/src/main/java/com/nmc/android/marketTracking/TealiumSdkUtils.kt @@ -0,0 +1,107 @@ +package com.nmc.android.marketTracking + +import android.app.Application +import com.nextcloud.client.preferences.AppPreferences +import com.owncloud.android.BuildConfig +import com.tealium.library.Tealium + +object TealiumSdkUtils { + + //Pre-defined values for Tealium + //** DO NOT CHANGE THE VALUES **// + private const val INSTANCE_NAME = "tealium_main" + private const val ACCOUNT_NAME = "telekom" + private const val PROFILE_NAME = "magentacloud-app" + + //Live Version of the app (published in app stores) + private const val PROD_ENV = "prod" + + //Quality System + private const val QA_ENV = "qa" + + //Staging System (Development System) + private const val DEV_ENV = "dev" + + const val EVENT_SUCCESSFUL_LOGIN = "magentacloud-app.login.successful" + const val EVENT_FILE_BROWSER_SHARING = "magentacloud-app.filebrowser.sharing" + const val EVENT_CREATE_SHARING_LINK = "magentacloud-app.sharing.create" + + /* event names to be tracked on clicking of FAB button which opens BottomSheet to select options */ + const val EVENT_FAB_BOTTOM_DOCUMENT_SCAN = "magentacloud-app.plus.documentscan" + const val EVENT_FAB_BOTTOM_PHOTO_VIDEO_UPLOAD = "magentacloud-app.plus.fotovideoupload" + const val EVENT_FAB_BOTTOM_FILE_UPLOAD = "magentacloud-app.plus.fileupload" + const val EVENT_FAB_BOTTOM_CAMERA_UPLOAD = "magentacloud-app.plus.cameraupload" + + /* events for settings screen */ + const val EVENT_SETTINGS_LOGOUT = "magentacloud-app.settings.logout" + const val EVENT_SETTINGS_RESET = "magentacloud-app.settings.reset" + const val EVENT_SETTINGS_AUTO_UPLOAD_ON = "magentacloud-app.settings.autoupload-on" + const val EVENT_SETTINGS_AUTO_UPLOAD_OFF = "magentacloud-app.settings.autoupload-off" + + const val EVENT_BACKUP_MANUAL = "magentacloud-app.backup.manual" + const val EVENT_BACKUP_AUTO = "magentacloud-app.backup.auto" + + /* Screen View Names to be tracked */ + const val SCREEN_VIEW_LOGIN = "magentacloud-app.login" + const val SCREEN_VIEW_FILE_BROWSER = "magentacloud-app.filebrowser" + const val SCREEN_VIEW_FAB_PLUS = "magentacloud-app.plus" + const val SCREEN_VIEW_SHARING = "magentacloud-app.sharing" + const val SCREEN_VIEW_SETTINGS = "magentacloud-app.settings" + const val SCREEN_VIEW_BACKUP = "magentacloud-app.backup" + + @JvmStatic + fun initialiseTealiumSDK(application: Application) { + val tealConfig = Tealium.Config.create( + application, + ACCOUNT_NAME, + PROFILE_NAME, + getTealiumEnvironment() + ) + + // Override for the tag management webview URL (mobile.html) + //tealConfig.setOverrideTagManagementUrl("https://tags-eu.tiqcdn.com/utag/telekom/magentacloudapp/prod/mobile" +".html"); + // Override for the tag management publish URL (compare to https://tealium.github.io/tealiumandroid/) + //tealConfig.setOverrideTagManagementUrl("https://tags-eu.tiqcdn.com/utag/telekom/magentacloudapp/prod"); + Tealium.createInstance(INSTANCE_NAME, tealConfig) + } + + /** + * method to return the tealium sdk environment + */ + private fun getTealiumEnvironment(): String { + //if flavour is qa then return the qa environment + if (BuildConfig.FLAVOR == "qa") { + return QA_ENV + } + + //if flavour is versionDev or the build has debug mode then return dev environment + if (BuildConfig.FLAVOR == "versionDev" || BuildConfig.DEBUG) { + return DEV_ENV + } + + //for release build to play store return prod environment + return PROD_ENV + } + + /** + * method to track events + * tracking event only if data analysis is enabled else don't track it + */ + @JvmStatic + fun trackEvent(eventName: String, appPreferences: AppPreferences?) { + if (appPreferences?.isDataAnalysisEnabled == true) { + Tealium.getInstance(INSTANCE_NAME).trackEvent(eventName, null) + } + } + + /** + * method to track view + * tracking view only if data analysis is enabled else don't track it + */ + @JvmStatic + fun trackView(viewName: String, appPreferences: AppPreferences?) { + if (appPreferences?.isDataAnalysisEnabled == true) { + Tealium.getInstance(INSTANCE_NAME).trackView(viewName, null) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/nmc/android/marketTracking/TrackingScanInterface.kt b/app/src/main/java/com/nmc/android/marketTracking/TrackingScanInterface.kt new file mode 100644 index 000000000000..3a517a29f458 --- /dev/null +++ b/app/src/main/java/com/nmc/android/marketTracking/TrackingScanInterface.kt @@ -0,0 +1,14 @@ +package com.nmc.android.marketTracking + +import com.nextcloud.client.preferences.AppPreferences + +/** + * interface to track the scanning events from nmc/1867-scanbot branch + * for implementation look nmc/1925-market_tracking branch + * this class will have the declaration for it since it has the tracking SDK's in place + * since we don't have scanning functionality in this branch so to handle the event we have used interface + */ +interface TrackingScanInterface { + + fun sendScanEvent(appPreferences: AppPreferences) +} \ No newline at end of file diff --git a/app/src/main/java/com/nmc/android/marketTracking/TrackingScanInterfaceImpl.kt b/app/src/main/java/com/nmc/android/marketTracking/TrackingScanInterfaceImpl.kt new file mode 100644 index 000000000000..ed0c7cd5d92a --- /dev/null +++ b/app/src/main/java/com/nmc/android/marketTracking/TrackingScanInterfaceImpl.kt @@ -0,0 +1,18 @@ +package com.nmc.android.marketTracking + +import com.nextcloud.client.preferences.AppPreferences + +/** + * interface impl to send the scanning events to tealium and adjust + * this class will have the implementation for it since it has the tracking SDK's in place + * since we don't have scanning functionality in this branch so to handle the event we have used interface + * calling of this method will be done from nmc/1867-scanbot + */ +class TrackingScanInterfaceImpl : TrackingScanInterface { + + override fun sendScanEvent(appPreferences: AppPreferences) { + //track event on Scan Document button click + AdjustSdkUtils.trackEvent(AdjustSdkUtils.EVENT_TOKEN_FAB_BOTTOM_DOCUMENT_SCAN, appPreferences) + TealiumSdkUtils.trackEvent(TealiumSdkUtils.EVENT_FAB_BOTTOM_DOCUMENT_SCAN, appPreferences) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/nmc/android/ui/PrivacyUserAction.kt b/app/src/main/java/com/nmc/android/ui/PrivacyUserAction.kt new file mode 100644 index 000000000000..6dca412cc29b --- /dev/null +++ b/app/src/main/java/com/nmc/android/ui/PrivacyUserAction.kt @@ -0,0 +1,9 @@ +package com.nmc.android.ui + +//class to handle user action for privacy +object PrivacyUserAction { + //privacy user action to maintain the state of privacy policy + const val NO_ACTION = 0 //user has taken no action + const val REJECT_ACTION = 1 //user rejected the privacy policy + const val ACCEPT_ACTION = 2 //user has accepted the privacy policy +} \ No newline at end of file diff --git a/app/src/main/java/com/nmc/android/ui/utils/ProgressBarThemeUtils.kt b/app/src/main/java/com/nmc/android/ui/utils/ProgressBarThemeUtils.kt new file mode 100644 index 000000000000..ea274bb68c3a --- /dev/null +++ b/app/src/main/java/com/nmc/android/ui/utils/ProgressBarThemeUtils.kt @@ -0,0 +1,28 @@ +package com.nmc.android.ui.utils + +import android.widget.ProgressBar +import android.widget.SeekBar +import androidx.annotation.ColorInt +import androidx.core.graphics.BlendModeColorFilterCompat +import androidx.core.graphics.BlendModeCompat + +/** + * theming progress and seek bar for NMC + */ +object ProgressBarThemeUtils { + + @JvmStatic + fun themeHorizontalSeekBar(seekBar: SeekBar, @ColorInt color: Int) { + themeHorizontalProgressBar(seekBar, color) + seekBar.thumb.colorFilter = + BlendModeColorFilterCompat.createBlendModeColorFilterCompat(color, BlendModeCompat.SRC_IN) + } + + @JvmStatic + fun themeHorizontalProgressBar(progressBar: ProgressBar?, @ColorInt color: Int) { + progressBar?.indeterminateDrawable?.colorFilter = + BlendModeColorFilterCompat.createBlendModeColorFilterCompat(color, BlendModeCompat.SRC_IN) + progressBar?.progressDrawable?.colorFilter = + BlendModeColorFilterCompat.createBlendModeColorFilterCompat(color, BlendModeCompat.SRC_IN) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/owncloud/android/MainApp.java b/app/src/main/java/com/owncloud/android/MainApp.java index 9fd3e2cb7abe..1bfda13e9931 100644 --- a/app/src/main/java/com/owncloud/android/MainApp.java +++ b/app/src/main/java/com/owncloud/android/MainApp.java @@ -61,6 +61,8 @@ import com.nextcloud.client.preferences.DarkMode; import com.nextcloud.utils.extensions.ContextExtensionsKt; import com.nmc.android.ui.LauncherActivity; +import com.nmc.android.marketTracking.AdjustSdkUtils; +import com.nmc.android.marketTracking.TealiumSdkUtils; import com.owncloud.android.authentication.AuthenticatorActivity; import com.owncloud.android.authentication.PassCodeManager; import com.owncloud.android.datamodel.ArbitraryDataProvider; @@ -309,6 +311,11 @@ public void onCreate() { initSecurityKeyManager(); + // NMC Customization + // Adjust SDK has to be initialised before registerActivityLifecycleCallbacks method + // https://github.com/adjust/android_sdk#api-level-14-and-higher + initMarketTrackingSdks(); + registerActivityLifecycleCallbacks(new ActivityInjector()); //update the app restart count when app is launched by the user @@ -967,6 +974,12 @@ public AndroidInjector androidInjector() { return dispatchingAndroidInjector; } + //NMC Customization + private void initMarketTrackingSdks(){ + TealiumSdkUtils.initialiseTealiumSDK(this); + AdjustSdkUtils.initialiseAdjustSDK(this); + } + public static void setAppTheme(DarkMode mode) { switch (mode) { case LIGHT -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO); diff --git a/app/src/main/java/com/owncloud/android/authentication/AuthenticatorActivity.java b/app/src/main/java/com/owncloud/android/authentication/AuthenticatorActivity.java index 727f514ca66d..855413123046 100644 --- a/app/src/main/java/com/owncloud/android/authentication/AuthenticatorActivity.java +++ b/app/src/main/java/com/owncloud/android/authentication/AuthenticatorActivity.java @@ -66,6 +66,8 @@ import com.nextcloud.common.PlainClient; import com.nextcloud.operations.PostMethod; import com.nextcloud.utils.extensions.BundleExtensionsKt; +import com.nmc.android.marketTracking.AdjustSdkUtils; +import com.nmc.android.marketTracking.TealiumSdkUtils; import com.owncloud.android.MainApp; import com.owncloud.android.R; import com.owncloud.android.databinding.AccountSetupBinding; @@ -1333,6 +1335,10 @@ public void onAuthenticatorTaskCallback(RemoteOperationResult result) } private void endSuccess() { + //track successful login event + AdjustSdkUtils.trackEvent(AdjustSdkUtils.EVENT_TOKEN_SUCCESSFUL_LOGIN, preferences); + TealiumSdkUtils.trackEvent(TealiumSdkUtils.EVENT_SUCCESSFUL_LOGIN, preferences); + if (onlyAdd) { finish(); } else { @@ -1735,4 +1741,11 @@ public void onSavedCertificate() { public void onFailedSavingCertificate() { DisplayUtils.showSnackMessage(this, R.string.ssl_validator_not_saved); } + + @Override + protected void onStart() { + super.onStart(); + //track screen view when activity is visible + TealiumSdkUtils.trackView(TealiumSdkUtils.SCREEN_VIEW_LOGIN, preferences); + } } diff --git a/app/src/main/java/com/owncloud/android/media/MediaControlView.kt b/app/src/main/java/com/owncloud/android/media/MediaControlView.kt index 25747c3f1bd0..1b7eb5081e0b 100644 --- a/app/src/main/java/com/owncloud/android/media/MediaControlView.kt +++ b/app/src/main/java/com/owncloud/android/media/MediaControlView.kt @@ -27,6 +27,7 @@ import android.widget.MediaController.MediaPlayerControl import android.widget.SeekBar import android.widget.SeekBar.OnSeekBarChangeListener import androidx.core.content.ContextCompat +import com.nmc.android.ui.utils.ProgressBarThemeUtils import com.owncloud.android.MainApp import com.owncloud.android.R import com.owncloud.android.databinding.MediaControlBinding @@ -85,7 +86,8 @@ class MediaControlView(context: Context, attrs: AttributeSet?) : binding.rewindBtn.setOnClickListener(this) binding.progressBar.run { - viewThemeUtils.platform.themeHorizontalSeekBar(this) + // NMC Customization + ProgressBarThemeUtils.themeHorizontalSeekBar(this, resources.getColor(R.color.primary, null)) setMax(1000) } diff --git a/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.java b/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.java index 868513da42f2..0e5f5fa1bc9e 100644 --- a/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.java +++ b/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.java @@ -63,6 +63,7 @@ import com.nextcloud.client.network.ConnectivityService; import com.nextcloud.client.preferences.AppPreferences; import com.nextcloud.client.utils.IntentUtil; +import com.nmc.android.marketTracking.TealiumSdkUtils; import com.nextcloud.model.WorkerState; import com.nextcloud.model.WorkerStateLiveData; import com.nextcloud.utils.extensions.ActivityExtensionsKt; @@ -2327,6 +2328,9 @@ public void onStart() { EventBus.getDefault().post(new TokenPushEvent()); checkForNewDevVersionNecessary(getApplicationContext()); + + //track screen view when activity is visible + TealiumSdkUtils.trackView(TealiumSdkUtils.SCREEN_VIEW_FILE_BROWSER, preferences); } private void registerRefreshFolderEventReceiver() { diff --git a/app/src/main/java/com/owncloud/android/ui/activity/SettingsActivity.java b/app/src/main/java/com/owncloud/android/ui/activity/SettingsActivity.java index 0dbf9ca99e92..949601a2421a 100644 --- a/app/src/main/java/com/owncloud/android/ui/activity/SettingsActivity.java +++ b/app/src/main/java/com/owncloud/android/ui/activity/SettingsActivity.java @@ -47,6 +47,7 @@ import com.nextcloud.client.network.ClientFactory; import com.nextcloud.client.network.ConnectivityService; import com.nextcloud.client.preferences.AppPreferences; +import com.nmc.android.marketTracking.TealiumSdkUtils; import com.nextcloud.client.preferences.AppPreferencesImpl; import com.nextcloud.client.preferences.DarkMode; import com.owncloud.android.BuildConfig; @@ -1067,6 +1068,13 @@ protected void onPostCreate(Bundle savedInstanceState) { getDelegate().onPostCreate(savedInstanceState); } + @Override + protected void onStart() { + super.onStart(); + //track screen view when activity is visible + TealiumSdkUtils.trackView(TealiumSdkUtils.SCREEN_VIEW_SETTINGS, preferences); + } + @Override protected void onDestroy() { super.onDestroy(); diff --git a/app/src/main/java/com/owncloud/android/ui/activity/SyncedFoldersActivity.kt b/app/src/main/java/com/owncloud/android/ui/activity/SyncedFoldersActivity.kt index 23486394a2ca..cdc265f63ae8 100644 --- a/app/src/main/java/com/owncloud/android/ui/activity/SyncedFoldersActivity.kt +++ b/app/src/main/java/com/owncloud/android/ui/activity/SyncedFoldersActivity.kt @@ -35,6 +35,8 @@ import com.nextcloud.client.preferences.AppPreferences import com.nextcloud.client.preferences.SubFolderRule import com.nextcloud.utils.extensions.getParcelableArgument import com.nextcloud.utils.extensions.isDialogFragmentReady +import com.nmc.android.marketTracking.AdjustSdkUtils +import com.nmc.android.marketTracking.TealiumSdkUtils import com.owncloud.android.BuildConfig import com.owncloud.android.MainApp import com.owncloud.android.R @@ -583,6 +585,9 @@ class SyncedFoldersActivity : backgroundJobManager.startImmediateFilesSyncJob(syncedFolderDisplayItem.id, overridePowerSaving = false) showBatteryOptimizationInfo() } + + //track event when user enable/disable auto upload on/off + trackAutoUploadEvent(syncedFolderDisplayItem.isEnabled) } override fun onSyncFolderSettingsClick(section: Int, syncedFolderDisplayItem: SyncedFolderDisplayItem?) { @@ -710,6 +715,14 @@ class SyncedFoldersActivity : if (syncedFolder.isEnabled) { showBatteryOptimizationInfo() } + + //track event when user enable/disable auto upload on/off + trackAutoUploadEvent(syncedFolder.isEnabled) + } + + private fun trackAutoUploadEvent(enabled: Boolean) { + AdjustSdkUtils.trackEvent(if (enabled) AdjustSdkUtils.EVENT_TOKEN_SETTINGS_AUTO_UPLOAD_ON else AdjustSdkUtils.EVENT_TOKEN_SETTINGS_AUTO_UPLOAD_OFF, preferences) + TealiumSdkUtils.trackEvent(if (enabled) TealiumSdkUtils.EVENT_SETTINGS_AUTO_UPLOAD_ON else TealiumSdkUtils.EVENT_SETTINGS_AUTO_UPLOAD_OFF, preferences) } private fun saveOrUpdateSyncedFolder(item: SyncedFolderDisplayItem) { diff --git a/app/src/main/java/com/owncloud/android/ui/adapter/UploadListAdapter.java b/app/src/main/java/com/owncloud/android/ui/adapter/UploadListAdapter.java index 80fdcb89a5c0..5bff6ac85d21 100755 --- a/app/src/main/java/com/owncloud/android/ui/adapter/UploadListAdapter.java +++ b/app/src/main/java/com/owncloud/android/ui/adapter/UploadListAdapter.java @@ -30,6 +30,7 @@ import com.nextcloud.client.jobs.upload.FileUploadHelper; import com.nextcloud.client.jobs.upload.FileUploadWorker; import com.nextcloud.client.network.ConnectivityService; +import com.nmc.android.ui.utils.ProgressBarThemeUtils; import com.owncloud.android.MainApp; import com.owncloud.android.R; import com.owncloud.android.databinding.UploadListHeaderBinding; @@ -345,7 +346,9 @@ public void onBindViewHolder(SectionedViewHolder holder, int section, int relati String status = getStatusText(item); switch (item.getUploadStatus()) { case UPLOAD_IN_PROGRESS -> { - viewThemeUtils.platform.themeHorizontalProgressBar(itemViewHolder.binding.uploadProgressBar); + // NMC Customization + ProgressBarThemeUtils.themeHorizontalProgressBar(itemViewHolder.binding.uploadProgressBar, + holder.itemView.getContext().getResources().getColor(R.color.primary, null)); itemViewHolder.binding.uploadProgressBar.setProgress(0); itemViewHolder.binding.uploadProgressBar.setVisibility(View.VISIBLE); diff --git a/app/src/main/java/com/owncloud/android/ui/dialog/AccountRemovalDialog.kt b/app/src/main/java/com/owncloud/android/ui/dialog/AccountRemovalDialog.kt index e42f1b7c626f..f07de12e475f 100644 --- a/app/src/main/java/com/owncloud/android/ui/dialog/AccountRemovalDialog.kt +++ b/app/src/main/java/com/owncloud/android/ui/dialog/AccountRemovalDialog.kt @@ -9,27 +9,23 @@ package com.owncloud.android.ui.dialog import android.app.Dialog -import android.graphics.drawable.Drawable +import android.content.DialogInterface import android.os.Bundle -import android.view.View -import androidx.appcompat.app.AlertDialog import androidx.fragment.app.DialogFragment -import com.google.android.material.button.MaterialButton import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.nextcloud.client.account.User -import com.nextcloud.client.account.UserAccountManager import com.nextcloud.client.di.Injectable import com.nextcloud.client.jobs.BackgroundJobManager +import com.nextcloud.client.preferences.AppPreferences +import com.nmc.android.marketTracking.AdjustSdkUtils +import com.nmc.android.marketTracking.TealiumSdkUtils import com.nextcloud.utils.extensions.getParcelableArgument import com.owncloud.android.R -import com.owncloud.android.databinding.AccountRemovalDialogBinding -import com.owncloud.android.datamodel.FileDataStorageManager -import com.owncloud.android.utils.DisplayUtils -import com.owncloud.android.utils.DisplayUtils.AvatarGenerationListener import com.owncloud.android.utils.theme.ViewThemeUtils import javax.inject.Inject -class AccountRemovalDialog : DialogFragment(), AvatarGenerationListener, Injectable { +// NMC Customization: We don't need two option for logout. On logout directly logout the user locally from the app +class AccountRemovalDialog : DialogFragment(), Injectable { @Inject lateinit var backgroundJobManager: BackgroundJobManager @@ -37,137 +33,37 @@ class AccountRemovalDialog : DialogFragment(), AvatarGenerationListener, Injecta @Inject lateinit var viewThemeUtils: ViewThemeUtils + @Inject + lateinit var appPreferences: AppPreferences + private var user: User? = null - private lateinit var alertDialog: AlertDialog - private var _binding: AccountRemovalDialogBinding? = null - val binding get() = _binding!! override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) user = requireArguments().getParcelableArgument(KEY_USER, User::class.java) } - override fun onStart() { - super.onStart() - - // disable positive button and apply theming - alertDialog = dialog as AlertDialog - alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).isEnabled = false - - viewThemeUtils.platform.themeRadioButton(binding.radioLocalRemove) - viewThemeUtils.platform.themeRadioButton(binding.radioRequestDeletion) - viewThemeUtils.material.colorMaterialButtonPrimaryTonal( - alertDialog.getButton(AlertDialog.BUTTON_POSITIVE) as MaterialButton - ) - viewThemeUtils.material.colorMaterialButtonPrimaryBorderless( - alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE) as MaterialButton - ) - - binding.userName.text = UserAccountManager.getDisplayName(user) - binding.account.text = user?.let { DisplayUtils.convertIdn(it.accountName, false) } - } - override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - _binding = AccountRemovalDialogBinding.inflate(layoutInflater) - - // start avatar generation - setAvatar() - - // hide second option when plug-in isn't installed - if (hasDropAccount()) { - binding.requestDeletion.visibility = View.VISIBLE - } - - val builder = - MaterialAlertDialogBuilder(requireActivity()) - .setTitle(R.string.delete_account) - .setView(binding.root) - .setNegativeButton(R.string.common_cancel) { _, _ -> } - .setPositiveButton(R.string.delete_account) { _, _ -> removeAccount() } - - // allow selection by clicking on list element - binding.localRemove.setOnClickListener { - binding.radioLocalRemove.performClick() - } - binding.requestDeletion.setOnClickListener { - binding.radioRequestDeletion.performClick() - } - - // set listeners for custom radio button list - binding.radioLocalRemove.setOnClickListener { - binding.radioRequestDeletion.isChecked = false - alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).apply { - text = getText(R.string.delete_account) - isEnabled = true - } - } - binding.radioRequestDeletion.setOnClickListener { - binding.radioLocalRemove.isChecked = false - alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).apply { - text = getString(R.string.request_account_deletion_button) - isEnabled = true + val builder = MaterialAlertDialogBuilder(requireActivity()) + .setTitle(R.string.delete_account) + .setMessage(resources.getString(R.string.delete_account_warning, user!!.accountName)) + .setIcon(R.drawable.ic_warning) + .setPositiveButton(R.string.common_ok) { _: DialogInterface?, _: Int -> + // track adjust and tealium events on logout confirmed + AdjustSdkUtils.trackEvent(AdjustSdkUtils.EVENT_TOKEN_SETTINGS_LOGOUT, appPreferences) + TealiumSdkUtils.trackEvent(TealiumSdkUtils.EVENT_SETTINGS_LOGOUT, appPreferences) + backgroundJobManager.startAccountRemovalJob( + user!!.accountName, + false + ) } - } - - viewThemeUtils.dialog.colorMaterialAlertDialogBackground(requireActivity(), builder) + .setNegativeButton(R.string.common_cancel, null) return builder.create() } - /** - * Get value of `drop-account` capability. - */ - private fun hasDropAccount(): Boolean { - val capability = FileDataStorageManager(user, context?.contentResolver).getCapability(user) - return capability.dropAccount.isTrue - } - - /** - * Start removal of account. Depending on which option is checked, either a browser will open to request deletion, - * or the local account will be removed immediately. - */ - private fun removeAccount() { - user?.let { user -> - if (binding.radioRequestDeletion.isChecked) { - DisplayUtils.startLinkIntent(activity, user.server.uri.toString() + DROP_ACCOUNT_URI) - } else { - backgroundJobManager.startAccountRemovalJob(user.accountName, false) - } - } - } - - /** - * Start avatar generation. - */ - private fun setAvatar() { - try { - val imageView = binding.userIcon - imageView.tag = user!!.accountName - DisplayUtils.setAvatar( - user!!, - this, - resources.getDimension(R.dimen.list_item_avatar_icon_radius), - resources, - imageView, - context - ) - } catch (_: Exception) { - } - } - - override fun avatarGenerated(avatarDrawable: Drawable?, callContext: Any?) { - avatarDrawable?.let { - binding.userIcon.setImageDrawable(it) - } - } - - override fun shouldCallGeneratedCallback(tag: String?, callContext: Any?): Boolean { - return binding.userIcon.tag == tag - } - companion object { private const val KEY_USER = "USER" - private const val DROP_ACCOUNT_URI = "/settings/user/drop_account" @JvmStatic fun newInstance(user: User) = AccountRemovalDialog().apply { diff --git a/app/src/main/java/com/owncloud/android/ui/fragment/FileDetailFragment.java b/app/src/main/java/com/owncloud/android/ui/fragment/FileDetailFragment.java index b02a85ae5022..d0c2711e6baa 100644 --- a/app/src/main/java/com/owncloud/android/ui/fragment/FileDetailFragment.java +++ b/app/src/main/java/com/owncloud/android/ui/fragment/FileDetailFragment.java @@ -36,6 +36,7 @@ import com.nextcloud.utils.MenuUtils; import com.nextcloud.utils.extensions.BundleExtensionsKt; import com.nextcloud.utils.extensions.FileExtensionsKt; +import com.nmc.android.marketTracking.TealiumSdkUtils; import com.owncloud.android.MainApp; import com.owncloud.android.R; import com.owncloud.android.databinding.FileDetailsFragmentBinding; @@ -58,6 +59,7 @@ import com.owncloud.android.utils.DisplayUtils; import com.owncloud.android.utils.EncryptionUtils; import com.owncloud.android.utils.MimeTypeUtil; +import com.nmc.android.ui.utils.ProgressBarThemeUtils; import com.owncloud.android.utils.theme.ViewThemeUtils; import org.greenrobot.eventbus.EventBus; @@ -255,7 +257,8 @@ public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { if (getFile() != null && user != null) { - viewThemeUtils.platform.themeHorizontalProgressBar(binding.progressBar); + //NMC Customization + ProgressBarThemeUtils.themeHorizontalProgressBar(binding.progressBar, getResources().getColor(R.color.primary, null)); progressListener = new ProgressListener(binding.progressBar); binding.cancelBtn.setOnClickListener(this); binding.favorite.setOnClickListener(this); @@ -371,6 +374,8 @@ public void onStart() { super.onStart(); listenForTransferProgress(); EventBus.getDefault().register(this); + //track screen view when fragment is visible + TealiumSdkUtils.trackView(TealiumSdkUtils.SCREEN_VIEW_SHARING, preferences); } @Override diff --git a/app/src/main/java/com/owncloud/android/ui/fragment/FileDetailSharingFragment.java b/app/src/main/java/com/owncloud/android/ui/fragment/FileDetailSharingFragment.java index 071faeee4666..372fde88d28d 100644 --- a/app/src/main/java/com/owncloud/android/ui/fragment/FileDetailSharingFragment.java +++ b/app/src/main/java/com/owncloud/android/ui/fragment/FileDetailSharingFragment.java @@ -55,6 +55,9 @@ import com.owncloud.android.ui.adapter.ShareeListAdapter; import com.owncloud.android.ui.adapter.ShareeListAdapterListener; import com.owncloud.android.ui.asynctasks.RetrieveHoverCardAsyncTask; +import com.nextcloud.client.preferences.AppPreferences; +import com.nmc.android.marketTracking.AdjustSdkUtils; +import com.nmc.android.marketTracking.TealiumSdkUtils; import com.owncloud.android.ui.dialog.SharePasswordDialogFragment; import com.owncloud.android.ui.fragment.util.FileDetailSharingFragmentHelper; import com.owncloud.android.ui.helpers.FileOperationsHelper; @@ -101,6 +104,7 @@ public class FileDetailSharingFragment extends Fragment implements ShareeListAda @Inject ClientFactory clientFactory; @Inject ViewThemeUtils viewThemeUtils; @Inject UsersAndGroupsSearchConfig searchConfig; + @Inject AppPreferences appPreferences; public static FileDetailSharingFragment newInstance(OCFile file, User user) { FileDetailSharingFragment fragment = new FileDetailSharingFragment(); @@ -311,6 +315,10 @@ public void createPublicShareLink() { // create without password if not enforced by server or we don't know if enforced; fileOperationsHelper.shareFileViaPublicShare(file, null); } + + //track event on creating share link + AdjustSdkUtils.trackEvent(AdjustSdkUtils.EVENT_TOKEN_CREATE_SHARING_LINK, appPreferences); + TealiumSdkUtils.trackEvent(TealiumSdkUtils.EVENT_CREATE_SHARING_LINK, appPreferences); } @Override diff --git a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListBottomSheetDialog.java b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListBottomSheetDialog.java index 2deb69e0537d..941b0530396d 100644 --- a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListBottomSheetDialog.java +++ b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListBottomSheetDialog.java @@ -16,7 +16,9 @@ import com.nextcloud.client.device.DeviceInfo; import com.nextcloud.client.di.Injectable; import com.nextcloud.client.documentscan.AppScanOptionalFeature; +import com.nextcloud.client.preferences.AppPreferencesImpl; import com.nextcloud.utils.EditorUtils; +import com.nmc.android.marketTracking.TealiumSdkUtils; import com.owncloud.android.R; import com.owncloud.android.databinding.FileListActionsBottomSheetCreatorBinding; import com.owncloud.android.databinding.FileListActionsBottomSheetFragmentBinding; @@ -157,6 +159,12 @@ protected void onCreate(Bundle savedInstanceState) { } setupClickListener(); + + //track screen view when fragment is visible + TealiumSdkUtils.trackView(TealiumSdkUtils.SCREEN_VIEW_FAB_PLUS, + //Need to create direct instance of AppPreferences as Injection doesn't work in Dialogs + //If we take AppPreferences as parameter in constructor it will affect the other NMC PRs test cases + AppPreferencesImpl.fromContext(fileActivity)); } private void setupClickListener() { diff --git a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java index d6725c51d7ef..54aacc0d7dc2 100644 --- a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java +++ b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java @@ -61,7 +61,11 @@ import com.nextcloud.utils.extensions.FileExtensionsKt; import com.nextcloud.utils.extensions.IntentExtensionsKt; import com.nextcloud.utils.fileNameValidator.FileNameValidator; +import com.nmc.android.marketTracking.TrackingScanInterface; import com.nextcloud.utils.view.FastScrollUtils; +import com.nmc.android.marketTracking.AdjustSdkUtils; +import com.nmc.android.marketTracking.TrackingScanInterfaceImpl; +import com.nmc.android.marketTracking.TealiumSdkUtils; import com.owncloud.android.MainApp; import com.owncloud.android.R; import com.owncloud.android.datamodel.ArbitraryDataProvider; @@ -233,6 +237,13 @@ public class OCFileListFragment extends ExtendedListFragment implements @Inject DeviceInfo deviceInfo; + /** + * Things to note about both the branches. 1. nmc/1867-scanbot branch: --> interface won't be initialised --> + * calling of interface method will be done here 2. nmc/1925-market_tracking --> interface will be initialised --> + * calling of interface method won't be done here + */ + private TrackingScanInterface trackingScanInterface; + protected enum MenuItemAddRemove { DO_NOTHING, REMOVE_SORT, @@ -257,6 +268,9 @@ public void onCreate(Bundle savedInstanceState) { } searchFragment = currentSearchType != null && isSearchEventSet(searchEvent); + + //NMC customization will be initialised in nmc/1925-market_tracking + trackingScanInterface = new TrackingScanInterfaceImpl(); } @Override @@ -520,6 +534,10 @@ public void uploadFromApp() { Intent.createChooser(action, getString(R.string.upload_chooser_title)), FileDisplayActivity.REQUEST_CODE__SELECT_CONTENT_FROM_APPS ); + + //track event photo/video/any upload button click + AdjustSdkUtils.trackEvent(AdjustSdkUtils.EVENT_TOKEN_FAB_BOTTOM_PHOTO_VIDEO_UPLOAD, preferences); + TealiumSdkUtils.trackEvent(TealiumSdkUtils.EVENT_FAB_BOTTOM_PHOTO_VIDEO_UPLOAD, preferences); } @Override @@ -537,6 +555,10 @@ public void directCameraUpload() { } showDirectCameraUploadAlertDialog(fileDisplayActivity); + + // NMC: track event for camera upload button click + AdjustSdkUtils.trackEvent(AdjustSdkUtils.EVENT_TOKEN_FAB_BOTTOM_CAMERA_UPLOAD, preferences); + TealiumSdkUtils.trackEvent(TealiumSdkUtils.EVENT_FAB_BOTTOM_CAMERA_UPLOAD, preferences); } private void showDirectCameraUploadAlertDialog(FileDisplayActivity fileDisplayActivity) { @@ -579,6 +601,10 @@ public void uploadFiles() { ((FileActivity) getActivity()).getUser().orElseThrow(RuntimeException::new), FileDisplayActivity.REQUEST_CODE__SELECT_FILES_FROM_FILE_SYSTEM, getCurrentFile().isEncrypted()); + + // track event for uploading files button click + AdjustSdkUtils.trackEvent(AdjustSdkUtils.EVENT_TOKEN_FAB_BOTTOM_FILE_UPLOAD, preferences); + TealiumSdkUtils.trackEvent(TealiumSdkUtils.EVENT_FAB_BOTTOM_FILE_UPLOAD, preferences); } @Override @@ -607,6 +633,14 @@ public void onShareIconClick(OCFile file) { mContainerActivity.getFileOperationsHelper().sendShareFile(file); }); } + + //track event on click of Share button + trackSharingClickEvent(); + } + + private void trackSharingClickEvent() { + AdjustSdkUtils.trackEvent(AdjustSdkUtils.EVENT_TOKEN_FILE_BROWSER_SHARING, preferences); + TealiumSdkUtils.trackEvent(TealiumSdkUtils.EVENT_FILE_BROWSER_SHARING, preferences); } @Override @@ -1193,6 +1227,8 @@ public boolean onFileActionChosen(@IdRes final int itemId, Set checkedFi if (itemId == R.id.action_send_share_file) { mContainerActivity.getFileOperationsHelper().sendShareFile(singleFile); + //track event on click of Share button + trackSharingClickEvent(); return true; } else if (itemId == R.id.action_open_file_with) { mContainerActivity.getFileOperationsHelper().openFile(singleFile); @@ -1223,6 +1259,9 @@ public boolean onFileActionChosen(@IdRes final int itemId, Set checkedFi mContainerActivity.showDetails(singleFile); mContainerActivity.showSortListGroup(false); + + //track event on click of Share button + trackSharingClickEvent(); return true; } else if (itemId == R.id.action_set_as_wallpaper) { mContainerActivity.getFileOperationsHelper().setPictureAs(singleFile, getView()); diff --git a/app/src/main/java/com/owncloud/android/ui/preview/FileDownloadFragment.java b/app/src/main/java/com/owncloud/android/ui/preview/FileDownloadFragment.java index 3004dce0fd36..2bdae76f8f30 100644 --- a/app/src/main/java/com/owncloud/android/ui/preview/FileDownloadFragment.java +++ b/app/src/main/java/com/owncloud/android/ui/preview/FileDownloadFragment.java @@ -25,6 +25,7 @@ import com.nextcloud.client.jobs.download.FileDownloadHelper; import com.nextcloud.utils.extensions.BundleExtensionsKt; import com.nextcloud.utils.extensions.FileExtensionsKt; +import com.nmc.android.ui.utils.ProgressBarThemeUtils; import com.owncloud.android.R; import com.owncloud.android.datamodel.OCFile; import com.owncloud.android.lib.common.network.OnDatatransferProgressListener; @@ -139,7 +140,8 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, mView = inflater.inflate(R.layout.file_download_fragment, container, false); ProgressBar progressBar = mView.findViewById(R.id.progressBar); - viewThemeUtils.platform.themeHorizontalProgressBar(progressBar); + //NMC Customization + ProgressBarThemeUtils.themeHorizontalProgressBar(progressBar, getResources().getColor(R.color.primary, null)); mProgressListener = new ProgressListener(progressBar); (mView.findViewById(R.id.cancelBtn)).setOnClickListener(this); diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 947a61daeb76..102179c9092a 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -219,6 +219,7 @@ Zu sichernde Daten Zugangsdaten falsch Benutzerkonto löschen + Konto %s und alle lokalen Dateien löschen?\n\nLöschung kann nicht rückgängig gemacht werden. Einträgen entfernen Link löschen Auswahl aufheben diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5cdc8b30bd8d..6b4c2b4ff14d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -185,6 +185,7 @@ Request deletion Request permanent deletion of account by service provider Remove account + Remove account %s and delete all local files?\n\nDeletion cannot be undone. Avatar Active user Upload from… diff --git a/gradle.properties b/gradle.properties index 8a056693e8ea..9d5ed622fef4 100644 --- a/gradle.properties +++ b/gradle.properties @@ -10,7 +10,7 @@ android.useAndroidX=true android.nonTransitiveRClass=false android.nonFinalResIds=false #android.debug.obsoleteApi=true - +ADJUST_APP_TOKEN="54qd7rraqav4" # JVM arguments to optimize heap usage, enable heap dump on out-of-memory errors, and set the file encoding org.gradle.jvmargs=-Xmx4g -XX:MaxMetaspaceSize=1g -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 diff --git a/nmc_marketing-dependencies.gradle b/nmc_marketing-dependencies.gradle new file mode 100644 index 000000000000..79cc28d01fb6 --- /dev/null +++ b/nmc_marketing-dependencies.gradle @@ -0,0 +1,23 @@ +allprojects { + repositories { + jcenter() + maven { + url "https://maven.tealiumiq.com/android/releases/" + } + } +} + +android { + buildTypes.each { + it.buildConfigField "String", "ADJUST_APP_TOKEN", "${ADJUST_APP_TOKEN}" + } +} + +dependencies { + //Adjust SDK --> https://github.com/adjust/android_sdk + implementation 'com.adjust.sdk:adjust-android:4.28.1' + implementation 'com.android.installreferrer:installreferrer:2.2' + + //tealium sdk + implementation 'com.tealium:library:5.8.0' +} \ No newline at end of file