1fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal/*
2fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal * Copyright (C) 2014 The Android Open Source Project
3fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal *
4fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal * Licensed under the Apache License, Version 2.0 (the "License");
5fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal * you may not use this file except in compliance with the License.
6fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal * You may obtain a copy of the License at
7fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal *
8fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal *      http://www.apache.org/licenses/LICENSE-2.0
9fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal *
10fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal * Unless required by applicable law or agreed to in writing, software
11fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal * distributed under the License is distributed on an "AS IS" BASIS,
12fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal * See the License for the specific language governing permissions and
14fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal * limitations under the License
15fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal */
16fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal
17fc22ba88566ef70e202128335231c367de6c52afSailesh Nepalpackage com.android.incallui;
18fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal
190afa8f450a86517bac3009dbae94ed4973de4dddSantos Cordonimport android.content.ActivityNotFoundException;
200afa8f450a86517bac3009dbae94ed4973de4dddSantos Cordonimport android.content.Intent;
21fc22ba88566ef70e202128335231c367de6c52afSailesh Nepalimport android.os.Looper;
220ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordonimport android.telecom.InCallService;
236cddf46812634fadc194830774110780f14e9462Tyler Gunnimport android.telecom.PhoneAccountHandle;
24fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal
25fc22ba88566ef70e202128335231c367de6c52afSailesh Nepalimport com.google.common.base.Preconditions;
26fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal
27c79d745deeda2cdd2b17122602a32812132885aaSantos Cordonimport java.util.List;
28c79d745deeda2cdd2b17122602a32812132885aaSantos Cordon
290ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordonfinal class TelecomAdapter implements InCallServiceListener {
300afa8f450a86517bac3009dbae94ed4973de4dddSantos Cordon    private static final String ADD_CALL_MODE_KEY = "add_call_mode";
310afa8f450a86517bac3009dbae94ed4973de4dddSantos Cordon
326cddf46812634fadc194830774110780f14e9462Tyler Gunn    private static TelecomAdapter sInstance;
330ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon    private InCallService mInCallService;
34fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal
356cddf46812634fadc194830774110780f14e9462Tyler Gunn    static TelecomAdapter getInstance() {
36fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal        Preconditions.checkState(Looper.getMainLooper().getThread() == Thread.currentThread());
37fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal        if (sInstance == null) {
386cddf46812634fadc194830774110780f14e9462Tyler Gunn            sInstance = new TelecomAdapter();
39fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal        }
40fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal        return sInstance;
41fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal    }
42fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal
436cddf46812634fadc194830774110780f14e9462Tyler Gunn    private TelecomAdapter() {
44fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal    }
45fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal
46df06e232852a93d8238f3cacaab4d704de7e1216Ihab Awad    @Override
470ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon    public void setInCallService(InCallService inCallService) {
480ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon        mInCallService = inCallService;
49df06e232852a93d8238f3cacaab4d704de7e1216Ihab Awad    }
50df06e232852a93d8238f3cacaab4d704de7e1216Ihab Awad
51df06e232852a93d8238f3cacaab4d704de7e1216Ihab Awad    @Override
520ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon    public void clearInCallService() {
530ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon        mInCallService = null;
54df06e232852a93d8238f3cacaab4d704de7e1216Ihab Awad    }
55df06e232852a93d8238f3cacaab4d704de7e1216Ihab Awad
566cddf46812634fadc194830774110780f14e9462Tyler Gunn    private android.telecom.Call getTelecommCallById(String callId) {
570ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon        Call call = CallList.getInstance().getCallById(callId);
58f3400c7cebb84af2a25137f536d17c1f3c50b556Yorke Lee        return call == null ? null : call.getTelecommCall();
59fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal    }
60fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal
619044e6296320cac2ee7c49465fdbb4a55912058aAndrew Lee    void answerCall(String callId, int videoState) {
620ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon        android.telecom.Call call = getTelecommCallById(callId);
630ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon        if (call != null) {
640ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon            call.answer(videoState);
65fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal        } else {
660ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon            Log.e(this, "error answerCall, call not in call list: " + callId);
67fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal        }
68fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal    }
69fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal
706af0c61c32da6cfb400168ae3b0cf9f802abfed4Sailesh Nepal    void rejectCall(String callId, boolean rejectWithMessage, String message) {
710ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon        android.telecom.Call call = getTelecommCallById(callId);
720ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon        if (call != null) {
730ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon            call.reject(rejectWithMessage, message);
74fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal        } else {
750ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon            Log.e(this, "error rejectCall, call not in call list: " + callId);
76fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal        }
77fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal    }
78fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal
796af0c61c32da6cfb400168ae3b0cf9f802abfed4Sailesh Nepal    void disconnectCall(String callId) {
800ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon        android.telecom.Call call = getTelecommCallById(callId);
810ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon        if (call != null) {
820ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon            call.disconnect();
83fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal        } else {
840ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon            Log.e(this, "error disconnectCall, call not in call list " + callId);
85fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal        }
86fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal    }
87fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal
886af0c61c32da6cfb400168ae3b0cf9f802abfed4Sailesh Nepal    void holdCall(String callId) {
890ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon        android.telecom.Call call = getTelecommCallById(callId);
900ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon        if (call != null) {
910ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon            call.hold();
92fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal        } else {
930ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon            Log.e(this, "error holdCall, call not in call list " + callId);
94fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal        }
95fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal    }
96fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal
976af0c61c32da6cfb400168ae3b0cf9f802abfed4Sailesh Nepal    void unholdCall(String callId) {
980ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon        android.telecom.Call call = getTelecommCallById(callId);
990ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon        if (call != null) {
1000ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon            call.unhold();
101fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal        } else {
1020ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon            Log.e(this, "error unholdCall, call not in call list " + callId);
103fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal        }
104fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal    }
105fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal
106fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal    void mute(boolean shouldMute) {
1070ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon        if (mInCallService != null) {
1080ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon            mInCallService.setMuted(shouldMute);
109fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal        } else {
1100ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon            Log.e(this, "error mute, mInCallService is null");
111fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal        }
112fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal    }
113fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal
114fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal    void setAudioRoute(int route) {
1150ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon        if (mInCallService != null) {
1160ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon            mInCallService.setAudioRoute(route);
117fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal        } else {
1180ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon            Log.e(this, "error setAudioRoute, mInCallService is null");
119fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal        }
120fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal    }
121fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal
1226af0c61c32da6cfb400168ae3b0cf9f802abfed4Sailesh Nepal    void separateCall(String callId) {
1230ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon        android.telecom.Call call = getTelecommCallById(callId);
1240ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon        if (call != null) {
1250ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon            call.splitFromConference();
126c9e18a969b97f6d110c1e1e84240d4828706c401Santos Cordon        } else {
1270ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon            Log.e(this, "error separateCall, call not in call list " + callId);
128c9e18a969b97f6d110c1e1e84240d4828706c401Santos Cordon        }
129fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal    }
130fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal
131c9e18a969b97f6d110c1e1e84240d4828706c401Santos Cordon    void merge(String callId) {
1320ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon        android.telecom.Call call = getTelecommCallById(callId);
1330ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon        if (call != null) {
1346cddf46812634fadc194830774110780f14e9462Tyler Gunn            List<android.telecom.Call> conferenceable = call.getConferenceableCalls();
135c79d745deeda2cdd2b17122602a32812132885aaSantos Cordon            if (!conferenceable.isEmpty()) {
136c79d745deeda2cdd2b17122602a32812132885aaSantos Cordon                call.conference(conferenceable.get(0));
13752c30ebe11e132c5b00a15aabdf4a411355bf0f4Santos Cordon            } else {
138737f56760b617688aac7218021a5e615ed750810Ihab Awad                if (call.getDetails().can(
139737f56760b617688aac7218021a5e615ed750810Ihab Awad                        android.telecom.Call.Details.CAPABILITY_MERGE_CONFERENCE)) {
14052c30ebe11e132c5b00a15aabdf4a411355bf0f4Santos Cordon                    call.mergeConference();
14152c30ebe11e132c5b00a15aabdf4a411355bf0f4Santos Cordon                }
142c79d745deeda2cdd2b17122602a32812132885aaSantos Cordon            }
143c9e18a969b97f6d110c1e1e84240d4828706c401Santos Cordon        } else {
1440ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon            Log.e(this, "error merge, call not in call list " + callId);
145c9e18a969b97f6d110c1e1e84240d4828706c401Santos Cordon        }
146fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal    }
147fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal
1485461c6a3b5090e6fab47076c5c0aeb2d1091606dSailesh Nepal    void swap(String callId) {
1490ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon        android.telecom.Call call = getTelecommCallById(callId);
1500ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon        if (call != null) {
151737f56760b617688aac7218021a5e615ed750810Ihab Awad            if (call.getDetails().can(
152737f56760b617688aac7218021a5e615ed750810Ihab Awad                    android.telecom.Call.Details.CAPABILITY_SWAP_CONFERENCE)) {
15352c30ebe11e132c5b00a15aabdf4a411355bf0f4Santos Cordon                call.swapConference();
15452c30ebe11e132c5b00a15aabdf4a411355bf0f4Santos Cordon            }
15552c30ebe11e132c5b00a15aabdf4a411355bf0f4Santos Cordon        } else {
1560ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon            Log.e(this, "error swap, call not in call list " + callId);
15752c30ebe11e132c5b00a15aabdf4a411355bf0f4Santos Cordon        }
158fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal    }
159fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal
160fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal    void addCall() {
1610ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon        if (mInCallService != null) {
1620afa8f450a86517bac3009dbae94ed4973de4dddSantos Cordon            Intent intent = new Intent(Intent.ACTION_DIAL);
1630afa8f450a86517bac3009dbae94ed4973de4dddSantos Cordon            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1640afa8f450a86517bac3009dbae94ed4973de4dddSantos Cordon
1650afa8f450a86517bac3009dbae94ed4973de4dddSantos Cordon            // when we request the dialer come up, we also want to inform
1660afa8f450a86517bac3009dbae94ed4973de4dddSantos Cordon            // it that we're going through the "add call" option from the
1670afa8f450a86517bac3009dbae94ed4973de4dddSantos Cordon            // InCallScreen / PhoneUtils.
1680afa8f450a86517bac3009dbae94ed4973de4dddSantos Cordon            intent.putExtra(ADD_CALL_MODE_KEY, true);
1690afa8f450a86517bac3009dbae94ed4973de4dddSantos Cordon            try {
1700afa8f450a86517bac3009dbae94ed4973de4dddSantos Cordon                Log.d(this, "Sending the add Call intent");
1710ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon                mInCallService.startActivity(intent);
1720afa8f450a86517bac3009dbae94ed4973de4dddSantos Cordon            } catch (ActivityNotFoundException e) {
1730afa8f450a86517bac3009dbae94ed4973de4dddSantos Cordon                // This is rather rare but possible.
1740afa8f450a86517bac3009dbae94ed4973de4dddSantos Cordon                // Note: this method is used even when the phone is encrypted. At that moment
1750afa8f450a86517bac3009dbae94ed4973de4dddSantos Cordon                // the system may not find any Activity which can accept this Intent.
1760afa8f450a86517bac3009dbae94ed4973de4dddSantos Cordon                Log.e(this, "Activity for adding calls isn't found.", e);
1770afa8f450a86517bac3009dbae94ed4973de4dddSantos Cordon            }
1780afa8f450a86517bac3009dbae94ed4973de4dddSantos Cordon        }
179fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal    }
180fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal
1816af0c61c32da6cfb400168ae3b0cf9f802abfed4Sailesh Nepal    void playDtmfTone(String callId, char digit) {
1820ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon        android.telecom.Call call = getTelecommCallById(callId);
1830ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon        if (call != null) {
1840ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon            call.playDtmfTone(digit);
185fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal        } else {
1860ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon            Log.e(this, "error playDtmfTone, call not in call list " + callId);
187fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal        }
188fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal    }
189fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal
1906af0c61c32da6cfb400168ae3b0cf9f802abfed4Sailesh Nepal    void stopDtmfTone(String callId) {
1910ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon        android.telecom.Call call = getTelecommCallById(callId);
1920ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon        if (call != null) {
1930ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon            call.stopDtmfTone();
194fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal        } else {
1950ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon            Log.e(this, "error stopDtmfTone, call not in call list " + callId);
196fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal        }
197fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal    }
198fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal
19903e06507ca4fb2463155052622880eff6286e254Evan Charlton    void postDialContinue(String callId, boolean proceed) {
2000ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon        android.telecom.Call call = getTelecommCallById(callId);
2010ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon        if (call != null) {
2020ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon            call.postDialContinue(proceed);
2036e017333e59cb26bc914c6d77798a97d8c789d68Sailesh Nepal        } else {
2040ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon            Log.e(this, "error postDialContinue, call not in call list " + callId);
2056e017333e59cb26bc914c6d77798a97d8c789d68Sailesh Nepal        }
206fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal    }
207fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal
20890b4ee033c8c0e9ceeaef0495ce8e1c205203aa5Nancy Chen    void phoneAccountSelected(String callId, PhoneAccountHandle accountHandle, boolean setDefault) {
2090b26ad3b112ff399aa9627d7e6a252080a46f319Nancy Chen        if (accountHandle == null) {
2100b26ad3b112ff399aa9627d7e6a252080a46f319Nancy Chen            Log.e(this, "error phoneAccountSelected, accountHandle is null");
2110ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon            // TODO: Do we really want to send null accountHandle?
2120ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon        }
2130ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon
2140ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon        android.telecom.Call call = getTelecommCallById(callId);
2150ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon        if (call != null) {
2160ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon            call.phoneAccountSelected(accountHandle, setDefault);
2170ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon        } else {
2180ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon            Log.e(this, "error phoneAccountSelected, call not in call list " + callId);
2190b26ad3b112ff399aa9627d7e6a252080a46f319Nancy Chen        }
2204fbdb77e2abc34e0a5e2479ab3a7e71c1da4619dNancy Chen    }
221ba4e858e872fe446f3a7a17321289d025a40a847Santos Cordon
222ba4e858e872fe446f3a7a17321289d025a40a847Santos Cordon    boolean canAddCall() {
223ba4e858e872fe446f3a7a17321289d025a40a847Santos Cordon        // Default to true if we are not connected to telecom.
2240ea6ed91cc6956cf9497e506a9c63ef8380aaf42Santos Cordon        return mInCallService == null ? true : mInCallService.canAddCall();
225ba4e858e872fe446f3a7a17321289d025a40a847Santos Cordon    }
226fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal}
227