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

【基本解决】研究rcsjta中源码中和启动RCS的服务的相关代码和逻辑

RCS crifan 475浏览 0评论
折腾:
【未解决】rcsjta中RCS的RI中各种功能都提示:The service is not available Please retry later
期间,先去研究代码中,和此处服务没启动,有哪些相关的代码和逻辑。
搜:
The service is not available
找到:
很多个。其中RI中的是:
/Users/xxx/dev/xxx/RCS/rcsjta/RI/res/values/strings.xml
    <string name="label_service_not_available">The service is not available. Please retry later.</string>
去找找代码中哪里用到了:label_service_not_available
看到了 Capability的对应代码
/Users/xxx/dev/xxx/RCS/rcsjta/RI/src/com/gsma/rcs/ri/capabilities/MyCapabilities.java
public class MyCapabilities extends RcsActivity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        setContentView(R.layout.capabilities_mine);

        /* Register to API connection manager */
        if (!isServiceConnected(RcsServiceName.CAPABILITY)) {
            showMessageThenExit(R.string.label_service_not_available);
            return;
        }
        startMonitorServices(RcsServiceName.CAPABILITY);
    }
继续去研究代码
 isServiceConnected(
找到多处定义

找到了
rcsjta/libs/api_cnx/src/main/java/com/gsma/rcs/api/connection/ConnectionManager.java
    /**
     * Check if services are connected
     *
     * @param services list of services
     * @return true if all services of the list are connected
     */
    public boolean isServiceConnected(RcsServiceName... services) {
        for (RcsServiceName service : services) {
            if (!mManagedServices.contains(service)) {
                throw new IllegalArgumentException("Service " + service
                        + " does not belong to set of managed services!");
            }
            if (!mConnectedServices.contains(service)) {
                return false;
            }
        }
        return true;
    }
其他地方都是调用这个ConnectionManager.java中的isServiceConnected
且其中的:mManagedServices
是开始初始化包含的一个列表:
    /**
     * The set of managed services
     */
    private final Set<RcsServiceName> mManagedServices;


    /**
     * Constructor
     *
     * @param context The context
     * @param managedServices Set of managed services
     * @param rcsServiceControl instance of RcsServiceControl
     */
    private ConnectionManager(Context context, Set<RcsServiceName> managedServices,
            RcsServiceControl rcsServiceControl) {
        mCtx = context;
        mCnxIntent = PendingIntent.getBroadcast(context, 0, new Intent(ACTION_CONNECT), 0);
        mAlarmManager = (AlarmManager) mCtx.getSystemService(Context.ALARM_SERVICE);


        mManagedServices = managedServices;
        mRcsServiceControl = rcsServiceControl;
        /* Construct list of connected services */
        mConnectedServices = new HashSet<>();
        /* Construct list of clients to notify */
        mClientsToNotify = new HashMap<>();
        /* Construct list of APIs */
        mApis = new HashMap<>();


        if (managedServices == null || managedServices.isEmpty()) {
            throw new RuntimeException("Incorrect parameter managedService!");
        }
        /* Instantiate APIs */
        for (RcsServiceName service : mManagedServices) {
            switch (service) {
                case CAPABILITY:
                    mApis.put(RcsServiceName.CAPABILITY, new CapabilityService(context,
                            newRcsServiceListener(RcsServiceName.CAPABILITY)));
                    break;
                case CHAT:
                    mApis.put(RcsServiceName.CHAT, new ChatService(context,
                            newRcsServiceListener(RcsServiceName.CHAT)));
                    break;
                case CONTACT:
                    mApis.put(RcsServiceName.CONTACT, new ContactService(context,
                            newRcsServiceListener(RcsServiceName.CONTACT)));
                    break;
                case FILE_TRANSFER:
                    mApis.put(RcsServiceName.FILE_TRANSFER, new FileTransferService(context,
                            newRcsServiceListener(RcsServiceName.FILE_TRANSFER)));
                    break;
                case FILE_UPLOAD:
                    mApis.put(RcsServiceName.FILE_UPLOAD, new FileUploadService(context,
                            newRcsServiceListener(RcsServiceName.FILE_UPLOAD)));
                    break;
                case GEOLOC_SHARING:
                    mApis.put(RcsServiceName.GEOLOC_SHARING, new GeolocSharingService(context,
                            newRcsServiceListener(RcsServiceName.GEOLOC_SHARING)));
                    break;
                case HISTORY:
                    mApis.put(RcsServiceName.HISTORY, new HistoryService(context,
                            newRcsServiceListener(RcsServiceName.HISTORY)));
                    break;
                case IMAGE_SHARING:
                    mApis.put(RcsServiceName.IMAGE_SHARING, new ImageSharingService(context,
                            newRcsServiceListener(RcsServiceName.IMAGE_SHARING)));
                    break;
                case MULTIMEDIA:
                    mApis.put(RcsServiceName.MULTIMEDIA, new MultimediaSessionService(context,
                            newRcsServiceListener(RcsServiceName.MULTIMEDIA)));
                    break;
                case VIDEO_SHARING:
                    mApis.put(RcsServiceName.VIDEO_SHARING, new VideoSharingService(context,
                            newRcsServiceListener(RcsServiceName.VIDEO_SHARING)));
                    break;
            }
        }
    }
其中容易看出是各个功能和服务项目:
  • CAPABILITY
  • CHAT
  • CONTACT
  • FILE_TRANSFER
  • FILE_UPLOAD
  • GEOLOC_SHARING
  • HISTORY
  • IMAGE_SHARING
  • MULTIMEDIA
  • VIDEO_SHARING
再去看看mConnectedServices
    /**
     * Set of connected services
     */
    private final Set<RcsServiceName> mConnectedServices;


        mConnectedServices = new HashSet<>();


    /**
     * Create a RCS service listener to monitor API connection
     *
     * @param service the service to monitor
     * @return the listener
     */
    private RcsServiceListener newRcsServiceListener(final RcsServiceName service) {
        return new RcsServiceListener() {
            @Override
            public void onServiceConnected() {
                mConnectedServices.add(service);
                notifyConnection(service);
            }


            @Override
            public void onServiceDisconnected(ReasonCode error) {
                mConnectedServices.remove(service);
                notifyDisconnection(service, error);
            }
        };


    }

        public void notifyConnection() {
            if (mListener == null) {
                return;
            }
            if (mConnectedServices.containsAll(mMonitoredServices)) {
                /* All monitored services are connected -> notify connection */
                mListener.onServiceConnected();
                mRetryCount = 0;
            }
        }
其中的:newRcsServiceListener
就是前面调用的
不过注意到开始的ConnectionManager()初始化期间,是根据传入的mManagedServices去初始化对应服务的
所以要再去找找,有哪些用到了:
 ConnectionManager(
只有自己
libs/api_cnx/src/main/java/com/gsma/rcs/api/connection/ConnectionManager.java
    /**
     * Get an instance of ConnectionManager.
     *
     * @param ctx the context
     * @param rcsServiceControl instance of RcsServiceControl
     * @param managedServices Set of managed services
     * @return the singleton instance.
     */
    public static ConnectionManager createInstance(Context ctx,
            RcsServiceControl rcsServiceControl, Set<RcsServiceName> managedServices) {
        if (sInstance != null) {
            return sInstance;
        }
        synchronized (ConnectionManager.class) {
            if (sInstance == null) {
                if (ctx == null) {
                    throw new IllegalArgumentException("Context is null");
                }
                sInstance = new ConnectionManager(ctx, managedServices, rcsServiceControl);
            }
        }
        return sInstance;
    }
继续研究原因
继续找:
createInstance(
找到:
libs/api_cnx/src/main/java/com/gsma/rcs/api/connection/ConnectionManager.java
    /**
     * Get an instance of ConnectionManager.
     *
     * @param context the context
     * @param rcsServiceControl instance of RcsServiceControl
     * @param services list of managed services
     * @return the singleton instance.
     */
    public static ConnectionManager createInstance(Context context,
            RcsServiceControl rcsServiceControl, RcsServiceName... services) {
        Set<RcsServiceName> managedServices = new HashSet<>();
        Collections.addAll(managedServices, services);
        return createInstance(context, rcsServiceControl, managedServices);
    }
以及真正的调用去初始化:
RI/src/com/gsma/rcs/ri/RiApplication.java
    @Override
    public void onCreate() {
        super.onCreate();
。。。

        mRcsServiceControl = RcsServiceControl.getInstance(mContext);


        /* Starts the RCS service notification manager */
        startService(new Intent(this, RcsServiceNotifManager.class));


        /* Do not execute the ConnectionManager on the main thread */
        Handler mainThreadHandler = new Handler(Looper.getMainLooper());
        final ConnectionManager cnxManager = ConnectionManager.createInstance(mContext,
                mRcsServiceControl, EnumSet.allOf(RcsServiceName.class));
        mainThreadHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                try {
                    cnxManager.start();
                    sCnxManagerStarted = true;


                } catch (RuntimeException e) {
                    Log.e(LOGTAG, "Failed to start connection manager!", e);
                }
            }
        }, DELAY_FOR_STARTING_CNX_MANAGER);
    }
和:
tools/settings/src/com/gsma/rcs/core/control/CoreControlApplication.java
public class CoreControlApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        Context context = getApplicationContext();
        mRcsServiceControl = RcsServiceControl.getInstance(context);


        final ConnectionManager cnxManager = ConnectionManager.createInstance(context,
                mRcsServiceControl, RcsServiceName.FILE_TRANSFER, RcsServiceName.CHAT,
                RcsServiceName.CONTACT);


        /* Do not execute the ConnectionManager on the main thread */
        Handler mainThreadHandler = new Handler(Looper.getMainLooper());


        mainThreadHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                cnxManager.start();
                sCnxManagerStarted = true;
            }
        }, DELAY_FOR_STARTING_CNX_MANAGER);
    }
此处很明显,Core的control的application中,最开始启动时,只初始化了:
  • FILE_TRANSFER
  • CHAT
  • CONTACT
并没有初始化其他的服务
比如Capability之类的
不知道为何?
去搜索其他的:
RcsServiceName.CAPABILITY
能找到其他的
但是没有找到 去启用的相关逻辑
所以难怪app中没看到服务启动
那如何启动其他如Capability的服务?
直接修改代码去加上?
感觉好像不太对啊,应该是哪里有配置,最开始启动哪些服务才对
去Core的app中看看
不过才注意到:
RI/src/com/gsma/rcs/ri/RiApplication.java
中的:
final ConnectionManager cnxManager = ConnectionManager.createInstance(mContext,
                mRcsServiceControl, EnumSet.allOf(RcsServiceName.class));
就是:
启动了RcsServiceName的所有的类名
就是启动了所有的服务才对
即:
RI的参考实现中,最开始是去启动了所有的服务的
对于RcsServiceName的定义,找了半天终于通过搜:
package com.gsma.rcs.api
间接的,最后找到了位置:
是在api_cnx中的:
libs/api_cnx/src/main/java/com/gsma/rcs/api/connection/ConnectionManager.java
而以为能找到原始定义:
        /* Instantiate APIs */
        for (RcsServiceName service : mManagedServices) {
            switch (service) {
                case CAPABILITY:
                    mApis.put(RcsServiceName.CAPABILITY, new CapabilityService(context,
                            newRcsServiceListener(RcsServiceName.CAPABILITY)));
                    break;
                case CHAT:
                    mApis.put(RcsServiceName.CHAT, new ChatService(context,
                            newRcsServiceListener(RcsServiceName.CHAT)));
                    break;
                case CONTACT:
                    mApis.put(RcsServiceName.CONTACT, new ContactService(context,
                            newRcsServiceListener(RcsServiceName.CONTACT)));
                    break;
                case FILE_TRANSFER:
                    mApis.put(RcsServiceName.FILE_TRANSFER, new FileTransferService(context,
                            newRcsServiceListener(RcsServiceName.FILE_TRANSFER)));
                    break;
                case FILE_UPLOAD:
                    mApis.put(RcsServiceName.FILE_UPLOAD, new FileUploadService(context,
                            newRcsServiceListener(RcsServiceName.FILE_UPLOAD)));
                    break;
                case GEOLOC_SHARING:
                    mApis.put(RcsServiceName.GEOLOC_SHARING, new GeolocSharingService(context,
                            newRcsServiceListener(RcsServiceName.GEOLOC_SHARING)));
                    break;
                case HISTORY:
                    mApis.put(RcsServiceName.HISTORY, new HistoryService(context,
                            newRcsServiceListener(RcsServiceName.HISTORY)));
                    break;
                case IMAGE_SHARING:
                    mApis.put(RcsServiceName.IMAGE_SHARING, new ImageSharingService(context,
                            newRcsServiceListener(RcsServiceName.IMAGE_SHARING)));
                    break;
                case MULTIMEDIA:
                    mApis.put(RcsServiceName.MULTIMEDIA, new MultimediaSessionService(context,
                            newRcsServiceListener(RcsServiceName.MULTIMEDIA)));
                    break;
                case VIDEO_SHARING:
                    mApis.put(RcsServiceName.VIDEO_SHARING, new VideoSharingService(context,
                            newRcsServiceListener(RcsServiceName.VIDEO_SHARING)));
                    break;
            }
还是没有直接定义。
然后去找最原始的定义
通过:
VIDEO_SHARING
找到:
core/src/com/gsma/rcs/provider/sharing/VideoSharingProvider.java
    private static final class UriType {


        private static final class VideoSharing {
            private static final int VIDEO_SHARING = 1;


            private static final int VIDEO_SHARING_WITH_ID = 2;
        }


        private static final class InternalVideoSharing {
            private static final int VIDEO_SHARING = 3;


            private static final int VIDEO_SHARING_WITH_ID = 4;
        }
    }
看来是:不同的类和实现中,有最原始的定义,且是 int值
不过后来终于找到了定义:
libs/api_cnx/src/main/java/com/gsma/rcs/api/connection/ConnectionManager.java
    /**
     * Enumerated type for RCS service name
     */
    @SuppressWarnings("javadoc")
    public enum RcsServiceName {
        CAPABILITY, CONTACT, CHAT, FILE_TRANSFER, IMAGE_SHARING, VIDEO_SHARING, GEOLOC_SHARING, FILE_UPLOAD, MULTIMEDIA, HISTORY
    }
即:该文件中是有定义的。
不是在每个具体实现中定义的。前面理解有误。
反推再去搜:
enum RcsServiceName
只能找到此处这一处:
也是对的。
至此:
基本上确定,代码逻辑上来说,应该就是:
RI/src/com/gsma/rcs/ri/RiApplication.java
        /* Do not execute the ConnectionManager on the main thread */
        Handler mainThreadHandler = new Handler(Looper.getMainLooper());
        final ConnectionManager cnxManager = ConnectionManager.createInstance(mContext,
                mRcsServiceControl, EnumSet.allOf(RcsServiceName.class));
        mainThreadHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                try {
                    cnxManager.start();
                    sCnxManagerStarted = true;


                } catch (RuntimeException e) {
                    Log.e(LOGTAG, "Failed to start connection manager!", e);
                }
            }
        }, DELAY_FOR_STARTING_CNX_MANAGER);
    }
这句:
final ConnectionManager cnxManager = ConnectionManager.createInstance(mContext,
                mRcsServiceControl, EnumSet.allOf(RcsServiceName.class));
去启动了RCS所有的服务。
至于后续为何服务还是没启动,则需要深入调研其他方面,继续找原因了。


转载请注明:在路上 » 【基本解决】研究rcsjta中源码中和启动RCS的服务的相关代码和逻辑

发表我的评论
取消评论

表情

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

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
86 queries in 0.262 seconds, using 20.19MB memory