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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 30 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,35 @@ option(BUILD_SIGNALS "Build Signals" YES)
option(BUILD_SANITIZER "Build Sanitizer" YES)
option(LINK_STATIC_DEPENDS "Link dependencies for static build" YES)

set(MATSDK_ANDROID_HTTP_CLIENT "AUTO" CACHE STRING "Android HTTP client: AUTO, JAVA, or CURL")
set_property(CACHE MATSDK_ANDROID_HTTP_CLIENT PROPERTY STRINGS AUTO JAVA CURL)
string(TOUPPER "${MATSDK_ANDROID_HTTP_CLIENT}" MATSDK_ANDROID_HTTP_CLIENT_UPPER)
if(NOT MATSDK_ANDROID_HTTP_CLIENT_UPPER STREQUAL "AUTO"
AND NOT MATSDK_ANDROID_HTTP_CLIENT_UPPER STREQUAL "JAVA"
AND NOT MATSDK_ANDROID_HTTP_CLIENT_UPPER STREQUAL "CURL")
message(FATAL_ERROR
"MATSDK_ANDROID_HTTP_CLIENT must be AUTO, JAVA, or CURL; got "
"'${MATSDK_ANDROID_HTTP_CLIENT}'.")
endif()

set(MATSDK_ANDROID_HTTP_CLIENT_RESOLVED "")
set(MATSDK_ANDROID_USES_CURL OFF)
set(MATSDK_ANDROID_USES_JAVA_HTTP OFF)
if(CMAKE_SYSTEM_NAME STREQUAL "Android")
if(MATSDK_ANDROID_HTTP_CLIENT_UPPER STREQUAL "AUTO")
set(MATSDK_ANDROID_HTTP_CLIENT_RESOLVED "JAVA")
else()
set(MATSDK_ANDROID_HTTP_CLIENT_RESOLVED "${MATSDK_ANDROID_HTTP_CLIENT_UPPER}")
endif()

if(MATSDK_ANDROID_HTTP_CLIENT_RESOLVED STREQUAL "CURL")
set(MATSDK_ANDROID_USES_CURL ON)
elseif(MATSDK_ANDROID_HTTP_CLIENT_RESOLVED STREQUAL "JAVA")
set(MATSDK_ANDROID_USES_JAVA_HTTP ON)
endif()
message(STATUS "MATSDK_ANDROID_HTTP_CLIENT: ${MATSDK_ANDROID_HTTP_CLIENT} -> ${MATSDK_ANDROID_HTTP_CLIENT_RESOLVED}")
endif()

# Enable Azure Monitor / Application Insights end-point support
option(BUILD_AZMON "Build for Azure Monitor" YES)

Expand All @@ -381,7 +410,7 @@ endif()
set(MATSDK_NEEDS_CURL OFF)
if(PAL_IMPLEMENTATION STREQUAL "CPP11"
AND NOT BUILD_IOS
AND (NOT CMAKE_SYSTEM_NAME STREQUAL "Android" OR MATSDK_USE_VCPKG_DEPS)
AND (NOT CMAKE_SYSTEM_NAME STREQUAL "Android" OR MATSDK_ANDROID_USES_CURL)
AND NOT BUILD_APPLE_HTTP)
set(MATSDK_NEEDS_CURL ON)
add_definitions(-DHAVE_MAT_CURL_HTTP_CLIENT)
Expand Down
13 changes: 11 additions & 2 deletions cmake/MSTelemetryConfig.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ find_dependency(ZLIB)
find_dependency(nlohmann_json CONFIG)

# Curl is re-found only when the SDK was built with the curl HTTP client
# (Linux, Android via vcpkg, and macOS built without Apple HTTP).
# Windows (WinInet), iOS, and macOS-with-Apple-HTTP do not link curl.
# (Linux, explicit Android curl builds, and macOS built without Apple HTTP).
# Windows (WinInet), default Android Java/JNI HTTP, iOS, and
# macOS-with-Apple-HTTP do not link curl.
# We bake the build-time decision into a boolean rather than re-deriving it,
# because the macOS BUILD_APPLE_HTTP choice can't be inferred from
# CMAKE_SYSTEM_NAME alone.
Expand All @@ -27,6 +28,14 @@ if(@MATSDK_NEEDS_CURL@)
find_dependency(CURL CONFIG)
endif()

set(MSTelemetry_ANDROID_HTTP_CLIENT "@MATSDK_ANDROID_HTTP_CLIENT_RESOLVED@")
if(MSTelemetry_ANDROID_HTTP_CLIENT STREQUAL "JAVA")
set(MSTelemetry_ANDROID_JAVA_SOURCE_DIR
"${PACKAGE_PREFIX_DIR}/@CMAKE_INSTALL_DATADIR@/cpp-client-telemetry/android/java")
else()
set(MSTelemetry_ANDROID_JAVA_SOURCE_DIR "")
endif()
Comment on lines +31 to +37

Comment on lines +31 to +38

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 4e6db99 and refined in 5982520. The comment now says curl is re-found for Linux, explicit Android curl builds, and macOS without Apple HTTP; it explicitly excludes default Android Java/JNI HTTP in cmake/MSTelemetryConfig.cmake.in:16-19. No further change needed for this thread.

# Pthreads are needed on Linux and Android (POSIX threading)
if(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_SYSTEM_NAME STREQUAL "Android")
find_dependency(Threads)
Expand Down
109 changes: 86 additions & 23 deletions docs/building-with-vcpkg.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,62 @@ scaffolding and not part of the published package.)
Supported triplets: `arm64-android`, `arm-neon-android`, `x64-android`,
`x86-android`.

#### Android HTTP transport

The CMake option `MATSDK_ANDROID_HTTP_CLIENT` selects the Android HTTP transport:

| Value | Behavior |
| ----- | -------- |
| `AUTO` | Default. Uses the Android Java/JNI transport. |
| `CURL` | Builds the native libcurl transport. This is an explicit escape hatch and requires one Android curl backend feature. |
| `JAVA` | Builds `HttpClient_Android`, which calls the Android Java bridge via JNI. |

For vcpkg, Android uses Java transport by default:

```json
{
"dependencies": [
{
"name": "cpp-client-telemetry",
"default-features": false,
"features": ["system-sqlite"]
}
]
}
```

To opt into native curl on Android, select exactly one Android curl backend:

```json
{
"dependencies": [
{
"name": "cpp-client-telemetry",
"default-features": false,
"features": ["android-curl-openssl", "system-sqlite"]
}
]
}
```

Use `android-curl-mbedtls` in place of `android-curl-openssl` for the mbedTLS
backend.

When Java transport is selected, the package installs the bridge sources under:

```text
share/cpp-client-telemetry/android/java/com/microsoft/applications/events/
```

The installed bridge contains `HttpClient.java` and `HttpClientRequest.java`.
Consumers are responsible for compiling those Java sources into their Android
application/AAR and constructing `com.microsoft.applications.events.HttpClient`
so it initializes the native `HttpClient_Android` singleton before telemetry is
uploaded. The bridge imports AndroidX annotations (`@Keep`, `@NonNull`,
`@Nullable`, `@RequiresApi`), so ensure `androidx.annotation:annotation` is on
the Java compile classpath, for example as a Gradle `compileOnly` or
`implementation` dependency.

## Dependencies

The vcpkg port automatically resolves the following dependencies:
Expand All @@ -148,7 +204,7 @@ The vcpkg port automatically resolves the following dependencies:
| SQLite3 | `sqlite3` | `unofficial::sqlite3::sqlite3` | Non-Apple (default; see `minimal-sqlite`). **macOS/iOS link the system `libsqlite3`** (`SQLite::SQLite3`) |
| zlib | `zlib` | `ZLIB::ZLIB` | Non-Apple. **macOS/iOS link the system `libz`** |
| nlohmann JSON | `nlohmann-json` | `nlohmann_json::nlohmann_json` | All |
| libcurl | `curl[openssl]` or `curl[mbedtls]` | `CURL::libcurl` | Non-Windows, non-Apple (required; TLS backend selectable: OpenSSL default or mbedTLS) |
| libcurl | `curl[openssl]` or `curl[mbedtls]` | `CURL::libcurl` | Linux by default; Android only when `android-curl-openssl` or `android-curl-mbedtls` is selected |

On **macOS/iOS** the SDK links the OS-provided `libsqlite3` and `libz` (the same
system libraries the SDK's Swift Package links), so the vcpkg `sqlite3` and `zlib`
Expand All @@ -160,17 +216,17 @@ feature. The `minimal-sqlite` feature replaces it with a private, feature-stripp
SQLite built from the SDK's vendored amalgamation — see
[Build a private minimal SQLite](#build-a-private-minimal-sqlite-minimal-sqlite-feature).

libcurl is provided by the default `curl-openssl` feature; `curl-mbedtls` swaps in
the mbedTLS backend — see
[Choose the HTTP client / TLS backend](#choose-the-http-client--tls-backend-largest-lever-on-linux).
On Linux, libcurl is provided by the default `curl-openssl` feature;
`curl-mbedtls` swaps in the mbedTLS backend — see
[Choose the Linux HTTP client / TLS backend](#choose-the-linux-http-client--tls-backend-largest-lever-on-linux).

Windows and macOS/iOS use platform-native HTTP clients (WinInet and
NSURLSession respectively). Android vcpkg consumers use native libcurl because
the Java-backed `HttpClient_Android` singleton is initialized by the repo's
Android Gradle/AAR flow, not by standalone native vcpkg consumers.
NSURLSession respectively). Android defaults to the platform Java/JNI HTTP
bridge; native curl is available only through explicit `android-curl-*` features.

> **Note (Windows):** The port targets the MSVC/`WIN32` PAL on Windows, which
> uses WinInet, so `curl` is declared for `linux | android` only. A MinGW /
> uses WinInet, so the default `curl` dependency is declared for Linux only
> (Android has separate explicit `android-curl-*` features). A MinGW /
> non-MSVC Windows triplet — or forcing `-DPAL_IMPLEMENTATION=CPP11` on Windows —
> selects the curl HTTP client, which the port does not provision on Windows
> (broadening `curl` to `windows` would pull an unused curl into every MSVC
Expand Down Expand Up @@ -244,13 +300,13 @@ the stripping happens at your link. Keep the SDK a static dependency linked
*into* your binary: if you re-export its API across your own DLL boundary, the
export table pins its symbols and defeats `/OPT:REF`.

### Choose the HTTP client / TLS backend (largest lever on Linux)
### Choose the Linux HTTP client / TLS backend (largest lever on Linux)

On Linux/Android the built-in HTTP client is libcurl, and curl's TLS backend
dominates the SDK's footprint. (Windows uses WinInet and Apple uses NSURLSession,
so this section does not apply there.) The port exposes the TLS backend as two
mutually-exclusive features; pick the one that matches what your application
already has:
On Linux the built-in HTTP client is libcurl, and curl's TLS backend dominates
the SDK's footprint. (Windows uses WinInet, Apple uses NSURLSession, and Android
uses the Java/JNI bridge by default, so this section does not apply there.) The
port exposes the Linux TLS backend as two mutually-exclusive features; pick the
one that matches what your application already has:

| Feature | Transport | Approx. stripped size¹ | Use when |
| ------- | --------- | ---------------------- | -------- |
Expand All @@ -261,7 +317,8 @@ already has:
(worst case); enabling `-Wl,--gc-sections` at your link reduces them. Your numbers
depend on triplet, dead-stripping, and what else shares those libraries.

To select **mbedTLS**, two things are required in *your top-level* manifest:
To select **mbedTLS on Linux**, two things are required in *your top-level*
manifest:

```json
{
Expand Down Expand Up @@ -290,7 +347,9 @@ To select **mbedTLS**, two things are required in *your top-level* manifest:
verified with `vcpkg install --dry-run`.

The default install (no features specified) keeps `curl-openssl` and works out of
the box.
the box on Linux. Android uses the Java/JNI HTTP bridge by default; use
`android-curl-openssl` or `android-curl-mbedtls` only when you explicitly want
the native curl Android escape hatch.

### Drop unused SQLite features (json1)

Expand Down Expand Up @@ -347,12 +406,14 @@ Enable it through the vcpkg feature:

Use the `[core,minimal-sqlite]` form (here, `"default-features": false` is the
`[core]` part) so the default `system-sqlite` feature — and its `sqlite3`
dependency — is dropped. Because `[core]` drops **all** defaults, the example
also re-selects `curl-openssl`: on Linux/Android the built-in curl client
requires a TLS backend, so omitting it would fail to configure (swap in
`curl-mbedtls` for the smaller mbedTLS backend). Requesting `minimal-sqlite`
*without* `[core]` still pulls in the default `system-sqlite`; that is harmless
(the external `sqlite3` is installed but unused) but does not save the dependency.
dependency — is dropped. Because `[core]` drops **all** defaults, Linux examples
also re-select `curl-openssl`; on Linux the built-in curl client requires a TLS
backend, so omitting it would fail to configure (swap in `curl-mbedtls` for the
smaller mbedTLS backend). Android does not need a curl feature unless you
explicitly opt into `android-curl-openssl` or `android-curl-mbedtls`.
Requesting `minimal-sqlite` *without* `[core]` still pulls in the default
`system-sqlite`; that is harmless (the external `sqlite3` is installed but
unused) but does not save the dependency.

For a plain (non-vcpkg) CMake build, pass the option directly:

Expand Down Expand Up @@ -382,7 +443,9 @@ unchanged against the minimal build.
When the SDK detects it is being built via vcpkg (by checking for
`VCPKG_TOOLCHAIN` or `VCPKG_TARGET_TRIPLET`), it automatically sets
`MATSDK_USE_VCPKG_DEPS=ON`. This switches dependency resolution from
vendored sources to vcpkg-provided packages via `find_package()`.
vendored sources to vcpkg-provided packages via `find_package()`. Android HTTP
transport selection is controlled separately by `MATSDK_ANDROID_HTTP_CLIENT`,
which defaults to `JAVA` on Android.

You can also set this explicitly for custom CMake workflows:

Expand Down
10 changes: 9 additions & 1 deletion lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ if(PAL_IMPLEMENTATION STREQUAL "CPP11")
list(APPEND SRCS
pal/posix/NetworkInformationImpl_Android.cpp
)
if(MATSDK_USE_VCPKG_DEPS)
if(MATSDK_ANDROID_USES_CURL)
list(APPEND SRCS
http/HttpClient_Curl.cpp
http/HttpClient_Curl.hpp
Expand Down Expand Up @@ -680,6 +680,14 @@ if(MATSDK_USE_VCPKG_DEPS)
"${CMAKE_CURRENT_BINARY_DIR}/MSTelemetryConfigVersion.cmake"
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/MSTelemetry
)

if(CMAKE_SYSTEM_NAME STREQUAL "Android" AND MATSDK_ANDROID_USES_JAVA_HTTP)
install(FILES
"${CMAKE_CURRENT_SOURCE_DIR}/android_build/maesdk/src/main/java/com/microsoft/applications/events/HttpClient.java"
"${CMAKE_CURRENT_SOURCE_DIR}/android_build/maesdk/src/main/java/com/microsoft/applications/events/HttpClientRequest.java"
DESTINATION "${CMAKE_INSTALL_DATADIR}/cpp-client-telemetry/android/java/com/microsoft/applications/events"
)
endif()
else()
# Legacy install: just put the library and headers in standard locations
install(TARGETS mat
Expand Down
5 changes: 3 additions & 2 deletions lib/pal/posix/DeviceInformationImpl_Android.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,10 @@ namespace PAL_NS_BEGIN {

///// IDeviceInformation API
DeviceInformationImpl::DeviceInformationImpl(IRuntimeConfig& configuration) :
m_os_architecture(OsArchitectureType_Unknown),
m_powerSource(PowerSource_Battery),
m_info_helper(),
m_powerSource(PowerSource_Battery)
m_registeredCount(0)
{}
Comment on lines 54 to 59

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 4e6db99 and completed in 5982520. m_registeredCount is now initialized to 0, and m_os_architecture is initialized to OsArchitectureType_Unknown, in lib/pal/posix/DeviceInformationImpl_Android.cpp:54-59. No further change needed for this thread.


std::string DeviceInformationImpl::GetDeviceTicket() const
Expand Down Expand Up @@ -260,4 +262,3 @@ Java_com_microsoft_applications_events_HttpClient_onPowerChange(JNIEnv* env,
PAL::AndroidDeviceInformationConnector::setModel(std::string(start, end));
env->ReleaseStringUTFChars(model, start);
}

5 changes: 3 additions & 2 deletions lib/pal/posix/NetworkInformationImpl_Android.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,10 @@ namespace PAL_NS_BEGIN {
NetworkCost AndroidNetcostConnector::s_cost = NetworkCost_Unknown;

NetworkInformationImpl::NetworkInformationImpl(IRuntimeConfig& configuration) :
m_info_helper(),
m_type(NetworkType_Unknown),
m_cost(NetworkCost_Unknown),
m_info_helper(),
m_registeredCount(0),
m_isNetDetectEnabled(configuration[CFG_BOOL_ENABLE_NET_DETECT]){};
Comment on lines 44 to 49

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 4e6db99 and completed in 5982520. m_registeredCount is now initialized to 0 and the related m_type getter state is initialized to NetworkType_Unknown in lib/pal/posix/NetworkInformationImpl_Android.cpp:44-49. No further change needed for this thread.


NetworkInformationImpl::~NetworkInformationImpl() {};
Expand Down Expand Up @@ -156,4 +158,3 @@ Java_com_microsoft_applications_events_HttpClient_onCostChange(JNIEnv* env,
{
PAL::AndroidNetcostConnector::UpdateCost(isMetered ? NetworkCost_Metered : NetworkCost_Unmetered);
}

5 changes: 2 additions & 3 deletions lib/pal/posix/SystemInformationImpl_Android.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,8 +163,8 @@ namespace PAL_NS_BEGIN {
std::string AndroidSystemInformationConnector::s_device_class;

SystemInformationImpl::SystemInformationImpl(IRuntimeConfig& configuration) :
m_info_helper(),
m_os_name("Android")
m_os_name("Android"),
m_info_helper()
{
if (configuration.HasConfig(CFG_PTR_ANDROID_JVM) && configuration.HasConfig(CFG_JOBJECT_ANDROID_ACTIVITY))
{
Expand Down Expand Up @@ -245,4 +245,3 @@ extern "C" JNIEXPORT void JNICALL Java_com_microsoft_applications_events_HttpCli
PAL::AndroidSystemInformationConnector::s_device_class,
deviceClass);
}

Loading
Loading