diff --git a/build/config.mak b/build/config.mak index d62c770bf..2ac8e3703 100644 --- a/build/config.mak +++ b/build/config.mak @@ -8,6 +8,7 @@ EPSILON_VERSION ?= 13.0.0 EPSILON_APPS ?= calculation graph code statistics probability solver sequence regression settings EPSILON_I18N ?= en fr es de pt EPSILON_GETOPT ?= 0 +EPSILON_TELEMETRY ?= 0 ESCHER_LOG_EVENTS_BINARY ?= 0 include build/defaults.mak @@ -23,4 +24,5 @@ include build/toolchain.$(TOOLCHAIN).mak SFLAGS += -DDEBUG=$(DEBUG) SFLAGS += -DEPSILON_GETOPT=$(EPSILON_GETOPT) +SFLAGS += -DEPSILON_TELEMETRY=$(EPSILON_TELEMETRY) SFLAGS += -DESCHER_LOG_EVENTS_BINARY=$(ESCHER_LOG_EVENTS_BINARY) diff --git a/build/platform.simulator.android.mak b/build/platform.simulator.android.mak index e7f065be8..97cd7faf7 100644 --- a/build/platform.simulator.android.mak +++ b/build/platform.simulator.android.mak @@ -1,6 +1,8 @@ TOOLCHAIN = android EXE = so +EPSILON_TELEMETRY ?= 1 + ifdef NDK_ABI BUILD_DIR := $(BUILD_DIR)/$(NDK_ABI) endif diff --git a/build/platform.simulator.ios.mak b/build/platform.simulator.ios.mak index dfadbda22..89a3c3c57 100644 --- a/build/platform.simulator.ios.mak +++ b/build/platform.simulator.ios.mak @@ -3,6 +3,7 @@ EXE = bin APPLE_PLATFORM ?= ios APPLE_PLATFORM_MIN_VERSION = 8.0 +EPSILON_TELEMETRY ?= 1 ifeq ($(APPLE_PLATFORM),ios) ARCHS ?= arm64 armv7 diff --git a/escher/include/escher/app.h b/escher/include/escher/app.h index eb070ab4e..7a5a79d5e 100644 --- a/escher/include/escher/app.h +++ b/escher/include/escher/app.h @@ -10,6 +10,7 @@ #include #include #include +#include /* An app is fed events and outputs drawing calls. * @@ -65,6 +66,9 @@ public: virtual int numberOfTimers() { return 0; } virtual Timer * timerAtIndex(int i) { assert(false); return nullptr; } virtual Poincare::Context * localContext() { return nullptr; } +#if EPSILON_TELEMETRY + virtual const char * telemetryId() const { return nullptr; } +#endif protected: App(Snapshot * snapshot, ViewController * rootViewController, I18n::Message warningMessage = (I18n::Message)0) : Responder(nullptr), diff --git a/escher/include/escher/telemetry.h b/escher/include/escher/telemetry.h new file mode 100644 index 000000000..eb06ca3c5 --- /dev/null +++ b/escher/include/escher/telemetry.h @@ -0,0 +1,10 @@ +#ifndef ESCHER_TELEMETRY_H +#define ESCHER_TELEMETRY_H + +#if EPSILON_TELEMETRY +#define TELEMETRY_ID(x) const char * telemetryId() const override { return (x); } +#else +#define TELEMETRY_ID(x) +#endif + +#endif diff --git a/escher/include/escher/view_controller.h b/escher/include/escher/view_controller.h index cb37c788f..a7fd6b026 100644 --- a/escher/include/escher/view_controller.h +++ b/escher/include/escher/view_controller.h @@ -3,6 +3,7 @@ #include #include +#include extern "C" { #include } @@ -51,6 +52,13 @@ public: virtual void viewWillAppear(); virtual void viewDidDisappear() {} virtual DisplayParameter displayParameter() { return DisplayParameter::Default; } +protected: +#if EPSILON_TELEMETRY + virtual const char * telemetryId() const { return nullptr; } + void telemetryReportEvent(const char * action, const char * label) const; +#else + void telemetryReportEvent(const char * action, const char * label) const {} +#endif }; #endif diff --git a/escher/src/view_controller.cpp b/escher/src/view_controller.cpp index 01d167c7c..8144a35b6 100644 --- a/escher/src/view_controller.cpp +++ b/escher/src/view_controller.cpp @@ -1,4 +1,40 @@ #include +#include +#include +#include void ViewController::viewWillAppear() { +#if EPSILON_TELEMETRY + const char * screenId = telemetryId(); + if (screenId == nullptr) { + return; + } + + const char * appId = Container::activeApp()->telemetryId(); + if (appId == nullptr) { + return; + } + + char reportedName[64]; + assert(strlen(appId) + 1 + strlen(screenId) < sizeof(reportedName)); + + reportedName[0] = 0; + strlcat(reportedName, appId, sizeof(reportedName)); + if (strlen(screenId) > 0) { + strlcat(reportedName, ".", sizeof(reportedName)); + strlcat(reportedName, screenId, sizeof(reportedName)); + } + + Ion::Telemetry::reportScreen(reportedName); +#endif } + +#if EPSILON_TELEMETRY +void ViewController::telemetryReportEvent(const char * action, const char * label) const { + const char * category = Container::activeApp()->telemetryId(); + assert(category != nullptr); + assert(action != nullptr); + assert(label != nullptr); + Ion::Telemetry::reportEvent(category, action, label); +} +#endif