Adapting OAID acquisition in Android system

1. OAID concept

OAID (Open Anonymous Identification) is an anonymous identity identifier
used for ad tracking and personalized ad serving on mobile devices.
It is an industry standard jointly launched by China Mobile Communications Group , China Telecom Group and China Unicom Group
. The OAID value is a 64-bit number.

2. Background of OAID

On Android 10 and above, Android prohibits us from obtaining IMEI. If we want to uniquely identify a mobile phone, we can use OAID.
Because traditional mobile terminal device identifiers such as the International Mobile Equipment Identity (IMEI) have been recognized by some countries as part of user privacy, and there is a risk of tampering and unauthorized use, non-manufacturer system applications in Android 10 and subsequent versions Device information such as IMEI and MAC will not be obtained. Failure to obtain the IMEI will have a certain impact on device identification during the user behavior statistics process.
Recently, the Mobile Security Alliance has joined hands with domestic mobile phone manufacturers to launch a supplementary device standard system plan to address this problem, choosing the OAID field as an alternative field to IMEI and so on. The OAID field is a device identification field jointly launched by the China Academy of Information and Communications Technology and Huawei, Xiaomi, OPPO, VIVO and other manufacturers. It has a certain degree of authority and can meet the usage scenarios of user behavior statistics.

3. Problems caused by OAID

Environment: Qualcomm 865 Android10 virtualization

1. Problem phenomenon

The third-party game application integrates the Mobile Alliance SDK to obtain OAID, but the system is not adapted to OAID. As a result, when the third-party application integrates the Mobile Alliance SDK to obtain OAID, the result is empty and the application crashes.

2. Solution ideas

(1). Write an apk, integrate it into the system, and start automatically at boot. The application defines a service and rewrites the corresponding interface for obtaining oaid. (2) Define
an oaid attribute value. Persist.oaid is used to set and Obtain the OAID value
(3). When a third-party application calls the Mobile Alliance SDK to obtain OAID, it calls the obtain OAID interface rewritten in step 1. This interface reads the OAID value through the attribute value persist.oaid and returns it to the third-party application, so This can avoid getting the oaid value to be empty.

3. Processing steps

3.1 Write apk. Here we take adapting to OPPO manufacturer as an example. Each manufacturer may rewrite the interface and method in different ways, so you need to pay attention here. The oppo manufacturer's code is as follows, you can download the source code to view the details.

The BootCompletedReceiver.java code is as follows:
package com.heytap.openid;

import android.app.ActivityManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.text.TextUtils;
import android.util.Log;

import java.util.List;

public class BootCompletedReceiver extends BroadcastReceiver {

    //    private final String ACTION_BOOT_COMPLETED = "com.matrixlauncher.oncreate"; //开机Launcher广播
    private final String ACTION_BOOT_COMPLETED = "android.intent.action.BOOT_COMPLETED"; //系统开机广播

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent != null) {
            Log.d("CCCCC", "Oppo BootCompletedReceiveronReceive");
            if (!TextUtils.isEmpty(intent.getAction()) && intent.getAction().equals(ACTION_BOOT_COMPLETED)) {
                if (!isRun(context)) {
                    Log.d("CCCCC", "Oppo BootCompletedReceiveronReceive start IdentifyService");
                    context.startService(new Intent(context, IdentifyService.class));
                }
            }
        }
    }

    /**
     * 判断应用是否在运行
     *
     * @param context
     * @return
     */
    public boolean isRun(Context context) {
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningTaskInfo> list = am.getRunningTasks(100);
        boolean isAppRunning = false;
        String MY_PKG_NAME = "com.heytap.openid";
        //100表示取的最大的任务数,info.topActivity表示当前正在运行的Activity,info.baseActivity表系统后台有此进程在运行
        for (ActivityManager.RunningTaskInfo info : list) {
            if (info.topActivity.getPackageName().equals(MY_PKG_NAME) || info.baseActivity.getPackageName().equals(MY_PKG_NAME)) {
                isAppRunning = true;
                break;
            }
        }
        return isAppRunning;
    }
}
IdentifyService.java code is as follows:
package com.heytap.openid;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;

import androidx.annotation.Nullable;

public class IdentifyService extends Service {

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d("CCCCC", "Oppo IdentifyService onCreate()");
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return binder;
    }

    private final IOpenID.Stub binder = new IOpenID.Stub() {
        @Override
        public String getSerID(String pkgName, String sign, String type) throws RemoteException {
            Log.d("CCCCC", "Oppo OpenDeviceIdentifierService.Stub getOaid=" + SysProp.get("persist.oaid", ""));
            return SysProp.get("persist.oaid", "");
        }
    };
}

The IOpenID.aidl code is as follows:

// IOpenID.aidl
package com.heytap.openid;

// Declare any non-default types here with import statements

interface IOpenID {
    String getSerID(String pkgName, String sign, String type);
}

The AndroidManifest.xml code is as follows:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.heytap.openid"
    android:sharedUserId="android.uid.system">

    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <!-- 开机广播 -->
        <receiver
            android:name=".BootCompletedReceiver"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="com.matrixlauncher.oncreate" />
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>
        <service android:name=".IdentifyService"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="action.com.heytap.openid.OPEN_ID_SERVICE" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </service>
    </application>

</manifest>

The code structure is as follows. Note: the package names are fixed:


At the end of the article, relevant information and application service source codes adapted to Huawei, OPPO, Samsung, and Vivo will be attached.

3.2 Integrate the compiled apk into the system (the file and location of the integrated apk are for reference only and may be different. The example integrates OppoAnonymousId.apk)

3.2.1 Qualcomm865_vir/vendor/qcom/proprietary/prebuilt_HY11/target/product/qssi/prebuilt.mk中添加

PRODUCT_PACKAGES += OppoAnonymousId

3.2.2 New attributes in Qualcomm865_vir/device/qcom/qssi/system.prop

#oaid 
persist.oaid=0

3.2.3 Modify the manufacturer value in Qualcomm865_vir/frameworks/base/core/java/android/app/ActivityThread.java

3.2.4 Added apk that needs to be integrated in /home/wenyang/workplace/code/Qualcomm865_vir/vendor/qcom/proprietary/prebuilt_HY11/target/product/qssi/Android.mk

include $(CLEAR_VARS)
LOCAL_MODULE        := OppoAnonymousId
LOCAL_MODULE_OWNER  := qcom
LOCAL_MODULE_TAGS   := optional
LOCAL_MODULE_CLASS  := APPS
LOCAL_CERTIFICATE   := platform
LOCAL_MODULE_SUFFIX := .apk
LOCAL_SRC_FILES     := ../../.././target/product/qssi/system/app/OppoAnonymousId/OppoAnonymousId.apk
LOCAL_MULTILIB := 64
LOCAL_MODULE_PATH   := $(PRODUCT_OUT)/system/app
include $(BUILD_PREBUILT)

3.2.5 Add OppoAnonymousId to device/qcom/qssi/apps_white_list.txt and device/qcom/kona/apps_white_list.txt, as shown in the following figure:

3.3 Modify the equipment manufacturer to OPPO (repeat step 3.2.3, it is recommended to use 3.2.3 to modify the machine. If you modify the ro.product.manufacturer attribute value in the form of machine modification, this step can be ignored) ro.product.manufacturer
 = After modifying the device manufacturer in OPPO
3.4, install and test oaid test_get_oaid.apk to see if it supports obtaining oaid.

4. Verification

4.1 Check if the application exists

 pm list packages | grep com.heytap.openid

If the service starts normally, the following results can be found through the above command:

Or check whether the process exists through the following command:

ps  -A |  grep  com.heytap.openid

4.2 Check whether there is a call to the rewritten interface

When a third-party application obtains oaid, does it call the interface in the apk aidl we wrote? Here we take oppo as an example. Checking the log will call the following interface:

oaid adaptation application source code and related materials download link:  https://download.csdn.net/download/banzhuantuqiang/88331871

Guess you like

Origin blog.csdn.net/banzhuantuqiang/article/details/132832661