• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.libraries.rcs.simpleclient;
18 
19 import android.os.Build.VERSION_CODES;
20 import android.telephony.ims.ImsException;
21 import android.util.Log;
22 
23 import androidx.annotation.RequiresApi;
24 
25 import com.android.libraries.rcs.simpleclient.protocol.sip.SipSession;
26 import com.android.libraries.rcs.simpleclient.provisioning.ProvisioningController;
27 import com.android.libraries.rcs.simpleclient.registration.RegistrationController;
28 import com.android.libraries.rcs.simpleclient.registration.RegistrationStateChangeCallback;
29 import com.android.libraries.rcs.simpleclient.service.ImsService;
30 
31 import java.util.concurrent.atomic.AtomicReference;
32 
33 /**
34  * Simple RCS client implementation.
35  *
36  * State is covered by a context instance.
37  */
38 @RequiresApi(api = VERSION_CODES.R)
39 public class SimpleRcsClient {
40     private static final String TAG = SimpleRcsClient.class.getSimpleName();
41     private final AtomicReference<State> state = new AtomicReference<>(State.NEW);
42     private ProvisioningController provisioningController;
43     private RegistrationController registrationController;
44     private ImsService imsService;
45     private SimpleRcsClientContext context;
46     private StateChangedCallback stateChangedCallback;
47 
newBuilder()48     public static Builder newBuilder() {
49         return new Builder();
50     }
51 
getContext()52     public SimpleRcsClientContext getContext() {
53         return context;
54     }
55 
start()56     public void start() {
57         provision();
58     }
59 
stop()60     public void stop() {
61         Log.i(TAG, "stop..");
62         registrationController.deregister();
63         provisioningController.unRegister();
64         provisioningController = null;
65         registrationController = null;
66         imsService = null;
67     }
68 
onStateChanged(StateChangedCallback cb)69     public void onStateChanged(StateChangedCallback cb) {
70         this.stateChangedCallback = cb;
71     }
72 
enterState(State expected, State newState)73     private boolean enterState(State expected, State newState) {
74         boolean result = state.compareAndSet(expected, newState);
75 
76         if (result && stateChangedCallback != null) {
77             try {
78                 stateChangedCallback.notifyStateChange(expected, newState);
79             } catch (Exception e) {
80                 Log.e(TAG, "Exception on calling state change callback", e);
81             }
82         }
83         Log.i(TAG, "expected:" + expected + " new:" + newState + " res:" + result);
84         return result;
85     }
86 
provision()87     private void provision() {
88         if (!enterState(State.NEW, State.PROVISIONING)) {
89             return;
90         }
91         provisioningController.onConfigurationChange(configXml -> {
92             register();
93         });
94         try {
95             provisioningController.triggerProvisioning();
96         } catch (ImsException e) {
97             // TODO: ...
98         }
99     }
100 
register()101     private void register() {
102         if (!enterState(State.PROVISIONING, State.REGISTERING)) {
103             return;
104         }
105 
106         registrationController.register(imsService,
107                 new RegistrationStateChangeCallback() {
108                     @Override
109                     public void notifyRegStateChanged(ImsService imsService) {
110 
111                     }
112 
113                     @Override
114                     public void onSuccess(SipSession sipSession) {
115                         Log.i(TAG, "onSuccess");
116                         registered(sipSession);
117                     }
118 
119                     @Override
120                     public void onFailure(String reason) {
121                         Log.i(TAG, "onFailure reason:" + reason);
122                         notRegistered();
123                     }
124                 });
125     }
126 
registered(SipSession session)127     private void registered(SipSession session) {
128         if (state.get().equals(State.REGISTERING) || state.get().equals(State.NOT_REGISTERED)) {
129             enterState(state.get(), State.REGISTERED);
130         }
131 
132         context = new SimpleRcsClientContext(provisioningController, registrationController,
133                 imsService,
134                 session);
135 
136         imsService.start(context);
137     }
138 
notRegistered()139     private void notRegistered() {
140         enterState(State.REGISTERED, State.NOT_REGISTERED);
141     }
142 
143     /**
144      * Possible client states.
145      */
146     public enum State {
147         NEW,
148         PROVISIONING,
149         REGISTERING,
150         REGISTERED,
151         NOT_REGISTERED,
152     }
153 
154     /**
155      * Builder for creating new SimpleRcsClient instances.
156      */
157     public static class Builder {
158 
159         private ProvisioningController provisioningController;
160         private RegistrationController registrationController;
161         private ImsService imsService;
162 
provisioningController(ProvisioningController controller)163         public Builder provisioningController(ProvisioningController controller) {
164             this.provisioningController = controller;
165             return this;
166         }
167 
registrationController(RegistrationController controller)168         public Builder registrationController(RegistrationController controller) {
169             this.registrationController = controller;
170             return this;
171         }
172 
imsService(ImsService imsService)173         public Builder imsService(ImsService imsService) {
174             this.imsService = imsService;
175             return this;
176         }
177 
build()178         public SimpleRcsClient build() {
179             SimpleRcsClient client = new SimpleRcsClient();
180             client.registrationController = registrationController;
181             client.provisioningController = provisioningController;
182             client.imsService = imsService;
183 
184             return client;
185         }
186     }
187 }
188