Init analytics modules (#350)
This commit is contained in:
@@ -20,3 +20,8 @@ plugins {
|
||||
android {
|
||||
namespace = "io.element.android.services.analytics.api"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api(projects.services.analyticsproviders.api)
|
||||
implementation(libs.coroutines.core)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 2023 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.element.android.services.analytics.api
|
||||
|
||||
import io.element.android.services.analyticsproviders.api.AnalyticsProvider
|
||||
import io.element.android.services.analyticsproviders.api.trackers.AnalyticsTracker
|
||||
import io.element.android.services.analyticsproviders.api.trackers.ErrorTracker
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
interface AnalyticsService: AnalyticsTracker, ErrorTracker {
|
||||
fun getAvailableAnalyticsProviders(): List<AnalyticsProvider>
|
||||
|
||||
/**
|
||||
* Return a Flow of Boolean, true if the user has given their consent.
|
||||
*/
|
||||
fun getUserConsent(): Flow<Boolean>
|
||||
|
||||
/**
|
||||
* Update the user consent value.
|
||||
*/
|
||||
suspend fun setUserConsent(userConsent: Boolean)
|
||||
|
||||
/**
|
||||
* Return a Flow of Boolean, true if the user has been asked for their consent.
|
||||
*/
|
||||
fun didAskUserConsent(): Flow<Boolean>
|
||||
|
||||
/**
|
||||
* Store the fact that the user has been asked for their consent.
|
||||
*/
|
||||
suspend fun setDidAskUserConsent()
|
||||
|
||||
/**
|
||||
* Return a Flow of String, used for analytics Id.
|
||||
*/
|
||||
fun getAnalyticsId(): Flow<String>
|
||||
|
||||
/**
|
||||
* Update analyticsId from the AccountData.
|
||||
*/
|
||||
suspend fun setAnalyticsId(analyticsId: String)
|
||||
|
||||
/**
|
||||
* To be called when a session is destroyed.
|
||||
*/
|
||||
suspend fun onSignOut()
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.element.android.services.analytics.api.plan
|
||||
|
||||
import io.element.android.services.analytics.api.VectorAnalyticsEvent
|
||||
|
||||
// GENERATED FILE, DO NOT EDIT. FOR MORE INFORMATION VISIT
|
||||
// https://github.com/matrix-org/matrix-analytics-events/
|
||||
|
||||
/**
|
||||
* Triggered when a call has ended.
|
||||
*/
|
||||
data class CallEnded(
|
||||
/**
|
||||
* The duration of the call in milliseconds.
|
||||
*/
|
||||
val durationMs: Int,
|
||||
/**
|
||||
* Whether its a video call or not.
|
||||
*/
|
||||
val isVideo: Boolean,
|
||||
/**
|
||||
* Number of participants in the call.
|
||||
*/
|
||||
val numParticipants: Int,
|
||||
/**
|
||||
* Whether this user placed it.
|
||||
*/
|
||||
val placed: Boolean,
|
||||
) : VectorAnalyticsEvent {
|
||||
|
||||
override fun getName() = "CallEnded"
|
||||
|
||||
override fun getProperties(): Map<String, Any>? {
|
||||
return mutableMapOf<String, Any>().apply {
|
||||
put("durationMs", durationMs)
|
||||
put("isVideo", isVideo)
|
||||
put("numParticipants", numParticipants)
|
||||
put("placed", placed)
|
||||
}.takeIf { it.isNotEmpty() }
|
||||
}
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.element.android.services.analytics.api.plan
|
||||
|
||||
import io.element.android.services.analytics.api.VectorAnalyticsEvent
|
||||
|
||||
// GENERATED FILE, DO NOT EDIT. FOR MORE INFORMATION VISIT
|
||||
// https://github.com/matrix-org/matrix-analytics-events/
|
||||
|
||||
/**
|
||||
* Triggered when an error occurred in a call.
|
||||
*/
|
||||
data class CallError(
|
||||
/**
|
||||
* Whether its a video call or not.
|
||||
*/
|
||||
val isVideo: Boolean,
|
||||
/**
|
||||
* Number of participants in the call.
|
||||
*/
|
||||
val numParticipants: Int,
|
||||
/**
|
||||
* Whether this user placed it.
|
||||
*/
|
||||
val placed: Boolean,
|
||||
) : VectorAnalyticsEvent {
|
||||
|
||||
override fun getName() = "CallError"
|
||||
|
||||
override fun getProperties(): Map<String, Any>? {
|
||||
return mutableMapOf<String, Any>().apply {
|
||||
put("isVideo", isVideo)
|
||||
put("numParticipants", numParticipants)
|
||||
put("placed", placed)
|
||||
}.takeIf { it.isNotEmpty() }
|
||||
}
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.element.android.services.analytics.api.plan
|
||||
|
||||
import io.element.android.services.analytics.api.VectorAnalyticsEvent
|
||||
|
||||
// GENERATED FILE, DO NOT EDIT. FOR MORE INFORMATION VISIT
|
||||
// https://github.com/matrix-org/matrix-analytics-events/
|
||||
|
||||
/**
|
||||
* Triggered when a call is started.
|
||||
*/
|
||||
data class CallStarted(
|
||||
/**
|
||||
* Whether its a video call or not.
|
||||
*/
|
||||
val isVideo: Boolean,
|
||||
/**
|
||||
* Number of participants in the call.
|
||||
*/
|
||||
val numParticipants: Int,
|
||||
/**
|
||||
* Whether this user placed it.
|
||||
*/
|
||||
val placed: Boolean,
|
||||
) : VectorAnalyticsEvent {
|
||||
|
||||
override fun getName() = "CallStarted"
|
||||
|
||||
override fun getProperties(): Map<String, Any>? {
|
||||
return mutableMapOf<String, Any>().apply {
|
||||
put("isVideo", isVideo)
|
||||
put("numParticipants", numParticipants)
|
||||
put("placed", placed)
|
||||
}.takeIf { it.isNotEmpty() }
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.element.android.services.analytics.api.plan
|
||||
|
||||
import io.element.android.services.analytics.api.VectorAnalyticsEvent
|
||||
|
||||
// GENERATED FILE, DO NOT EDIT. FOR MORE INFORMATION VISIT
|
||||
// https://github.com/matrix-org/matrix-analytics-events/
|
||||
|
||||
/**
|
||||
* Triggered when the user sends a message via the composer.
|
||||
*/
|
||||
data class Composer(
|
||||
/**
|
||||
* Whether the user was using the composer inside of a thread.
|
||||
*/
|
||||
val inThread: Boolean,
|
||||
/**
|
||||
* Whether the user's composer interaction was editing a previously sent
|
||||
* event.
|
||||
*/
|
||||
val isEditing: Boolean,
|
||||
/**
|
||||
* Whether the user's composer interaction was a reply to a previously
|
||||
* sent event.
|
||||
*/
|
||||
val isReply: Boolean,
|
||||
/**
|
||||
* Whether this message begins a new thread or not.
|
||||
*/
|
||||
val startsThread: Boolean? = null,
|
||||
) : VectorAnalyticsEvent {
|
||||
|
||||
override fun getName() = "Composer"
|
||||
|
||||
override fun getProperties(): Map<String, Any>? {
|
||||
return mutableMapOf<String, Any>().apply {
|
||||
put("inThread", inThread)
|
||||
put("isEditing", isEditing)
|
||||
put("isReply", isReply)
|
||||
startsThread?.let { put("startsThread", it) }
|
||||
}.takeIf { it.isNotEmpty() }
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.element.android.services.analytics.api.plan
|
||||
|
||||
import io.element.android.services.analytics.api.VectorAnalyticsEvent
|
||||
|
||||
// GENERATED FILE, DO NOT EDIT. FOR MORE INFORMATION VISIT
|
||||
// https://github.com/matrix-org/matrix-analytics-events/
|
||||
|
||||
/**
|
||||
* Triggered when the user creates a room.
|
||||
*/
|
||||
data class CreatedRoom(
|
||||
/**
|
||||
* Whether the room is a DM.
|
||||
*/
|
||||
val isDM: Boolean,
|
||||
) : VectorAnalyticsEvent {
|
||||
|
||||
override fun getName() = "CreatedRoom"
|
||||
|
||||
override fun getProperties(): Map<String, Any>? {
|
||||
return mutableMapOf<String, Any>().apply {
|
||||
put("isDM", isDM)
|
||||
}.takeIf { it.isNotEmpty() }
|
||||
}
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.element.android.services.analytics.api.plan
|
||||
|
||||
import io.element.android.services.analytics.api.VectorAnalyticsEvent
|
||||
|
||||
// GENERATED FILE, DO NOT EDIT. FOR MORE INFORMATION VISIT
|
||||
// https://github.com/matrix-org/matrix-analytics-events/
|
||||
|
||||
/**
|
||||
* Triggered when an error occurred.
|
||||
*/
|
||||
data class Error(
|
||||
/**
|
||||
* Context - client defined, can be used for debugging.
|
||||
*/
|
||||
val context: String? = null,
|
||||
/**
|
||||
* Which crypto module is the client currently using.
|
||||
*/
|
||||
val cryptoModule: CryptoModule? = null,
|
||||
val domain: Domain,
|
||||
val name: Name,
|
||||
) : VectorAnalyticsEvent {
|
||||
|
||||
enum class Domain {
|
||||
E2EE,
|
||||
TO_DEVICE,
|
||||
VOIP,
|
||||
}
|
||||
|
||||
enum class Name {
|
||||
OlmIndexError,
|
||||
OlmKeysNotSentError,
|
||||
OlmUnspecifiedError,
|
||||
ToDeviceFailedToDecrypt,
|
||||
UnknownError,
|
||||
VoipIceFailed,
|
||||
VoipIceTimeout,
|
||||
VoipInviteTimeout,
|
||||
VoipUserHangup,
|
||||
VoipUserMediaFailed,
|
||||
}
|
||||
|
||||
enum class CryptoModule {
|
||||
|
||||
/**
|
||||
* Native / legacy crypto module specific to each platform.
|
||||
*/
|
||||
Native,
|
||||
|
||||
/**
|
||||
* Shared / cross-platform crypto module written in Rust.
|
||||
*/
|
||||
Rust,
|
||||
}
|
||||
|
||||
override fun getName() = "Error"
|
||||
|
||||
override fun getProperties(): Map<String, Any>? {
|
||||
return mutableMapOf<String, Any>().apply {
|
||||
context?.let { put("context", it) }
|
||||
cryptoModule?.let { put("cryptoModule", it.name) }
|
||||
put("domain", domain.name)
|
||||
put("name", name.name)
|
||||
}.takeIf { it.isNotEmpty() }
|
||||
}
|
||||
}
|
||||
@@ -1,468 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.element.android.services.analytics.api.plan
|
||||
|
||||
import io.element.android.services.analytics.api.VectorAnalyticsEvent
|
||||
|
||||
// GENERATED FILE, DO NOT EDIT. FOR MORE INFORMATION VISIT
|
||||
// https://github.com/matrix-org/matrix-analytics-events/
|
||||
|
||||
/**
|
||||
* Triggered when the user clicks/taps/activates a UI element.
|
||||
*/
|
||||
data class Interaction(
|
||||
/**
|
||||
* The index of the element, if its in a list of elements.
|
||||
*/
|
||||
val index: Int? = null,
|
||||
/**
|
||||
* The manner with which the user activated the UI element.
|
||||
*/
|
||||
val interactionType: InteractionType? = null,
|
||||
/**
|
||||
* The unique name of this element.
|
||||
*/
|
||||
val name: Name,
|
||||
) : VectorAnalyticsEvent {
|
||||
|
||||
enum class Name {
|
||||
/**
|
||||
* User tapped the All filter in the All Chats filter tab.
|
||||
*/
|
||||
MobileAllChatsFilterAll,
|
||||
|
||||
/**
|
||||
* User tapped the Favourites filter in the All Chats filter tab.
|
||||
*/
|
||||
MobileAllChatsFilterFavourites,
|
||||
|
||||
/**
|
||||
* User tapped the People filter in the All Chats filter tab.
|
||||
*/
|
||||
MobileAllChatsFilterPeople,
|
||||
|
||||
/**
|
||||
* User tapped the Unreads filter in the All Chats filter tab.
|
||||
*/
|
||||
MobileAllChatsFilterUnreads,
|
||||
|
||||
/**
|
||||
* User disabled filters from the all chats layout settings.
|
||||
*/
|
||||
MobileAllChatsFiltersDisabled,
|
||||
|
||||
/**
|
||||
* User enabled filters from the all chats layout settings.
|
||||
*/
|
||||
MobileAllChatsFiltersEnabled,
|
||||
|
||||
/**
|
||||
* User disabled recents from the all chats layout settings.
|
||||
*/
|
||||
MobileAllChatsRecentsDisabled,
|
||||
|
||||
/**
|
||||
* User enabled recents from the all chats layout settings.
|
||||
*/
|
||||
MobileAllChatsRecentsEnabled,
|
||||
|
||||
/**
|
||||
* User tapped on Add to Home button on Room Details screen.
|
||||
*/
|
||||
MobileRoomAddHome,
|
||||
|
||||
/**
|
||||
* User tapped on Leave Room button on Room Details screen.
|
||||
*/
|
||||
MobileRoomLeave,
|
||||
|
||||
/**
|
||||
* User tapped on Threads button on Room screen.
|
||||
*/
|
||||
MobileRoomThreadListButton,
|
||||
|
||||
/**
|
||||
* User tapped on a thread summary item on Room screen.
|
||||
*/
|
||||
MobileRoomThreadSummaryItem,
|
||||
|
||||
/**
|
||||
* User validated the creation of a new space.
|
||||
*/
|
||||
MobileSpaceCreationValidated,
|
||||
|
||||
/**
|
||||
* User tapped on the filter button on ThreadList screen.
|
||||
*/
|
||||
MobileThreadListFilterItem,
|
||||
|
||||
/**
|
||||
* User selected a thread on ThreadList screen.
|
||||
*/
|
||||
MobileThreadListThreadItem,
|
||||
|
||||
/**
|
||||
* User tapped the already selected space from the space list.
|
||||
*/
|
||||
SpacePanelSelectedSpace,
|
||||
|
||||
/**
|
||||
* User tapped an unselected space from the space list -> space
|
||||
* switching should occur.
|
||||
*/
|
||||
SpacePanelSwitchSpace,
|
||||
|
||||
/**
|
||||
* User tapped an unselected sub space from the space list -> space
|
||||
* switching should occur.
|
||||
*/
|
||||
SpacePanelSwitchSubSpace,
|
||||
|
||||
/**
|
||||
* User clicked the create room button in the add existing room to space
|
||||
* dialog in Element Web/Desktop.
|
||||
*/
|
||||
WebAddExistingToSpaceDialogCreateRoomButton,
|
||||
|
||||
/**
|
||||
* User clicked the create DM button in the home page of Element
|
||||
* Web/Desktop.
|
||||
*/
|
||||
WebHomeCreateChatButton,
|
||||
|
||||
/**
|
||||
* User clicked the create room button in the home page of Element
|
||||
* Web/Desktop.
|
||||
*/
|
||||
WebHomeCreateRoomButton,
|
||||
|
||||
/**
|
||||
* User clicked the explore rooms button in the home page of Element
|
||||
* Web/Desktop.
|
||||
*/
|
||||
WebHomeExploreRoomsButton,
|
||||
|
||||
/**
|
||||
* User clicked on the mini avatar uploader in the home page of Element
|
||||
* Web/Desktop.
|
||||
*/
|
||||
WebHomeMiniAvatarUploadButton,
|
||||
|
||||
/**
|
||||
* User clicked the explore rooms button next to the search field at the
|
||||
* top of the left panel in Element Web/Desktop.
|
||||
*/
|
||||
WebLeftPanelExploreRoomsButton,
|
||||
|
||||
/**
|
||||
* User clicked on the avatar uploader in the profile settings of
|
||||
* Element Web/Desktop.
|
||||
*/
|
||||
WebProfileSettingsAvatarUploadButton,
|
||||
|
||||
/**
|
||||
* User interacted with pin to sidebar checkboxes in the quick settings
|
||||
* menu of Element Web/Desktop.
|
||||
*/
|
||||
WebQuickSettingsPinToSidebarCheckbox,
|
||||
|
||||
/**
|
||||
* User interacted with the theme dropdown in the quick settings menu of
|
||||
* Element Web/Desktop.
|
||||
*/
|
||||
WebQuickSettingsThemeDropdown,
|
||||
|
||||
/**
|
||||
* User accessed the room invite flow using the button at the top of the
|
||||
* room member list in the right panel of Element Web/Desktop.
|
||||
*/
|
||||
WebRightPanelMemberListInviteButton,
|
||||
|
||||
/**
|
||||
* User accessed room member list using the 'People' button in the right
|
||||
* panel room summary card of Element Web/Desktop.
|
||||
*/
|
||||
WebRightPanelRoomInfoPeopleButton,
|
||||
|
||||
/**
|
||||
* User accessed room settings using the 'Settings' button in the right
|
||||
* panel room summary card of Element Web/Desktop.
|
||||
*/
|
||||
WebRightPanelRoomInfoSettingsButton,
|
||||
|
||||
/**
|
||||
* User accessed room member list using the back button in the right
|
||||
* panel user info card of Element Web/Desktop.
|
||||
*/
|
||||
WebRightPanelRoomUserInfoBackButton,
|
||||
|
||||
/**
|
||||
* User invited someone to room by clicking invite on the right panel
|
||||
* user info card in Element Web/Desktop.
|
||||
*/
|
||||
WebRightPanelRoomUserInfoInviteButton,
|
||||
|
||||
/**
|
||||
* User clicked the threads 'show' filter dropdown in the threads panel
|
||||
* in Element Web/Desktop.
|
||||
*/
|
||||
WebRightPanelThreadPanelFilterDropdown,
|
||||
|
||||
/**
|
||||
* User clicked the create room button in the room directory of Element
|
||||
* Web/Desktop.
|
||||
*/
|
||||
WebRoomDirectoryCreateRoomButton,
|
||||
|
||||
/**
|
||||
* User clicked the Threads button in the top right of a room in Element
|
||||
* Web/Desktop.
|
||||
*/
|
||||
WebRoomHeaderButtonsThreadsButton,
|
||||
|
||||
/**
|
||||
* User adjusted their favourites using the context menu on the header
|
||||
* of a room in Element Web/Desktop.
|
||||
*/
|
||||
WebRoomHeaderContextMenuFavouriteToggle,
|
||||
|
||||
/**
|
||||
* User accessed the room invite flow using the context menu on the
|
||||
* header of a room in Element Web/Desktop.
|
||||
*/
|
||||
WebRoomHeaderContextMenuInviteItem,
|
||||
|
||||
/**
|
||||
* User interacted with leave action in the context menu on the header
|
||||
* of a room in Element Web/Desktop.
|
||||
*/
|
||||
WebRoomHeaderContextMenuLeaveItem,
|
||||
|
||||
/**
|
||||
* User accessed their room notification settings via the context menu
|
||||
* on the header of a room in Element Web/Desktop.
|
||||
*/
|
||||
WebRoomHeaderContextMenuNotificationsItem,
|
||||
|
||||
/**
|
||||
* User accessed room member list using the context menu on the header
|
||||
* of a room in Element Web/Desktop.
|
||||
*/
|
||||
WebRoomHeaderContextMenuPeopleItem,
|
||||
|
||||
/**
|
||||
* User accessed room settings using the context menu on the header of a
|
||||
* room in Element Web/Desktop.
|
||||
*/
|
||||
WebRoomHeaderContextMenuSettingsItem,
|
||||
|
||||
/**
|
||||
* User clicked the create DM button in the + context menu of the room
|
||||
* list header in Element Web/Desktop.
|
||||
*/
|
||||
WebRoomListHeaderPlusMenuCreateChatItem,
|
||||
|
||||
/**
|
||||
* User clicked the create room button in the + context menu of the room
|
||||
* list header in Element Web/Desktop.
|
||||
*/
|
||||
WebRoomListHeaderPlusMenuCreateRoomItem,
|
||||
|
||||
/**
|
||||
* User clicked the explore rooms button in the + context menu of the
|
||||
* room list header in Element Web/Desktop.
|
||||
*/
|
||||
WebRoomListHeaderPlusMenuExploreRoomsItem,
|
||||
|
||||
/**
|
||||
* User adjusted their favourites using the context menu on a room tile
|
||||
* in the room list in Element Web/Desktop.
|
||||
*/
|
||||
WebRoomListRoomTileContextMenuFavouriteToggle,
|
||||
|
||||
/**
|
||||
* User accessed the room invite flow using the context menu on a room
|
||||
* tile in the room list in Element Web/Desktop.
|
||||
*/
|
||||
WebRoomListRoomTileContextMenuInviteItem,
|
||||
|
||||
/**
|
||||
* User interacted with leave action in the context menu on a room tile
|
||||
* in the room list in Element Web/Desktop.
|
||||
*/
|
||||
WebRoomListRoomTileContextMenuLeaveItem,
|
||||
|
||||
/**
|
||||
* User accessed room settings using the context menu on a room tile in
|
||||
* the room list in Element Web/Desktop.
|
||||
*/
|
||||
WebRoomListRoomTileContextMenuSettingsItem,
|
||||
|
||||
/**
|
||||
* User accessed their room notification settings via the context menu
|
||||
* on a room tile in the room list in Element Web/Desktop.
|
||||
*/
|
||||
WebRoomListRoomTileNotificationsMenu,
|
||||
|
||||
/**
|
||||
* User clicked the create DM button in the + context menu of the rooms
|
||||
* sublist in Element Web/Desktop.
|
||||
*/
|
||||
WebRoomListRoomsSublistPlusMenuCreateChatItem,
|
||||
|
||||
/**
|
||||
* User clicked the create room button in the + context menu of the
|
||||
* rooms sublist in Element Web/Desktop.
|
||||
*/
|
||||
WebRoomListRoomsSublistPlusMenuCreateRoomItem,
|
||||
|
||||
/**
|
||||
* User clicked the explore rooms button in the + context menu of the
|
||||
* rooms sublist in Element Web/Desktop.
|
||||
*/
|
||||
WebRoomListRoomsSublistPlusMenuExploreRoomsItem,
|
||||
|
||||
/**
|
||||
* User clicked on the button to return to the user onboarding list in
|
||||
* the room list in Element Web/Desktop.
|
||||
*/
|
||||
WebRoomListUserOnboardingButton,
|
||||
|
||||
/**
|
||||
* User clicked on the button to close the user onboarding button in the
|
||||
* room list in Element Web/Desktop.
|
||||
*/
|
||||
WebRoomListUserOnboardingIgnoreButton,
|
||||
|
||||
/**
|
||||
* User interacted with leave action in the general tab of the room
|
||||
* settings dialog in Element Web/Desktop.
|
||||
*/
|
||||
WebRoomSettingsLeaveButton,
|
||||
|
||||
/**
|
||||
* User interacted with the prompt to create a new room when adjusting
|
||||
* security settings in an existing room in Element Web/Desktop.
|
||||
*/
|
||||
WebRoomSettingsSecurityTabCreateNewRoomButton,
|
||||
|
||||
/**
|
||||
* User clicked a thread summary in the timeline of a room in Element
|
||||
* Web/Desktop.
|
||||
*/
|
||||
WebRoomTimelineThreadSummaryButton,
|
||||
|
||||
/**
|
||||
* User interacted with the theme radio selector in the Appearance tab
|
||||
* of Settings in Element Web/Desktop.
|
||||
*/
|
||||
WebSettingsAppearanceTabThemeSelector,
|
||||
|
||||
/**
|
||||
* User interacted with the pre-built space checkboxes in the Sidebar
|
||||
* tab of Settings in Element Web/Desktop.
|
||||
*/
|
||||
WebSettingsSidebarTabSpacesCheckbox,
|
||||
|
||||
/**
|
||||
* User clicked the explore rooms button in the context menu of a space
|
||||
* in Element Web/Desktop.
|
||||
*/
|
||||
WebSpaceContextMenuExploreRoomsItem,
|
||||
|
||||
/**
|
||||
* User clicked the home button in the context menu of a space in
|
||||
* Element Web/Desktop.
|
||||
*/
|
||||
WebSpaceContextMenuHomeItem,
|
||||
|
||||
/**
|
||||
* User clicked the new room button in the context menu of a space in
|
||||
* Element Web/Desktop.
|
||||
*/
|
||||
WebSpaceContextMenuNewRoomItem,
|
||||
|
||||
/**
|
||||
* User clicked the new room button in the context menu on the space
|
||||
* home in Element Web/Desktop.
|
||||
*/
|
||||
WebSpaceHomeCreateRoomButton,
|
||||
|
||||
/**
|
||||
* User clicked the back button on a Thread view going back to the
|
||||
* Threads Panel of Element Web/Desktop.
|
||||
*/
|
||||
WebThreadViewBackButton,
|
||||
|
||||
/**
|
||||
* User selected a thread in the Threads panel in Element Web/Desktop.
|
||||
*/
|
||||
WebThreadsPanelThreadItem,
|
||||
|
||||
/**
|
||||
* User clicked the theme toggle button in the user menu of Element
|
||||
* Web/Desktop.
|
||||
*/
|
||||
WebUserMenuThemeToggleButton,
|
||||
|
||||
/**
|
||||
* User clicked on the send DM CTA in the header of the new user
|
||||
* onboarding page in Element Web/Desktop.
|
||||
*/
|
||||
WebUserOnboardingHeaderSendDm,
|
||||
|
||||
/**
|
||||
* User clicked on the action of the download apps task on the new user
|
||||
* onboarding page in Element Web/Desktop.
|
||||
*/
|
||||
WebUserOnboardingTaskDownloadApps,
|
||||
|
||||
/**
|
||||
* User clicked on the action of the enable notifications task on the
|
||||
* new user onboarding page in Element Web/Desktop.
|
||||
*/
|
||||
WebUserOnboardingTaskEnableNotifications,
|
||||
|
||||
/**
|
||||
* User clicked on the action of the find people task on the new user
|
||||
* onboarding page in Element Web/Desktop.
|
||||
*/
|
||||
WebUserOnboardingTaskSendDm,
|
||||
|
||||
/**
|
||||
* User clicked on the action of the your profile task on the new user
|
||||
* onboarding page in Element Web/Desktop.
|
||||
*/
|
||||
WebUserOnboardingTaskSetupProfile,
|
||||
}
|
||||
|
||||
enum class InteractionType {
|
||||
Keyboard,
|
||||
Pointer,
|
||||
Touch,
|
||||
}
|
||||
|
||||
override fun getName() = "Interaction"
|
||||
|
||||
override fun getProperties(): Map<String, Any>? {
|
||||
return mutableMapOf<String, Any>().apply {
|
||||
index?.let { put("index", it) }
|
||||
interactionType?.let { put("interactionType", it.name) }
|
||||
put("name", name.name)
|
||||
}.takeIf { it.isNotEmpty() }
|
||||
}
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.element.android.services.analytics.api.plan
|
||||
|
||||
import io.element.android.services.analytics.api.VectorAnalyticsEvent
|
||||
|
||||
// GENERATED FILE, DO NOT EDIT. FOR MORE INFORMATION VISIT
|
||||
// https://github.com/matrix-org/matrix-analytics-events/
|
||||
|
||||
/**
|
||||
* Triggered when the user joins a room.
|
||||
*/
|
||||
data class JoinedRoom(
|
||||
/**
|
||||
* Whether the room is a DM.
|
||||
*/
|
||||
val isDM: Boolean,
|
||||
/**
|
||||
* Whether the room is a Space.
|
||||
*/
|
||||
val isSpace: Boolean,
|
||||
/**
|
||||
* The size of the room.
|
||||
*/
|
||||
val roomSize: RoomSize,
|
||||
/**
|
||||
* The trigger for a room being joined if known.
|
||||
*/
|
||||
val trigger: Trigger? = null,
|
||||
) : VectorAnalyticsEvent {
|
||||
|
||||
enum class Trigger {
|
||||
/**
|
||||
* Room joined via an invite.
|
||||
*/
|
||||
Invite,
|
||||
|
||||
/**
|
||||
* Room joined via link.
|
||||
*/
|
||||
MobilePermalink,
|
||||
|
||||
/**
|
||||
* Room joined via a push/desktop notification.
|
||||
*/
|
||||
Notification,
|
||||
|
||||
/**
|
||||
* Room joined via the public rooms directory.
|
||||
*/
|
||||
RoomDirectory,
|
||||
|
||||
/**
|
||||
* Room joined via its preview.
|
||||
*/
|
||||
RoomPreview,
|
||||
|
||||
/**
|
||||
* Room joined via the /join slash command.
|
||||
*/
|
||||
SlashCommand,
|
||||
|
||||
/**
|
||||
* Room joined via the space hierarchy view.
|
||||
*/
|
||||
SpaceHierarchy,
|
||||
|
||||
/**
|
||||
* Room joined via a timeline pill or link in another room.
|
||||
*/
|
||||
Timeline,
|
||||
}
|
||||
|
||||
enum class RoomSize {
|
||||
ElevenToOneHundred,
|
||||
MoreThanAThousand,
|
||||
One,
|
||||
OneHundredAndOneToAThousand,
|
||||
ThreeToTen,
|
||||
Two,
|
||||
}
|
||||
|
||||
override fun getName() = "JoinedRoom"
|
||||
|
||||
override fun getProperties(): Map<String, Any>? {
|
||||
return mutableMapOf<String, Any>().apply {
|
||||
put("isDM", isDM)
|
||||
put("isSpace", isSpace)
|
||||
put("roomSize", roomSize.name)
|
||||
trigger?.let { put("trigger", it.name) }
|
||||
}.takeIf { it.isNotEmpty() }
|
||||
}
|
||||
}
|
||||
@@ -1,327 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.element.android.services.analytics.api.plan
|
||||
|
||||
import io.element.android.services.analytics.api.VectorAnalyticsScreen
|
||||
|
||||
// GENERATED FILE, DO NOT EDIT. FOR MORE INFORMATION VISIT
|
||||
// https://github.com/matrix-org/matrix-analytics-events/
|
||||
|
||||
/**
|
||||
* Triggered when the user changed screen on Element Android/iOS.
|
||||
*/
|
||||
data class MobileScreen(
|
||||
/**
|
||||
* How long the screen was displayed for in milliseconds.
|
||||
*/
|
||||
val durationMs: Int? = null,
|
||||
val screenName: ScreenName,
|
||||
) : VectorAnalyticsScreen {
|
||||
|
||||
enum class ScreenName {
|
||||
/**
|
||||
* The screen that displays the user's breadcrumbs.
|
||||
*/
|
||||
Breadcrumbs,
|
||||
|
||||
/**
|
||||
* The screen shown to create a new (non-direct) room.
|
||||
*/
|
||||
CreateRoom,
|
||||
|
||||
/**
|
||||
* The screen shown to create a new space.
|
||||
*/
|
||||
CreateSpace,
|
||||
|
||||
/**
|
||||
* The confirmation screen shown before deactivating an account.
|
||||
*/
|
||||
DeactivateAccount,
|
||||
|
||||
/**
|
||||
* The tab on mobile that displays the dialpad.
|
||||
*/
|
||||
Dialpad,
|
||||
|
||||
/**
|
||||
* The Favourites tab on mobile that lists your favourite people/rooms.
|
||||
*/
|
||||
Favourites,
|
||||
|
||||
/**
|
||||
* The form for the forgot password use case.
|
||||
*/
|
||||
ForgotPassword,
|
||||
|
||||
/**
|
||||
* Legacy: The screen that shows information about a specific group.
|
||||
*/
|
||||
Group,
|
||||
|
||||
/**
|
||||
* The Home tab on iOS | possibly the same on Android?
|
||||
*/
|
||||
Home,
|
||||
|
||||
/**
|
||||
* The screen shown to share a link to download the app.
|
||||
*/
|
||||
InviteFriends,
|
||||
|
||||
/**
|
||||
* Room accessed via space bottom sheet list.
|
||||
*/
|
||||
Invites,
|
||||
|
||||
/**
|
||||
* The screen that displays the login flow (when the user already has an
|
||||
* account).
|
||||
*/
|
||||
Login,
|
||||
|
||||
/**
|
||||
* Legacy: The screen that shows all groups/communities you have joined.
|
||||
*/
|
||||
MyGroups,
|
||||
|
||||
/**
|
||||
* The People tab on mobile that lists all the DM rooms you have joined.
|
||||
*/
|
||||
People,
|
||||
|
||||
/**
|
||||
* The screen that displays the registration flow (when the user wants
|
||||
* to create an account).
|
||||
*/
|
||||
Register,
|
||||
|
||||
/**
|
||||
* The screen that displays the messages and events received in a room.
|
||||
*/
|
||||
Room,
|
||||
|
||||
/**
|
||||
* The room addresses screen shown from the Room Details screen.
|
||||
*/
|
||||
RoomAddresses,
|
||||
|
||||
/**
|
||||
* The screen shown when tapping the name of a room from the Room
|
||||
* screen.
|
||||
*/
|
||||
RoomDetailss,
|
||||
|
||||
/**
|
||||
* The screen that lists public rooms for you to discover.
|
||||
*/
|
||||
RoomDirectory,
|
||||
|
||||
/**
|
||||
* The screen that lists all the user's rooms and let them filter the
|
||||
* rooms.
|
||||
*/
|
||||
RoomFilter,
|
||||
|
||||
/**
|
||||
* The screen that displays the list of members that are part of a room.
|
||||
*/
|
||||
RoomMembers,
|
||||
|
||||
/**
|
||||
* The notifications settings screen shown from the Room Details screen.
|
||||
*/
|
||||
RoomNotifications,
|
||||
|
||||
/**
|
||||
* The roles permissions screen shown from the Room Details screen.
|
||||
*/
|
||||
RoomPermissions,
|
||||
|
||||
/**
|
||||
* Screen that displays room preview if user hasn't joined yet.
|
||||
*/
|
||||
RoomPreview,
|
||||
|
||||
/**
|
||||
* The screen that allows you to search for messages/files in a specific
|
||||
* room.
|
||||
*/
|
||||
RoomSearch,
|
||||
|
||||
/**
|
||||
* The settings screen shown from the Room Details screen.
|
||||
*/
|
||||
RoomSettings,
|
||||
|
||||
/**
|
||||
* The screen that allows you to see all of the files sent in a specific
|
||||
* room.
|
||||
*/
|
||||
RoomUploads,
|
||||
|
||||
/**
|
||||
* The Rooms tab on mobile that lists all the (non-direct) rooms you've
|
||||
* joined.
|
||||
*/
|
||||
Rooms,
|
||||
|
||||
/**
|
||||
* The Files tab shown in the global search screen on Mobile.
|
||||
*/
|
||||
SearchFiles,
|
||||
|
||||
/**
|
||||
* The Messages tab shown in the global search screen on Mobile.
|
||||
*/
|
||||
SearchMessages,
|
||||
|
||||
/**
|
||||
* The People tab shown in the global search screen on Mobile.
|
||||
*/
|
||||
SearchPeople,
|
||||
|
||||
/**
|
||||
* The Rooms tab shown in the global search screen on Mobile.
|
||||
*/
|
||||
SearchRooms,
|
||||
|
||||
/**
|
||||
* The global settings screen shown in the app.
|
||||
*/
|
||||
Settings,
|
||||
|
||||
/**
|
||||
* The advanced settings screen (developer mode, rageshake, push
|
||||
* notification rules).
|
||||
*/
|
||||
SettingsAdvanced,
|
||||
|
||||
/**
|
||||
* The settings screen to change the default notification options.
|
||||
*/
|
||||
SettingsDefaultNotifications,
|
||||
|
||||
/**
|
||||
* The settings screen with general profile settings.
|
||||
*/
|
||||
SettingsGeneral,
|
||||
|
||||
/**
|
||||
* The Help and About screen.
|
||||
*/
|
||||
SettingsHelp,
|
||||
|
||||
/**
|
||||
* The settings screen with list of the ignored users.
|
||||
*/
|
||||
SettingsIgnoredUsers,
|
||||
|
||||
/**
|
||||
* The experimental features settings screen.
|
||||
*/
|
||||
SettingsLabs,
|
||||
|
||||
/**
|
||||
* The settings screen with legals information.
|
||||
*/
|
||||
SettingsLegals,
|
||||
|
||||
/**
|
||||
* The settings screen to manage notification mentions and keywords.
|
||||
*/
|
||||
SettingsMentionsAndKeywords,
|
||||
|
||||
/**
|
||||
* The notifications settings screen.
|
||||
*/
|
||||
SettingsNotifications,
|
||||
|
||||
/**
|
||||
* The preferences screen (theme, language, editor preferences, etc.
|
||||
*/
|
||||
SettingsPreferences,
|
||||
|
||||
/**
|
||||
* The global security settings screen.
|
||||
*/
|
||||
SettingsSecurity,
|
||||
|
||||
/**
|
||||
* The calls settings screen.
|
||||
*/
|
||||
SettingsVoiceVideo,
|
||||
|
||||
/**
|
||||
* The sidebar shown on mobile with spaces, settings etc.
|
||||
*/
|
||||
Sidebar,
|
||||
|
||||
/**
|
||||
* Room accessed via space bottom sheet list.
|
||||
*/
|
||||
SpaceBottomSheet,
|
||||
|
||||
/**
|
||||
* Screen that displays the list of rooms and spaces of a space.
|
||||
*/
|
||||
SpaceExploreRooms,
|
||||
|
||||
/**
|
||||
* Screen that displays the list of members of a space.
|
||||
*/
|
||||
SpaceMembers,
|
||||
|
||||
/**
|
||||
* The bottom sheet that list all space options.
|
||||
*/
|
||||
SpaceMenu,
|
||||
|
||||
/**
|
||||
* The screen shown to create a new direct room.
|
||||
*/
|
||||
StartChat,
|
||||
|
||||
/**
|
||||
* The screen shown to select which room directory you'd like to use.
|
||||
*/
|
||||
SwitchDirectory,
|
||||
|
||||
/**
|
||||
* Screen that displays list of threads for a room.
|
||||
*/
|
||||
ThreadList,
|
||||
|
||||
/**
|
||||
* A screen that shows information about a room member.
|
||||
*/
|
||||
User,
|
||||
|
||||
/**
|
||||
* The splash screen.
|
||||
*/
|
||||
Welcome,
|
||||
}
|
||||
|
||||
override fun getName() = screenName.name
|
||||
|
||||
override fun getProperties(): Map<String, Any>? {
|
||||
return mutableMapOf<String, Any>().apply {
|
||||
durationMs?.let { put("durationMs", it) }
|
||||
}.takeIf { it.isNotEmpty() }
|
||||
}
|
||||
}
|
||||
@@ -1,109 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.element.android.services.analytics.api.plan
|
||||
|
||||
import io.element.android.services.analytics.api.VectorAnalyticsEvent
|
||||
|
||||
// GENERATED FILE, DO NOT EDIT. FOR MORE INFORMATION VISIT
|
||||
// https://github.com/matrix-org/matrix-analytics-events/
|
||||
|
||||
/**
|
||||
* Triggered after timing an operation in the app.
|
||||
*/
|
||||
data class PerformanceTimer(
|
||||
/**
|
||||
* Client defined, can be used for debugging.
|
||||
*/
|
||||
val context: String? = null,
|
||||
/**
|
||||
* Client defined, an optional value to indicate how many items were
|
||||
* handled during the operation.
|
||||
*/
|
||||
val itemCount: Int? = null,
|
||||
/**
|
||||
* The timer that is being reported.
|
||||
*/
|
||||
val name: Name,
|
||||
/**
|
||||
* The time reported by the timer in milliseconds.
|
||||
*/
|
||||
val timeMs: Int,
|
||||
) : VectorAnalyticsEvent {
|
||||
|
||||
enum class Name {
|
||||
/**
|
||||
* The time spent parsing the response from an initial /sync request. In
|
||||
* this case, `itemCount` should contain the number of joined rooms.
|
||||
*/
|
||||
InitialSyncParsing,
|
||||
|
||||
/**
|
||||
* The time spent waiting for a response to an initial /sync request. In
|
||||
* this case, `itemCount` should contain the number of joined rooms.
|
||||
*/
|
||||
InitialSyncRequest,
|
||||
|
||||
/**
|
||||
* The time taken to display an event in the timeline that was opened
|
||||
* from a notification.
|
||||
*/
|
||||
NotificationsOpenEvent,
|
||||
|
||||
/**
|
||||
* The duration of a regular /sync request when resuming the app. In
|
||||
* this case, `itemCount` should contain the number of joined rooms in
|
||||
* the response.
|
||||
*/
|
||||
StartupIncrementalSync,
|
||||
|
||||
/**
|
||||
* The duration of an initial /sync request during startup (if the store
|
||||
* has been wiped). In this case, `itemCount` should contain the number
|
||||
* of joined rooms.
|
||||
*/
|
||||
StartupInitialSync,
|
||||
|
||||
/**
|
||||
* How long the app launch screen is displayed for.
|
||||
*/
|
||||
StartupLaunchScreen,
|
||||
|
||||
/**
|
||||
* The time to preload data in the MXStore on iOS. In this case,
|
||||
* `itemCount` should contain the number of rooms in the store.
|
||||
*/
|
||||
StartupStorePreload,
|
||||
|
||||
/**
|
||||
* The time to load all data from the store (including
|
||||
* StartupStorePreload time). In this case, `itemCount` should contain
|
||||
* the number of rooms loaded into the session
|
||||
*/
|
||||
StartupStoreReady,
|
||||
}
|
||||
|
||||
override fun getName() = "PerformanceTimer"
|
||||
|
||||
override fun getProperties(): Map<String, Any>? {
|
||||
return mutableMapOf<String, Any>().apply {
|
||||
context?.let { put("context", it) }
|
||||
itemCount?.let { put("itemCount", it) }
|
||||
put("name", name.name)
|
||||
put("timeMs", timeMs)
|
||||
}.takeIf { it.isNotEmpty() }
|
||||
}
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.element.android.services.analytics.api.plan
|
||||
|
||||
import io.element.android.services.analytics.api.VectorAnalyticsEvent
|
||||
|
||||
// GENERATED FILE, DO NOT EDIT. FOR MORE INFORMATION VISIT
|
||||
// https://github.com/matrix-org/matrix-analytics-events/
|
||||
|
||||
/**
|
||||
* Triggered when the user changes a permission status.
|
||||
*/
|
||||
data class PermissionChanged(
|
||||
/**
|
||||
* Whether the permission has been granted by the user.
|
||||
*/
|
||||
val granted: Boolean,
|
||||
/**
|
||||
* The name of the permission.
|
||||
*/
|
||||
val permission: Permission,
|
||||
) : VectorAnalyticsEvent {
|
||||
|
||||
enum class Permission {
|
||||
/**
|
||||
* Permissions related to sending notifications have changed.
|
||||
*/
|
||||
Notification,
|
||||
}
|
||||
|
||||
override fun getName() = "PermissionChanged"
|
||||
|
||||
override fun getProperties(): Map<String, Any>? {
|
||||
return mutableMapOf<String, Any>().apply {
|
||||
put("granted", granted)
|
||||
put("permission", permission.name)
|
||||
}.takeIf { it.isNotEmpty() }
|
||||
}
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.element.android.services.analytics.api.plan
|
||||
|
||||
import io.element.android.services.analytics.api.VectorAnalyticsEvent
|
||||
|
||||
// GENERATED FILE, DO NOT EDIT. FOR MORE INFORMATION VISIT
|
||||
// https://github.com/matrix-org/matrix-analytics-events/
|
||||
|
||||
/**
|
||||
* Triggered once onboarding has completed, but only if the user registered a
|
||||
* new account.
|
||||
*/
|
||||
data class Signup(
|
||||
/**
|
||||
* The type of authentication that was used to sign up.
|
||||
*/
|
||||
val authenticationType: AuthenticationType,
|
||||
) : VectorAnalyticsEvent {
|
||||
|
||||
enum class AuthenticationType {
|
||||
/**
|
||||
* Social login using Apple.
|
||||
*/
|
||||
Apple,
|
||||
|
||||
/**
|
||||
* Social login using Facebook.
|
||||
*/
|
||||
Facebook,
|
||||
|
||||
/**
|
||||
* Social login using GitHub.
|
||||
*/
|
||||
GitHub,
|
||||
|
||||
/**
|
||||
* Social login using GitLab.
|
||||
*/
|
||||
GitLab,
|
||||
|
||||
/**
|
||||
* Social login using Google.
|
||||
*/
|
||||
Google,
|
||||
|
||||
/**
|
||||
* Registration using some other mechanism such as fallback.
|
||||
*/
|
||||
Other,
|
||||
|
||||
/**
|
||||
* Registration with a username and password.
|
||||
*/
|
||||
Password,
|
||||
|
||||
/**
|
||||
* Registration using another SSO provider.
|
||||
*/
|
||||
SSO,
|
||||
}
|
||||
|
||||
override fun getName() = "Signup"
|
||||
|
||||
override fun getProperties(): Map<String, Any>? {
|
||||
return mutableMapOf<String, Any>().apply {
|
||||
put("authenticationType", authenticationType.name)
|
||||
}.takeIf { it.isNotEmpty() }
|
||||
}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.element.android.services.analytics.api.plan
|
||||
|
||||
import io.element.android.services.analytics.api.VectorAnalyticsEvent
|
||||
|
||||
// GENERATED FILE, DO NOT EDIT. FOR MORE INFORMATION VISIT
|
||||
// https://github.com/matrix-org/matrix-analytics-events/
|
||||
|
||||
/**
|
||||
* Triggered when the user runs a slash command in their composer.
|
||||
*/
|
||||
data class SlashCommand(
|
||||
/**
|
||||
* The name of this command.
|
||||
*/
|
||||
val command: Command,
|
||||
) : VectorAnalyticsEvent {
|
||||
|
||||
enum class Command {
|
||||
Invite,
|
||||
Part,
|
||||
}
|
||||
|
||||
override fun getName() = "SlashCommand"
|
||||
|
||||
override fun getProperties(): Map<String, Any>? {
|
||||
return mutableMapOf<String, Any>().apply {
|
||||
put("command", command.name)
|
||||
}.takeIf { it.isNotEmpty() }
|
||||
}
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.element.android.services.analytics.api.plan
|
||||
|
||||
import io.element.android.services.analytics.api.VectorAnalyticsEvent
|
||||
|
||||
// GENERATED FILE, DO NOT EDIT. FOR MORE INFORMATION VISIT
|
||||
// https://github.com/matrix-org/matrix-analytics-events/
|
||||
|
||||
/**
|
||||
* Triggered when the user becomes unauthenticated without actually clicking
|
||||
* sign out(E.g. Due to expiry of an access token without a way to refresh).
|
||||
*/
|
||||
data class UnauthenticatedError(
|
||||
/**
|
||||
* The error code as defined in matrix spec. The source of this error is
|
||||
* from the homeserver.
|
||||
*/
|
||||
val errorCode: ErrorCode,
|
||||
/**
|
||||
* The reason for the error. The source of this error is from the
|
||||
* homeserver, the reason can vary and is subject to change so there is
|
||||
* no enum of possible values.
|
||||
*/
|
||||
val errorReason: String,
|
||||
/**
|
||||
* Whether the auth mechanism is refresh-token-based.
|
||||
*/
|
||||
val refreshTokenAuth: Boolean,
|
||||
/**
|
||||
* Whether a soft logout or hard logout was triggered.
|
||||
*/
|
||||
val softLogout: Boolean,
|
||||
) : VectorAnalyticsEvent {
|
||||
|
||||
enum class ErrorCode {
|
||||
M_FORBIDDEN,
|
||||
M_UNKNOWN,
|
||||
M_UNKNOWN_TOKEN,
|
||||
}
|
||||
|
||||
override fun getName() = "UnauthenticatedError"
|
||||
|
||||
override fun getProperties(): Map<String, Any>? {
|
||||
return mutableMapOf<String, Any>().apply {
|
||||
put("errorCode", errorCode.name)
|
||||
put("errorReason", errorReason)
|
||||
put("refreshTokenAuth", refreshTokenAuth)
|
||||
put("softLogout", softLogout)
|
||||
}.takeIf { it.isNotEmpty() }
|
||||
}
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2023 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.element.android.services.analytics.api.plan
|
||||
|
||||
// GENERATED FILE, DO NOT EDIT. FOR MORE INFORMATION VISIT
|
||||
// https://github.com/matrix-org/matrix-analytics-events/
|
||||
|
||||
/**
|
||||
* The user properties to apply when identifying. This is not an event
|
||||
* definition. These properties must all be device independent.
|
||||
*/
|
||||
data class UserProperties(
|
||||
/**
|
||||
* The active filter in the All Chats screen.
|
||||
*/
|
||||
val allChatsActiveFilter: AllChatsActiveFilter? = null,
|
||||
/**
|
||||
* The selected messaging use case during the onboarding flow.
|
||||
*/
|
||||
val ftueUseCaseSelection: FtueUseCaseSelection? = null,
|
||||
/**
|
||||
* Number of joined rooms the user has favourited.
|
||||
*/
|
||||
val numFavouriteRooms: Int? = null,
|
||||
/**
|
||||
* Number of spaces (and sub-spaces) the user is joined to.
|
||||
*/
|
||||
val numSpaces: Int? = null,
|
||||
) {
|
||||
|
||||
enum class FtueUseCaseSelection {
|
||||
/**
|
||||
* The third option, Communities.
|
||||
*/
|
||||
CommunityMessaging,
|
||||
|
||||
/**
|
||||
* The first option, Friends and family.
|
||||
*/
|
||||
PersonalMessaging,
|
||||
|
||||
/**
|
||||
* The footer option to skip the question.
|
||||
*/
|
||||
Skip,
|
||||
|
||||
/**
|
||||
* The second option, Teams.
|
||||
*/
|
||||
WorkMessaging,
|
||||
}
|
||||
|
||||
enum class AllChatsActiveFilter {
|
||||
|
||||
/**
|
||||
* Filters are activated and All is selected.
|
||||
*/
|
||||
All,
|
||||
|
||||
/**
|
||||
* Filters are activated and Favourites is selected.
|
||||
*/
|
||||
Favourites,
|
||||
|
||||
/**
|
||||
* Filters are activated and People is selected.
|
||||
*/
|
||||
People,
|
||||
|
||||
/**
|
||||
* Filters are activated and Unreads is selected.
|
||||
*/
|
||||
Unreads,
|
||||
}
|
||||
|
||||
fun getProperties(): Map<String, Any>? {
|
||||
return mutableMapOf<String, Any>().apply {
|
||||
allChatsActiveFilter?.let { put("allChatsActiveFilter", it.name) }
|
||||
ftueUseCaseSelection?.let { put("ftueUseCaseSelection", it.name) }
|
||||
numFavouriteRooms?.let { put("numFavouriteRooms", it) }
|
||||
numSpaces?.let { put("numSpaces", it) }
|
||||
}.takeIf { it.isNotEmpty() }
|
||||
}
|
||||
}
|
||||
@@ -1,306 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.element.android.services.analytics.api.plan
|
||||
|
||||
import io.element.android.services.analytics.api.VectorAnalyticsEvent
|
||||
|
||||
// GENERATED FILE, DO NOT EDIT. FOR MORE INFORMATION VISIT
|
||||
// https://github.com/matrix-org/matrix-analytics-events/
|
||||
|
||||
/**
|
||||
* Triggered when the user changes rooms.
|
||||
*/
|
||||
data class ViewRoom(
|
||||
/**
|
||||
* active space when user navigated to the room.
|
||||
*/
|
||||
val activeSpace: ActiveSpace? = null,
|
||||
/**
|
||||
* Whether the room is a DM.
|
||||
*/
|
||||
val isDM: Boolean? = null,
|
||||
/**
|
||||
* Whether the room is a Space.
|
||||
*/
|
||||
val isSpace: Boolean? = null,
|
||||
/**
|
||||
* The reason for the room change if known.
|
||||
*/
|
||||
val trigger: Trigger? = null,
|
||||
/**
|
||||
* Whether the interaction was performed via the keyboard input.
|
||||
*/
|
||||
val viaKeyboard: Boolean? = null,
|
||||
) : VectorAnalyticsEvent {
|
||||
|
||||
enum class Trigger {
|
||||
/**
|
||||
* Room accessed due to being just created.
|
||||
*/
|
||||
Created,
|
||||
|
||||
/**
|
||||
* Room switched due to user interacting with a message search result.
|
||||
*/
|
||||
MessageSearch,
|
||||
|
||||
/**
|
||||
* Room switched due to user selecting a user to go to a DM with.
|
||||
*/
|
||||
MessageUser,
|
||||
|
||||
/**
|
||||
* Room accessed via space explore.
|
||||
*/
|
||||
MobileExploreRooms,
|
||||
|
||||
/**
|
||||
* Room switched due to user interacting with a file search result.
|
||||
*/
|
||||
MobileFileSearch,
|
||||
|
||||
/**
|
||||
* Room accessed via interacting with the incall screen.
|
||||
*/
|
||||
MobileInCall,
|
||||
|
||||
/**
|
||||
* Room accessed during external sharing.
|
||||
*/
|
||||
MobileLinkShare,
|
||||
|
||||
/**
|
||||
* Room accessed via link.
|
||||
*/
|
||||
MobilePermalink,
|
||||
|
||||
/**
|
||||
* Room accessed via interacting with direct chat item in the room
|
||||
* contact detail screen.
|
||||
*/
|
||||
MobileRoomMemberDetail,
|
||||
|
||||
/**
|
||||
* Room accessed via preview.
|
||||
*/
|
||||
MobileRoomPreview,
|
||||
|
||||
/**
|
||||
* Room switched due to user interacting with a room search result.
|
||||
*/
|
||||
MobileRoomSearch,
|
||||
|
||||
/**
|
||||
* Room accessed via interacting with direct chat item in the search
|
||||
* contact detail screen.
|
||||
*/
|
||||
MobileSearchContactDetail,
|
||||
|
||||
/**
|
||||
* Room accessed via space bottom sheet list.
|
||||
*/
|
||||
MobileSpaceBottomSheet,
|
||||
|
||||
/**
|
||||
* Room accessed via interacting with direct chat item in the space
|
||||
* contact detail screen.
|
||||
*/
|
||||
MobileSpaceMemberDetail,
|
||||
|
||||
/**
|
||||
* Room accessed via space members list.
|
||||
*/
|
||||
MobileSpaceMembers,
|
||||
|
||||
/**
|
||||
* Space accessed via interacting with the space menu.
|
||||
*/
|
||||
MobileSpaceMenu,
|
||||
|
||||
/**
|
||||
* Space accessed via interacting with a space settings menu item.
|
||||
*/
|
||||
MobileSpaceSettings,
|
||||
|
||||
/**
|
||||
* Room accessed via a push/desktop notification.
|
||||
*/
|
||||
Notification,
|
||||
|
||||
/**
|
||||
* Room accessed via the predecessor link at the top of the upgraded
|
||||
* room.
|
||||
*/
|
||||
Predecessor,
|
||||
|
||||
/**
|
||||
* Room accessed via the public rooms directory.
|
||||
*/
|
||||
RoomDirectory,
|
||||
|
||||
/**
|
||||
* Room accessed via the room list.
|
||||
*/
|
||||
RoomList,
|
||||
|
||||
/**
|
||||
* Room accessed via a shortcut.
|
||||
*/
|
||||
Shortcut,
|
||||
|
||||
/**
|
||||
* Room accessed via a slash command in Element Web/Desktop like /goto.
|
||||
*/
|
||||
SlashCommand,
|
||||
|
||||
/**
|
||||
* Room accessed via the space hierarchy view.
|
||||
*/
|
||||
SpaceHierarchy,
|
||||
|
||||
/**
|
||||
* Room accessed via a timeline pill or link in another room.
|
||||
*/
|
||||
Timeline,
|
||||
|
||||
/**
|
||||
* Room accessed via a tombstone at the bottom of a predecessor room.
|
||||
*/
|
||||
Tombstone,
|
||||
|
||||
/**
|
||||
* Room switched due to user interacting with incoming verification
|
||||
* request.
|
||||
*/
|
||||
VerificationRequest,
|
||||
|
||||
/**
|
||||
* Room switched due to accepting a call in a different room in Element
|
||||
* Web/Desktop.
|
||||
*/
|
||||
WebAcceptCall,
|
||||
|
||||
/**
|
||||
* Room switched due to making a call via the dial pad in Element
|
||||
* Web/Desktop.
|
||||
*/
|
||||
WebDialPad,
|
||||
|
||||
/**
|
||||
* Room accessed via interacting with the floating call or Jitsi PIP in
|
||||
* Element Web/Desktop.
|
||||
*/
|
||||
WebFloatingCallWindow,
|
||||
|
||||
/**
|
||||
* Room accessed via the shortcut in Element Web/Desktop's forward
|
||||
* modal.
|
||||
*/
|
||||
WebForwardShortcut,
|
||||
|
||||
/**
|
||||
* Room accessed via the Element Web/Desktop horizontal breadcrumbs at
|
||||
* the top of the room list.
|
||||
*/
|
||||
WebHorizontalBreadcrumbs,
|
||||
|
||||
/**
|
||||
* Room accessed via an Element Web/Desktop keyboard shortcut like go to
|
||||
* next room with unread messages.
|
||||
*/
|
||||
WebKeyboardShortcut,
|
||||
|
||||
/**
|
||||
* Room accessed via Element Web/Desktop's notification panel.
|
||||
*/
|
||||
WebNotificationPanel,
|
||||
|
||||
/**
|
||||
* Room accessed via the predecessor link in Settings > Advanced in
|
||||
* Element Web/Desktop.
|
||||
*/
|
||||
WebPredecessorSettings,
|
||||
|
||||
/**
|
||||
* Room accessed via clicking on a notifications badge on a room list
|
||||
* sublist in Element Web/Desktop.
|
||||
*/
|
||||
WebRoomListNotificationBadge,
|
||||
|
||||
/**
|
||||
* Room switched due to the user changing space in Element Web/Desktop.
|
||||
*/
|
||||
WebSpaceContextSwitch,
|
||||
|
||||
/**
|
||||
* Room accessed via clicking on the notifications badge on the
|
||||
* currently selected space in Element Web/Desktop.
|
||||
*/
|
||||
WebSpacePanelNotificationBadge,
|
||||
|
||||
/**
|
||||
* Room accessed via Element Web/Desktop's Unified Search modal.
|
||||
*/
|
||||
WebUnifiedSearch,
|
||||
|
||||
/**
|
||||
* Room accessed via the Element Web/Desktop vertical breadcrumb hover
|
||||
* menu.
|
||||
*/
|
||||
WebVerticalBreadcrumbs,
|
||||
|
||||
/**
|
||||
* Room switched due to widget interaction.
|
||||
*/
|
||||
Widget,
|
||||
}
|
||||
|
||||
enum class ActiveSpace {
|
||||
|
||||
/**
|
||||
* Active space is Home.
|
||||
*/
|
||||
Home,
|
||||
|
||||
/**
|
||||
* Active space is a meta space.
|
||||
*/
|
||||
Meta,
|
||||
|
||||
/**
|
||||
* Active space is a private space.
|
||||
*/
|
||||
Private,
|
||||
|
||||
/**
|
||||
* Active space is a public space.
|
||||
*/
|
||||
Public,
|
||||
}
|
||||
|
||||
override fun getName() = "ViewRoom"
|
||||
|
||||
override fun getProperties(): Map<String, Any>? {
|
||||
return mutableMapOf<String, Any>().apply {
|
||||
activeSpace?.let { put("activeSpace", it.name) }
|
||||
isDM?.let { put("isDM", it) }
|
||||
isSpace?.let { put("isSpace", it) }
|
||||
trigger?.let { put("trigger", it.name) }
|
||||
viaKeyboard?.let { put("viaKeyboard", it) }
|
||||
}.takeIf { it.isNotEmpty() }
|
||||
}
|
||||
}
|
||||
46
services/analytics/impl/build.gradle.kts
Normal file
46
services/analytics/impl/build.gradle.kts
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2023 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
plugins {
|
||||
id("io.element.android-compose-library")
|
||||
alias(libs.plugins.anvil)
|
||||
alias(libs.plugins.ksp)
|
||||
id("kotlin-parcelize")
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "io.element.android.services.analytics.impl"
|
||||
}
|
||||
|
||||
anvil {
|
||||
generateDaggerFactories.set(true)
|
||||
}
|
||||
|
||||
dependencies {
|
||||
anvil(projects.anvilcodegen)
|
||||
|
||||
implementation(projects.libraries.androidutils)
|
||||
implementation(projects.libraries.core)
|
||||
implementation(projects.libraries.architecture)
|
||||
implementation(projects.libraries.sessionStorage.api)
|
||||
|
||||
api(projects.services.analyticsproviders.api)
|
||||
api(projects.services.analytics.api)
|
||||
implementation(libs.androidx.datastore.preferences)
|
||||
|
||||
testImplementation(libs.coroutines.test)
|
||||
testImplementation(libs.test.mockk)
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* Copyright (c) 2023 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.element.android.services.analytics.impl
|
||||
|
||||
import com.squareup.anvil.annotations.ContributesBinding
|
||||
import im.vector.app.features.analytics.itf.VectorAnalyticsEvent
|
||||
import im.vector.app.features.analytics.itf.VectorAnalyticsScreen
|
||||
import im.vector.app.features.analytics.plan.UserProperties
|
||||
import io.element.android.libraries.di.AppScope
|
||||
import io.element.android.libraries.di.SingleIn
|
||||
import io.element.android.libraries.sessionstorage.api.observer.SessionListener
|
||||
import io.element.android.libraries.sessionstorage.api.observer.SessionObserver
|
||||
import io.element.android.services.analytics.api.AnalyticsService
|
||||
import io.element.android.services.analytics.impl.log.analyticsTag
|
||||
import io.element.android.services.analytics.impl.store.AnalyticsStore
|
||||
import io.element.android.services.analyticsproviders.api.AnalyticsProvider
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
@SingleIn(AppScope::class)
|
||||
@ContributesBinding(AppScope::class, boundType = AnalyticsService::class)
|
||||
class DefaultAnalyticsService @Inject constructor(
|
||||
private val analyticsProviders: Set<@JvmSuppressWildcards AnalyticsProvider>,
|
||||
private val analyticsStore: AnalyticsStore,
|
||||
// private val lateInitUserPropertiesFactory: LateInitUserPropertiesFactory,
|
||||
private val coroutineScope: CoroutineScope,
|
||||
private val sessionObserver: SessionObserver,
|
||||
) : AnalyticsService, SessionListener {
|
||||
// Cache for the store values
|
||||
private var userConsent: Boolean? = null
|
||||
|
||||
// Cache for the properties to send
|
||||
private var pendingUserProperties: UserProperties? = null
|
||||
|
||||
init {
|
||||
observeUserConsent()
|
||||
observeSessions()
|
||||
}
|
||||
|
||||
override fun getAvailableAnalyticsProviders(): List<AnalyticsProvider> {
|
||||
return analyticsProviders.sortedBy { it.index }
|
||||
}
|
||||
|
||||
override fun getUserConsent(): Flow<Boolean> {
|
||||
return analyticsStore.userConsentFlow
|
||||
}
|
||||
|
||||
override suspend fun setUserConsent(userConsent: Boolean) {
|
||||
Timber.tag(analyticsTag.value).d("setUserConsent($userConsent)")
|
||||
analyticsStore.setUserConsent(userConsent)
|
||||
}
|
||||
|
||||
override fun didAskUserConsent(): Flow<Boolean> {
|
||||
return analyticsStore.didAskUserConsentFlow
|
||||
}
|
||||
|
||||
override suspend fun setDidAskUserConsent() {
|
||||
Timber.tag(analyticsTag.value).d("setDidAskUserConsent()")
|
||||
analyticsStore.setDidAskUserConsent()
|
||||
}
|
||||
|
||||
override fun getAnalyticsId(): Flow<String> {
|
||||
return analyticsStore.analyticsIdFlow
|
||||
}
|
||||
|
||||
override suspend fun setAnalyticsId(analyticsId: String) {
|
||||
Timber.tag(analyticsTag.value).d("setAnalyticsId($analyticsId)")
|
||||
analyticsStore.setAnalyticsId(analyticsId)
|
||||
}
|
||||
|
||||
override suspend fun onSignOut() {
|
||||
// stop all providers
|
||||
analyticsProviders.onEach { it.stop() }
|
||||
}
|
||||
|
||||
override suspend fun onSessionCreated(userId: String) {
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
override suspend fun onSessionDeleted(userId: String) {
|
||||
// Delete the store
|
||||
analyticsStore.reset()
|
||||
}
|
||||
|
||||
private fun observeUserConsent() {
|
||||
getUserConsent()
|
||||
.onEach { consent ->
|
||||
Timber.tag(analyticsTag.value).d("User consent updated to $consent")
|
||||
userConsent = consent
|
||||
initOrStop()
|
||||
}
|
||||
.launchIn(coroutineScope)
|
||||
}
|
||||
|
||||
private fun observeSessions() {
|
||||
sessionObserver.addListener(this)
|
||||
}
|
||||
|
||||
private fun initOrStop() {
|
||||
userConsent?.let { _userConsent ->
|
||||
when (_userConsent) {
|
||||
true -> {
|
||||
pendingUserProperties?.let {
|
||||
analyticsProviders.onEach { provider -> provider.updateUserProperties(it) }
|
||||
pendingUserProperties = null
|
||||
}
|
||||
}
|
||||
false -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun capture(event: VectorAnalyticsEvent) {
|
||||
Timber.tag(analyticsTag.value).d("capture($event)")
|
||||
if (userConsent == true) {
|
||||
analyticsProviders.onEach { it.capture(event) }
|
||||
}
|
||||
}
|
||||
|
||||
override fun screen(screen: VectorAnalyticsScreen) {
|
||||
Timber.tag(analyticsTag.value).d("screen($screen)")
|
||||
if (userConsent == true) {
|
||||
analyticsProviders.onEach { it.screen(screen) }
|
||||
}
|
||||
}
|
||||
|
||||
override fun updateUserProperties(userProperties: UserProperties) {
|
||||
if (userConsent == true) {
|
||||
analyticsProviders.onEach { it.updateUserProperties(userProperties) }
|
||||
} else {
|
||||
pendingUserProperties = userProperties
|
||||
}
|
||||
}
|
||||
|
||||
override fun trackError(throwable: Throwable) {
|
||||
if (userConsent == true) {
|
||||
analyticsProviders.onEach { it.trackError(throwable) }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,9 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.element.android.services.analytics.api
|
||||
package io.element.android.services.analytics.impl.log
|
||||
|
||||
interface VectorAnalyticsEvent {
|
||||
fun getName(): String
|
||||
fun getProperties(): Map<String, Any?>?
|
||||
}
|
||||
import io.element.android.libraries.core.log.logger.LoggerTag
|
||||
|
||||
val analyticsTag = LoggerTag("Analytics")
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (c) 2021 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.element.android.services.analytics.impl.store
|
||||
|
||||
import android.content.Context
|
||||
import androidx.datastore.core.DataStore
|
||||
import androidx.datastore.preferences.core.Preferences
|
||||
import androidx.datastore.preferences.core.booleanPreferencesKey
|
||||
import androidx.datastore.preferences.core.edit
|
||||
import androidx.datastore.preferences.core.stringPreferencesKey
|
||||
import androidx.datastore.preferences.preferencesDataStore
|
||||
import io.element.android.libraries.di.ApplicationContext
|
||||
import io.element.android.libraries.core.bool.orFalse
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.map
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* Also accessed via reflection by the instrumentation tests @see [im.vector.app.ClearCurrentSessionRule].
|
||||
*/
|
||||
private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "vector_analytics")
|
||||
|
||||
/**
|
||||
* Local storage for:
|
||||
* - user consent (Boolean);
|
||||
* - did ask user consent (Boolean);
|
||||
* - analytics Id (String).
|
||||
*/
|
||||
class AnalyticsStore @Inject constructor(
|
||||
@ApplicationContext private val context: Context
|
||||
) {
|
||||
private val userConsent = booleanPreferencesKey("user_consent")
|
||||
private val didAskUserConsent = booleanPreferencesKey("did_ask_user_consent")
|
||||
private val analyticsId = stringPreferencesKey("analytics_id")
|
||||
|
||||
val userConsentFlow: Flow<Boolean> = context.dataStore.data
|
||||
.map { preferences -> preferences[userConsent].orFalse() }
|
||||
.distinctUntilChanged()
|
||||
|
||||
val didAskUserConsentFlow: Flow<Boolean> = context.dataStore.data
|
||||
.map { preferences -> preferences[didAskUserConsent].orFalse() }
|
||||
.distinctUntilChanged()
|
||||
|
||||
val analyticsIdFlow: Flow<String> = context.dataStore.data
|
||||
.map { preferences -> preferences[analyticsId].orEmpty() }
|
||||
.distinctUntilChanged()
|
||||
|
||||
suspend fun setUserConsent(newUserConsent: Boolean) {
|
||||
context.dataStore.edit { settings ->
|
||||
settings[userConsent] = newUserConsent
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun setDidAskUserConsent(newValue: Boolean = true) {
|
||||
context.dataStore.edit { settings ->
|
||||
settings[didAskUserConsent] = newValue
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun setAnalyticsId(newAnalyticsId: String) {
|
||||
context.dataStore.edit { settings ->
|
||||
settings[analyticsId] = newAnalyticsId
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun reset() {
|
||||
context.dataStore.edit {
|
||||
it.clear()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2023 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.element.android.services.analytics.noop
|
||||
|
||||
import com.squareup.anvil.annotations.ContributesBinding
|
||||
import io.element.android.services.analytics.api.AnalyticsTracker
|
||||
import io.element.android.services.analytics.api.VectorAnalyticsEvent
|
||||
import io.element.android.services.analytics.api.VectorAnalyticsScreen
|
||||
import io.element.android.services.analytics.api.plan.UserProperties
|
||||
import io.element.android.libraries.di.AppScope
|
||||
import javax.inject.Inject
|
||||
|
||||
@ContributesBinding(AppScope::class)
|
||||
class NoopAnalyticsTracker @Inject constructor() : AnalyticsTracker {
|
||||
|
||||
override fun capture(event: VectorAnalyticsEvent) = Unit
|
||||
|
||||
override fun screen(screen: VectorAnalyticsScreen) = Unit
|
||||
|
||||
override fun updateUserProperties(userProperties: UserProperties) = Unit
|
||||
}
|
||||
26
services/analyticsproviders/api/build.gradle.kts
Normal file
26
services/analyticsproviders/api/build.gradle.kts
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) 2023 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
plugins {
|
||||
id("io.element.android-library")
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "io.element.android.services.analyticsproviders.api"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api(libs.matrix.analytics.events)
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2023 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.element.android.services.analyticsproviders.api
|
||||
|
||||
import io.element.android.services.analyticsproviders.api.trackers.AnalyticsTracker
|
||||
import io.element.android.services.analyticsproviders.api.trackers.ErrorTracker
|
||||
|
||||
interface AnalyticsProvider: AnalyticsTracker, ErrorTracker {
|
||||
/**
|
||||
* Allow to sort providers, from lower index to higher index.
|
||||
*/
|
||||
val index: Int
|
||||
|
||||
/**
|
||||
* User friendly name.
|
||||
*/
|
||||
val name: String
|
||||
|
||||
suspend fun init()
|
||||
|
||||
fun stop()
|
||||
}
|
||||
@@ -14,9 +14,11 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.element.android.services.analytics.api
|
||||
package io.element.android.services.analyticsproviders.api.trackers
|
||||
|
||||
import io.element.android.services.analytics.api.plan.UserProperties
|
||||
import im.vector.app.features.analytics.itf.VectorAnalyticsEvent
|
||||
import im.vector.app.features.analytics.itf.VectorAnalyticsScreen
|
||||
import im.vector.app.features.analytics.plan.UserProperties
|
||||
|
||||
interface AnalyticsTracker {
|
||||
/**
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright (c) 2023 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.element.android.services.analyticsproviders.api.trackers
|
||||
|
||||
interface ErrorTracker {
|
||||
fun trackError(throwable: Throwable)
|
||||
}
|
||||
37
services/analyticsproviders/posthog/build.gradle.kts
Normal file
37
services/analyticsproviders/posthog/build.gradle.kts
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2023 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
plugins {
|
||||
id("io.element.android-library")
|
||||
alias(libs.plugins.anvil)
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "io.element.android.services.analyticsproviders.posthog"
|
||||
}
|
||||
|
||||
anvil {
|
||||
generateDaggerFactories.set(true)
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(libs.dagger)
|
||||
implementation(libs.posthog) {
|
||||
exclude("com.android.support", "support-annotations")
|
||||
}
|
||||
implementation(projects.libraries.core)
|
||||
implementation(projects.libraries.di)
|
||||
implementation(projects.services.analyticsproviders.api)
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2023 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.element.android.services.analyticsproviders.posthog
|
||||
|
||||
import android.content.Context
|
||||
import com.posthog.android.PostHog
|
||||
import io.element.android.libraries.core.meta.BuildMeta
|
||||
import io.element.android.libraries.di.ApplicationContext
|
||||
import javax.inject.Inject
|
||||
|
||||
class PostHogFactory @Inject constructor(
|
||||
@ApplicationContext private val context: Context,
|
||||
private val buildMeta: BuildMeta,
|
||||
) {
|
||||
|
||||
fun createPosthog(): PostHog {
|
||||
return PostHog.Builder(context, PosthogConfig.postHogApiKey, PosthogConfig.postHogHost)
|
||||
// Record certain application events automatically! (off/false by default)
|
||||
// .captureApplicationLifecycleEvents()
|
||||
// Record screen views automatically! (off/false by default)
|
||||
// .recordScreenViews()
|
||||
// Capture deep links as part of the screen call. (off by default)
|
||||
// .captureDeepLinks()
|
||||
// Maximum number of events to keep in queue before flushing (default 20)
|
||||
// .flushQueueSize(20)
|
||||
// Max delay before flushing the queue (30 seconds)
|
||||
// .flushInterval(30, TimeUnit.SECONDS)
|
||||
// Enable or disable collection of ANDROID_ID (true)
|
||||
.collectDeviceId(false)
|
||||
.logLevel(getLogLevel())
|
||||
.build()
|
||||
}
|
||||
|
||||
private fun getLogLevel(): PostHog.LogLevel {
|
||||
return if (buildMeta.isDebuggable) {
|
||||
PostHog.LogLevel.DEBUG
|
||||
} else {
|
||||
PostHog.LogLevel.INFO
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright (c) 2023 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.element.android.services.analyticsproviders.posthog
|
||||
|
||||
import com.posthog.android.Options
|
||||
import com.posthog.android.PostHog
|
||||
import com.posthog.android.Properties
|
||||
import com.squareup.anvil.annotations.ContributesMultibinding
|
||||
import im.vector.app.features.analytics.itf.VectorAnalyticsEvent
|
||||
import im.vector.app.features.analytics.itf.VectorAnalyticsScreen
|
||||
import im.vector.app.features.analytics.plan.UserProperties
|
||||
import io.element.android.libraries.di.AppScope
|
||||
import io.element.android.services.analyticsproviders.api.AnalyticsProvider
|
||||
import io.element.android.services.analyticsproviders.posthog.log.analyticsTag
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
private val REUSE_EXISTING_ID: String? = null
|
||||
private val IGNORED_OPTIONS: Options? = null
|
||||
|
||||
@ContributesMultibinding(AppScope::class)
|
||||
class PosthogAnalyticsProvider @Inject constructor(
|
||||
private val postHogFactory: PostHogFactory,
|
||||
) : AnalyticsProvider {
|
||||
override val index = PosthogConfig.index
|
||||
override val name = PosthogConfig.name
|
||||
|
||||
private var posthog: PostHog? = null
|
||||
private var analyticsId: String? = null
|
||||
|
||||
override suspend fun init() {
|
||||
posthog = createPosthog()
|
||||
posthog?.optOut(false)
|
||||
identifyPostHog()
|
||||
}
|
||||
|
||||
override fun stop() {
|
||||
// When opting out, ensure that the queue is flushed first, or it will be flushed later (after user has revoked consent)
|
||||
posthog?.flush()
|
||||
posthog?.optOut(true)
|
||||
posthog?.shutdown()
|
||||
posthog = null
|
||||
analyticsId = null
|
||||
}
|
||||
|
||||
override fun capture(event: VectorAnalyticsEvent) {
|
||||
posthog?.capture(event.getName(), event.getProperties()?.toPostHogProperties())
|
||||
}
|
||||
|
||||
override fun screen(screen: VectorAnalyticsScreen) {
|
||||
posthog?.screen(screen.getName(), screen.getProperties()?.toPostHogProperties())
|
||||
}
|
||||
|
||||
override fun updateUserProperties(userProperties: UserProperties) {
|
||||
posthog?.identify(
|
||||
REUSE_EXISTING_ID, userProperties.getProperties()?.toPostHogUserProperties(),
|
||||
IGNORED_OPTIONS
|
||||
)
|
||||
}
|
||||
|
||||
override fun trackError(throwable: Throwable) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
private fun createPosthog(): PostHog = postHogFactory.createPosthog()
|
||||
|
||||
private fun identifyPostHog() {
|
||||
val id = analyticsId ?: return
|
||||
if (id.isEmpty()) {
|
||||
Timber.tag(analyticsTag.value).d("reset")
|
||||
posthog?.reset()
|
||||
} else {
|
||||
Timber.tag(analyticsTag.value).d("identify")
|
||||
// posthog?.identify(id, lateInitUserPropertiesFactory.createUserProperties()?.getProperties()?.toPostHogUserProperties(), IGNORED_OPTIONS)
|
||||
}
|
||||
}
|
||||
|
||||
private fun Map<String, Any?>?.toPostHogProperties(): Properties? {
|
||||
if (this == null) return null
|
||||
|
||||
return Properties().apply {
|
||||
putAll(this@toPostHogProperties)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* We avoid sending nulls as part of the UserProperties as this will reset the values across all devices.
|
||||
* The UserProperties event has nullable properties to allow for clients to opt in.
|
||||
*/
|
||||
private fun Map<String, Any?>.toPostHogUserProperties(): Properties {
|
||||
return Properties().apply {
|
||||
putAll(this@toPostHogUserProperties.filter { it.value != null })
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (c) 2023 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.element.android.services.analyticsproviders.posthog
|
||||
|
||||
object PosthogConfig {
|
||||
const val index = 0
|
||||
const val name = "Posthog"
|
||||
const val postHogHost = "https://posthog.element.dev"
|
||||
const val postHogApiKey = "phc_VtA1L35nw3aeAtHIx1ayrGdzGkss7k1xINeXcoIQzXN"
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 2022 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.element.android.services.analyticsproviders.posthog.extensions
|
||||
|
||||
import im.vector.app.features.analytics.plan.Interaction
|
||||
|
||||
fun Interaction.Name.toAnalyticsInteraction(interactionType: Interaction.InteractionType = Interaction.InteractionType.Touch) =
|
||||
Interaction(
|
||||
name = this,
|
||||
interactionType = interactionType
|
||||
)
|
||||
@@ -14,9 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.element.android.services.analytics.api
|
||||
package io.element.android.services.analyticsproviders.posthog.log
|
||||
|
||||
interface VectorAnalyticsScreen {
|
||||
fun getName(): String
|
||||
fun getProperties(): Map<String, Any>?
|
||||
}
|
||||
import io.element.android.libraries.core.log.logger.LoggerTag
|
||||
|
||||
val analyticsTag = LoggerTag("Analytics")
|
||||
Reference in New Issue
Block a user