Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[stable-3.30] Nmc/1925 Market tracking #282

Open
wants to merge 1 commit into
base: stable-3.30
Choose a base branch
from
Open
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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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()}"

Expand Down Expand Up @@ -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 {
Expand Down
11 changes: 11 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +606,17 @@
android:name="com.nextcloud.client.etm.EtmActivity"
android:exported="false"
android:theme="@style/Theme.ownCloud.Toolbar" />

<!-- Adjust SDK Declarations -->
<receiver
android:name="com.adjust.sdk.AdjustReferrerReceiver"
android:exported="true"
android:permission="android.permission.INSTALL_PACKAGES">
<intent-filter>
<action android:name="com.android.vending.INSTALL_REFERRER" />
</intent-filter>
</receiver>

<activity
android:name=".ui.preview.PreviewBitmapActivity"
android:exported="false"
Expand Down
7 changes: 5 additions & 2 deletions app/src/main/java/com/nextcloud/client/di/ActivityInjector.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import android.app.Activity
import android.app.Application.ActivityLifecycleCallbacks
import android.os.Bundle
import androidx.fragment.app.FragmentActivity
import com.adjust.sdk.Adjust
import dagger.android.AndroidInjection

class ActivityInjector : ActivityLifecycleCallbacks {
Expand All @@ -28,11 +29,13 @@ class ActivityInjector : ActivityLifecycleCallbacks {
}

override fun onActivityResumed(activity: Activity) {
// unused atm
// NMC Customization
Adjust.onResume()
}

override fun onActivityPaused(activity: Activity) {
// unused atm
// NMC Customization
Adjust.onPause()
}

override fun onActivityStopped(activity: Activity) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
67 changes: 67 additions & 0 deletions app/src/main/java/com/nmc/android/marketTracking/AdjustSdkUtils.kt
Original file line number Diff line number Diff line change
@@ -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)
}
}
}
107 changes: 107 additions & 0 deletions app/src/main/java/com/nmc/android/marketTracking/TealiumSdkUtils.kt
Original file line number Diff line number Diff line change
@@ -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)
}
}
}
Original file line number Diff line number Diff line change
@@ -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)
}
Original file line number Diff line number Diff line change
@@ -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)
}
}
9 changes: 9 additions & 0 deletions app/src/main/java/com/nmc/android/ui/PrivacyUserAction.kt
Original file line number Diff line number Diff line change
@@ -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
}
13 changes: 13 additions & 0 deletions app/src/main/java/com/owncloud/android/MainApp.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -967,6 +974,12 @@ public AndroidInjector<Object> 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);
Expand Down
Loading