最新消息:20210917 已从crifan.com换到crifan.org

【记录】研究Android项目rcsjta中RCS的core的service启动的代码调用逻辑关系和顺序

Service crifan 450浏览 0评论
折腾:
【未解决】Android项目rcsjta中如何才能运行到rcs的core的service
期间,此处整理出rcsjta的代码中
到底是如何调用到RCS的core的service的
其具体调用逻辑和关系和顺序
期间可能会涉及 加断点,调试
startCore
找到
src/com/gsma/rcs/service/RcsCoreService.java
/**
 * Start core
 */
private synchronized void startCore() {

try {
    core = Core.createCore(mCtx, this, mRcsSettings, mContentResolver,
            mLocalContentResolver, mContactManager, mMessagingLog, mHistoryLog,
            mRichCallHistory);

    core.initialize();


    core.startCore();
。。。
加断点调试RI和core
core:没运行到
RI:也没运行到。
再去搜代码:startCore
有好几处调用了:startCore()
都去加上断点
src/com/gsma/rcs/service/StartService.java
@Override
public int onStartCommand(final Intent intent, final int flags, final int startId) {
    if (sLogger.isActivated()) {
        sLogger.debug("Start RCS service");
    }
    mStartServiceHandler = allocateBgHandler(STARTSERVICE_OPERATIONS_THREAD_NAME);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {


        mStartServiceHandler.post(new Runnable() {


            @Override
            public void run() {
                PermissionsManager pm = PermissionsManager.getInstance();
                Boolean allPermissionsGranted = pm.requestForPermissionsAndWaitResponse(mCtx);
                if (allPermissionsGranted) {
                    startCore(intent);
                } else {
                    StartService.this.stopSelf();
                }
            }
        });
    } else {
        startCore(intent);
    }


    /*
     * We want this service to continue running until it is explicitly stopped, so return
     * sticky.
     */
    return START_STICKY;
}
src/com/gsma/rcs/service/RcsCoreService.java
public class RcsCoreService extends Service implements CoreListener {

    @Override
    public void onCreate() {

        mLatch = new CountDownLatch(1);
        mBackgroundHandler.post(new Runnable() {
            @Override
            public void run() {
                try {
                    startCore();
                    mLatch.countDown();
src/com/gsma/rcs/service/RcsCoreService.java
public class RcsCoreService extends Service implements CoreListener {

@Override
public void onCoreLayerStopped() {
    boolean logActivated = sLogger.isActivated();
    // Display a notification
    if (logActivated) {
        sLogger.debug("Handle event core terminated");
    }
    if (!mRestartCoreRequested) {
        return;
    }
    if (logActivated) {
        sLogger.debug("Start the core after previous instance is stopped");
    }


    // @FIXME: This is not the final implementation, this is certainly an improvement over the
    // previous implementation as for now start core will run on worker thread instead of
    // main thread. However there is a need to properly refactor the whole start & stop core
    // functionality to properly handle simultaneous start/stop request's.
    mBackgroundHandler.post(new Runnable() {
        @Override
        public void run() {
            try {
                startCore();
            } catch (RuntimeException e) {
。。。
                sLogger.error("Unable to start IMS core!", e);
            }


        }
    });
}
再去调试看看RI和core
都没有运行到。
startCore(
RcsCoreService
RcsCoreService(
src/com/gsma/rcs/provisioning/https/HttpsProvisioningService.java
public class HttpsProvisioningService extends Service {

@Override
public int onStartCommand(final Intent intent, int flags, int startId) {

mHttpsProvisioningMng.tryLaunchRcsCoreService(mContext, -1);
src/com/gsma/rcs/provisioning/https/HttpsProvisioningManager.java
public class HttpsProvisioningManager {

/* package private */void tryLaunchRcsCoreService(Context context, long timerRetry) {

// Start the RCS service
LauncherUtils.launchRcsCoreService(context, mRcsSettings);
src/com/gsma/rcs/service/LauncherUtils.java
public static void launchRcsCoreService(Context context, RcsSettings rcsSettings) {

if (!rcsSettings.isServiceActivated()) {


context.startService(new Intent(context, RcsCoreService.class));
src/com/gsma/rcs/provider/settings/RcsSettings.java
/**
 * Is RCS service activated
 *
 * @return Boolean
 */
public boolean isServiceActivated() {
    return readBoolean(RcsSettingsData.SERVICE_ACTIVATED);
}
和:
/**
 * Set the RCS service activation state
 *
 * @param state State
 */
public void setServiceActivationState(boolean state) {
    writeBoolean(RcsSettingsData.SERVICE_ACTIVATED, state);
}
src/com/gsma/rcs/service/RcsServiceControlReceiver.java
public class RcsServiceControlReceiver extends BroadcastReceiver {

private boolean setActivationMode(Context ctx, boolean active) {

    mRcsSettings.setServiceActivationState(active);
src/com/gsma/rcs/service/StartService.java
public class StartService extends Service {


private boolean checkAccount() throws IOException, RcsAccountException {


/* Activate service if new account */
mRcsSettings.setServiceActivationState(true);
继续看看
context.startService(
感觉应该是:
src/com/gsma/rcs/service/RcsCoreService.java
public class RcsCoreService extends Service implements CoreListener {

public void onCreate() {
继续去搜:
LauncherUtils.launchRcsCoreService
src/com/gsma/rcs/service/StartService.java
private void connectionEvent(String action) {

LauncherUtils.launchRcsCoreService(mCtx, mRcsSettings);
src/com/gsma/rcs/service/StartService.java
/**
 * Register a broadcast receiver for network state changes
 */
private void registerNetworkStateListener() {

    connectionEvent(action);
src/com/gsma/rcs/service/StartService.java
private void startCore(final Intent intent) {

    registerNetworkStateListener();
好像有个mode:
src/com/gsma/rcs/provider/settings/RcsSettingsData.java
/**
 * The configuration mode enumerated type.
 */
public enum ConfigurationMode {
    /**
     * Manual configuration
     */
    MANUAL(0),
    /**
     * Automatic configuration
     */
    AUTO(1);
。。。
src/com/gsma/rcs/service/StartService.java
@Override
public int onStartCommand(final Intent intent, final int flags, final int startId) {
    if (sLogger.isActivated()) {
        sLogger.debug("Start RCS service");
    }
    mStartServiceHandler = allocateBgHandler(STARTSERVICE_OPERATIONS_THREAD_NAME);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {


        mStartServiceHandler.post(new Runnable() {


            @Override
            public void run() {
                PermissionsManager pm = PermissionsManager.getInstance();
                Boolean allPermissionsGranted = pm.requestForPermissionsAndWaitResponse(mCtx);
                if (allPermissionsGranted) {
                    startCore(intent);
                } else {
                    StartService.this.stopSelf();
                }
            }
        });
    } else {
        startCore(intent);
    }


    /*
     * We want this service to continue running until it is explicitly stopped, so return
     * sticky.
     */
    return START_STICKY;
}
然后注意到了:
onBind是返回null
@Override
public IBinder onBind(Intent intent) {
    return null;
}
说明是:startService的service
那去看:
public class StartService extends Service {
被谁调用了。
搜:
StartService(
很多地方都有调用
期间都去加上断点:
src/com/gsma/rcs/ri/sharing/geoloc/GeolocSharingInvitationReceiver.java
public class GeolocSharingInvitationReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        intent.setClass(context, GeolocSharingIntentService.class);
        context.startService(intent);
    }
}
src/com/gsma/rcs/ri/DeviceBoot.java
/**
 * On device boot starts the RCS service notification manager automatically
 * 
 * @author Jean-Marc AUFFRET
 */
public class DeviceBoot extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
            context.startService(new Intent(context, RcsServiceNotifManager.class));
        }
    }
}
发现搞错了:
此处是大写的S:StartService
所以区分大小写后再去搜:
只有2处,且还不是StartService
只有这里
src/com/gsma/rcs/service/StartService.java
/**
 * Launch the RCS start service
 *
 * @param context the context
 * @param boot start RCS service upon boot
 * @param user start RCS service upon user action
 */
static void LaunchRcsStartService(Context context, boolean boot, boolean user) {
    if (sLogger.isActivated())
        sLogger.debug("Launch RCS service (boot=" + boot + ") (user=" + user + ")");
    Intent intent = new Intent(context, StartService.class);
    intent.putExtra(INTENT_KEY_BOOT, boot);
    intent.putExtra(INTENT_KEY_USER, user);
    context.startService(intent);
}
是的
src/com/gsma/rcs/service/LauncherUtils.java
public static void launchRcsService(Context context, boolean boot, boolean user,
        RcsSettings rcsSettings) {
    /* Set the logger properties */
    Logger.sActivationFlag = rcsSettings.isTraceActivated();
    Logger.traceLevel = rcsSettings.getTraceLevel();
    if (rcsSettings.isServiceActivated()) {
        StartService.LaunchRcsStartService(context, boot, user);
    }
}
又算回到了之前的:
LauncherUtils.launchRcsService
了。
src/com/gsma/rcs/addressbook/SetupRcsAccount.java
public class SetupRcsAccount extends android.accounts.AccountAuthenticatorActivity {

public void onCreate(Bundle icicle) {

LauncherUtils.launchRcsService(ctx, false, false, rcsSettings);
src/com/gsma/rcs/provisioning/https/ProvisioningPushSMSReceiver.java
private void resetConfigurationThenRestart(Context ctx, ContentResolver resolver,
        LocalContentResolver localResolver, RcsSettings rcsSettings) {
    /* IMSI in smsData : fresh provisioning */
    LauncherUtils.stopRcsService(ctx);
    final ContactManager contactManager = ContactManager.getInstance(ctx, resolver,
            localResolver, rcsSettings);
    final MessagingLog messagingLog = MessagingLog.getInstance(localResolver, rcsSettings);
    LauncherUtils.resetRcsConfig(ctx, localResolver, rcsSettings, messagingLog, contactManager);
    LauncherUtils.launchRcsService(ctx, true, false, rcsSettings);
}
src/com/gsma/rcs/service/DeviceBoot.java
/**
 * Device boot event receiver: automatically starts the RCS service
 * 
 * @author jexa7410
 */
public class DeviceBoot extends BroadcastReceiver {
    private static Logger logger = Logger.getLogger(DeviceBoot.class.getSimpleName());


    @Override
    public void onReceive(Context context, Intent intent) {
        if (logger.isActivated())
            logger.debug("Start RCS service after boot");
        LocalContentResolver localContentResolver = new LocalContentResolver(context);
        RcsSettings rcsSettings = RcsSettings.getInstance(localContentResolver);
        LauncherUtils.launchRcsService(context, true, false, rcsSettings);
    }
}
src/com/gsma/rcs/service/RcsCoreService.java
@Override
public void onSimChangeDetected() {
    if (sLogger.isActivated()) {
        sLogger.debug("Handle SIM has changed");
    }
    // Restart the RCS service
    LauncherUtils.stopRcsService(mCtx);
    LauncherUtils.launchRcsService(mCtx, true, false, mRcsSettings);
}
src/com/gsma/rcs/service/RcsServiceControlReceiver.java
private boolean setActivationMode(Context ctx, boolean active) {

    LauncherUtils.launchRcsService(ctx, false, true, mRcsSettings);
也分别加上断点
分别去看看,如何被调用的
先看看:DeviceBoot
/rcsjta/core/AndroidManifest.xml
<receiver android:name="com.gsma.rcs.service.DeviceBoot">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED"/>
    </intent-filter>
</receiver>
是个receiver
继续:resetConfigurationThenRestart
src/com/gsma/rcs/provisioning/https/ProvisioningPushSMSReceiver.java
public class ProvisioningPushSMSReceiver extends BroadcastReceiver {
。。。
    @Override
    public void onReceive(Context ctx, Intent intent) {

if (smsData.contains(telephonyManager.getSubscriberId())) {
    resetConfigurationThenRestart(ctx, resolver, localResolver, rcsSettings);
} else if (smsData.contains(rcsSettings.getUserProfileImsPrivateId())) {
    if (NetworkUtils.getNetworkAccessType() == 
NetworkUtils.NETWORK_ACCESS_WIFI
) {
        tryUnRegister();
        /*
         * Only set version number to 0 in order to keep MSISDN and token.
         * Reprovisioning is done silently: the user is not prompted to enter its
         * MSISDN.
         */
        rcsSettings.setProvisioningVersion(ProvisioningInfo.Version.RESETED.toInt());
        HttpsProvisioningService.reProvisioning(ctx);
    } else {
        resetConfigurationThenRestart(ctx, resolver, localResolver, rcsSettings);
    }
}
AndroidManifest.xml
<!-- Provisioning Push SMS Receiver -->
<receiver android:name="com.gsma.rcs.provisioning.https.ProvisioningPushSMSReceiver">
    <intent-filter>
        <action android:name="android.intent.action.DATA_SMS_RECEIVED"/>
        <data
            android:host="localhost"
            android:port="37273"
            android:scheme="sms"/>
    </intent-filter>
</receiver>
感觉是:
收到了SMS消息后,会调用此处逻辑。
以及:
setActivationMode
src/com/gsma/rcs/service/RcsServiceControlReceiver.java
* A class to control the service activation.
public class RcsServiceControlReceiver extends BroadcastReceiver {

public void onReceive(Context ctx, Intent intent) {
。。。
    IntentProcessor intentProcessor = new IntentProcessor(ctx, intent, result);

private class IntentProcessor extends Thread {


@Override
public void run() {

case Intents.Service.ACTION_SET_ACTIVATION_MODE: {
    boolean active = mIntent.getBooleanExtra(
            Intents.Service.EXTRA_SET_ACTIVATION_MODE, true);
    activationMode = setActivationMode(mCtx, active);
    mResult.putBoolean(Intents.Service.EXTRA_SET_ACTIVATION_MODE,
            activationMode);
    if (sAccurateLog && sLogger.isActivated()) {
        sLogger.debug("setActivationMode(" + active + ") -> " + activationMode);
    }
    break;
}
去看看
RcsServiceControlReceiver
AndroidManifest.xml
<!-- RCS API -->

<receiver android:name="com.gsma.rcs.service.RcsServiceControlReceiver">
    <intent-filter>
        <action android:name="com.gsma.services.rcs.action.GET_ACTIVATION_MODE_CHANGEABLE"/>
        <action android:name="com.gsma.services.rcs.action.GET_ACTIVATION_MODE"/>
        <action android:name="com.gsma.services.rcs.action.SET_ACTIVATION_MODE"/>
        <action android:name="com.gsma.services.rcs.action.GET_COMPATIBILITY"/>
        <action android:name="com.gsma.services.rcs.action.GET_SERVICE_STARTING_STATE"/>
    </intent-filter>
</receiver>
另外看到和rcs服务有关的:
<!-- Startup service -->
<service android:name="com.gsma.rcs.service.StartService"/>
以及:
<!-- HTTPS provisioning service -->
<service android:name="com.gsma.rcs.provisioning.https.HttpsProvisioningService"/>
好像是:
定义到这里后,app启动后,就会调用这里的service?
如果是的话,那么对于:
com.gsma.rcs.service.StartService
这里就是其中一个启动的地方
->之前搜:
StartService
且区分大小写,没搜到。现在找到了。
不过再去试试Find Usages试试:
是能找到的。
那目前看来:
/RCS/rcsjta/core/AndroidManifest.xml
core的apk的AndroidManifest.xml定义了:
<!-- Startup service -->
<service android:name="com.gsma.rcs.service.StartService"/>
启动后,应该就会运行到对应代码
即:
src/com/gsma/rcs/service/StartService.java
public class StartService extends Service {

    public void onCreate() {
才对
去调试看看
结果app启动后,没有运行到断点位置
后续折腾:
【未解决】通过调试core加运行RI去研究rcsjta的服务没运行的原因
期间,继续回来看代码逻辑。
然后继续专门研究:
【记录】研究rcsjta中的RcsCoreService的代码调用逻辑和顺序
目前还没完全搞懂调用逻辑。
然后也去试试:
【未解决】通过调试rcs的core加运行其他几个apk去研究rcsjta的服务没运行的原因

转载请注明:在路上 » 【记录】研究Android项目rcsjta中RCS的core的service启动的代码调用逻辑关系和顺序

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
90 queries in 0.182 seconds, using 23.42MB memory