After gaining some traction online, Twitter user @JaCzekanski pointed out that there is a way to remove the OnePlus Device Manager app via adb, without requiring root (substitute
@chrisdcmoore I've read your article about OnePlus Analytics. Actually, you can disable it permanently: pm uninstall -k --user 0 pkg— Jakub Czekański (@JaCzekanski) October 10, 2017
Amidst the traffic, I noticed requests to a domain which I’d not seen before,
open.oneplus.net, and decided to examine them a little closer.
Our first question is what am I connecting to at
Obviously the top level domain
oneplus.net belongs to the manufacturer of the device, but what’s with the
Doing a DNS lookup, we can find that this points to an Amazon AWS instance with mention of Apache Hadoop in the record, located in the
So the next question is what is being sent here?
From the example screenshot, we see two requests being sent over HTTPS; the first (not pictured) sending authentication information to
/oauth/token and the second, more interesting request, to
/cloud/pushdata/ with two parameters;
access_token which was the OAuth token returned from the first request, and
data which appears to be Base64 encoded.
Decoding the Base64 parameter gives us some JSON, show below (formatting mine)
OK, so it looks like they’re collecting timestamped (the
ts field is the event time in milliseconds since unix epoch, which we’ll be seeing more of) metrics on certain events, some of which I understand - from a development point of view, wanting to know about abnormal reboots seems legitimate - but the screen on/off and unlock activities feel excessive.
At least these are anonymised, right? Well, not really - taking a closer look at the ID field, it seems familiar; this is my phone’s serial number.
This I’m less enthusiastic about, as this can be used by OnePlus to tie these events back to me personally (but only because I bought the handset directly from them, I suppose).
I leave the traffic proxied for some time, to see what other information is collected, and boy am I in for a shock…
Amongst other things, this time we have the phone’s IMEI(s), phone numbers, MAC addresses, mobile network(s) names and IMSI prefixes, as well as my wireless network ESSID and BSSID and, of course, the phone’s serial number. Wow, that’s quite a bit of information about my device, even more of which can be tied directly back to me by OnePlus and other entities.
It gets worse.
Those are timestamp ranges (again, unix epoch in milliseconds) of the when I opened and closed applications on my phone.
From this data we can see that on Tuesday, 10th Jan 2017, I had Slack open between
20:25:40 UTC and
20:25:52 UTC, and the Microsoft Outlook app open between
21:38:41 UTC and
21:38:53 UTC, to take just two examples, again stamped with my phone’s serial number.
It gets even worse.
These event data contain timestamps of which activities were fired up in which in applications, again stamped with the phone’s serial number.
I took to Twitter to ask OnePlus on Twitter how this could be turned off, which disappointingly led down the usual path of “troubleshooting” suggestions, before being met with radio silence:
@chrisdcmoore Try wiping out the cache.Turn off your device>Power key + volume down>English>Wipe and cache>Wipe Cache>Confirm wipe>Reboot.— OnePlus Support (@OnePlus_Support) January 13, 2017
A member of the community, @VenomSarad, who had noticed my tweets suggested that, even if they wanted to, OnePlus support were not allowed to suggest disabling applications, and that my time might be better spent looking on their forums:
I did some searching for any other mentions of this analytics data collection, and came across a few forum posts of varying relevance, the closest being this one, as well as a thread on Reddit based off of a tweet from July 2016 rather closely mirroring my own sentiments:
Reading through the Reddit thread, we learn that the code responsible for this data collection is part of the OnePlus Device Manager and the OnePlus Device Manager Provider, which run the
OneplusAnalyticsJobService under the
OnePlus System Service.
In my case, these services had sent 16MB of data in approximately 10 hours.
pm to locate the application package files, we find that it is located at
Grabbing the APK and extracting it using
apktool gives us the manifest and some resources, but no bytecode - this is because, as a system application, it has been optimised, so the
classes.dex file has been removed from the APK archive, optimised into an architecture-specific
.odex file and placed at, in my case,
Running this, in combination with
boot.oat, through baksmali gives us the bytecode for further analysis.
The OnePlus Device Manager (OPDM) which drives the Oneplus System Service, utilises a bunch of libraries - some expected, given the data we’ve seen, and others less so - such as
com.squareup.okhttp for serialisation and making requests, but also namespaces which imply geolocation functionality such as
Here’s a list of the public methods in
net/oneplus/odm/common/Utils.smali, just to give us a good idea for some of the breadth of this functionality, and an indication of some of the kinds of data it might collate:
.method public static encodeToBase64(Ljava/lang/String;)Ljava/lang/String; .method public static getAndroidVersion()Ljava/lang/String; .method public static getBSSID(Landroid/content/Context;)Ljava/lang/String; .method public static getBatteryLevel(Landroid/content/Context;)F .method public static getBatteryStatus(Landroid/content/Context;)Ljava/lang/String; .method public static getBrandName()Ljava/lang/String; .method public static getCellSignalLevel(Landroid/content/Context;)Ljava/lang/String; .method public static getDeviceId()Ljava/lang/String; .method public static getIMEI(Landroid/content/Context;)Ljava/lang/String; .method public static getIMEI1(Landroid/content/Context;)Ljava/lang/String; .method public static getIsHiddenSSID(Landroid/content/Context;)Z .method public static getLocale(Landroid/content/Context;)Ljava/util/Locale; .method public static getMacAddr(Landroid/content/Context;)Ljava/lang/String; .method public static getModelName()Ljava/lang/String; .method public static getOSVersion()Ljava/lang/String; .method public static getPCBA()Ljava/lang/String; .method public static getResolutionHeight(Landroid/content/Context;)I .method public static getResolutionWidth(Landroid/content/Context;)I .method public static getRomVersion()Ljava/lang/String; .method public static getSimCountryCode(Landroid/content/Context;)Ljava/lang/String; .method public static getSoftVersion()Ljava/lang/String; .method public static getTimezone()Ljava/lang/String; .method public static getWifiMacAddress(Landroid/content/Context;)Ljava/lang/String; .method public static getWifiSSID(Landroid/content/Context;)Ljava/lang/String; .method public static getWifiSignalLevel(Landroid/content/Context;)I .method public static isH2()Z .method public static isO2()Z .method public static isRooted()Z
Unfortunately, as a system service, there doesn’t appear to be any way of permanently disabling this data collection or removing this functionality without rooting the phone.
One alternative would be to stop the service every time you boot your phone (assuming it doesn’t get periodically restarted) or using an app to achieve the same effect, or perhaps prevent communication with
This kind of data collection, especially one containing information that can be directly tied back to me as an individual, should really be opt-in and/or have an easily accessible off switch…