Merge branch 'conferencing' of git.linphone.org:linphone-android-private
|
@ -6,6 +6,7 @@
|
||||||
<classpathentry kind="src" path="submodules/linphone/java/common"/>
|
<classpathentry kind="src" path="submodules/linphone/java/common"/>
|
||||||
<classpathentry kind="src" path="gen"/>
|
<classpathentry kind="src" path="gen"/>
|
||||||
<classpathentry kind="src" path="submodules/linphone/coreapi/help/java"/>
|
<classpathentry kind="src" path="submodules/linphone/coreapi/help/java"/>
|
||||||
|
<classpathentry kind="src" path="test"/>
|
||||||
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
|
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
|
||||||
<classpathentry kind="output" path="bin"/>
|
<classpathentry kind="output" path="bin"/>
|
||||||
</classpath>
|
</classpath>
|
||||||
|
|
|
@ -36,13 +36,39 @@
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
|
<activity android:name="org.linphone.IncomingCallActivity"
|
||||||
|
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
|
||||||
|
android:launchMode="singleInstance">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
|
||||||
|
<activity android:name="org.linphone.UriPickerActivity"
|
||||||
|
android:theme="@android:style/Theme.NoTitleBar"
|
||||||
|
android:screenOrientation="portrait">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
<activity android:name="org.linphone.UriPickerActivity$DialerActivity" android:theme="@android:style/Theme.NoTitleBar">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
|
||||||
<activity android:name="org.linphone.FirstLoginActivity" android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
|
<activity android:name="org.linphone.FirstLoginActivity" android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
<activity android:name="org.linphone.ConferenceActivity"
|
||||||
|
android:theme="@android:style/Theme.NoTitleBar"
|
||||||
|
android:screenOrientation="portrait">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
<activity android:name="org.linphone.IncallActivity"
|
<activity android:name="org.linphone.IncallActivity"
|
||||||
android:launchMode="singleTop"
|
android:launchMode="singleTop"
|
||||||
android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
|
android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
|
||||||
|
@ -100,9 +126,20 @@
|
||||||
<intent-filter><action android:name="android.intent.action.BOOT_COMPLETED"></action></intent-filter>
|
<intent-filter><action android:name="android.intent.action.BOOT_COMPLETED"></action></intent-filter>
|
||||||
</receiver>
|
</receiver>
|
||||||
|
|
||||||
|
<receiver android:name="org.linphone.PhoneStateChangedReceiver">
|
||||||
|
<intent-filter><action android:name="android.intent.action.PHONE_STATE" /></intent-filter>
|
||||||
|
</receiver>
|
||||||
|
|
||||||
|
|
||||||
|
<activity android:name="org.linphone.TestConferenceActivity"
|
||||||
|
android:label="Conf test"
|
||||||
|
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
|
||||||
|
android:enabled="false">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
<activity android:name="org.linphone.core.tutorials.TestVideoActivity"
|
<activity android:name="org.linphone.core.tutorials.TestVideoActivity"
|
||||||
android:label="Video test"
|
android:label="Video test"
|
||||||
android:theme="@android:style/Theme.NoTitleBar"
|
android:theme="@android:style/Theme.NoTitleBar"
|
||||||
|
@ -168,6 +205,7 @@
|
||||||
<uses-permission android:name="android.permission.CAMERA" />
|
<uses-permission android:name="android.permission.CAMERA" />
|
||||||
<uses-permission android:name="android.permission.READ_LOGS" />
|
<uses-permission android:name="android.permission.READ_LOGS" />
|
||||||
|
|
||||||
|
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
|
||||||
|
|
||||||
<supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:anyDensity="true"/>
|
<supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:anyDensity="true"/>
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|
BIN
res/drawable-hdpi/jog_tab_bar_left_end_confirm_green.9.png
Normal file
After Width: | Height: | Size: 5.8 KiB |
BIN
res/drawable-hdpi/jog_tab_bar_left_end_normal.9.png
Normal file
After Width: | Height: | Size: 3.9 KiB |
BIN
res/drawable-hdpi/jog_tab_bar_left_end_pressed.9.png
Normal file
After Width: | Height: | Size: 5.5 KiB |
BIN
res/drawable-hdpi/jog_tab_bar_right_end_confirm_red.9.png
Normal file
After Width: | Height: | Size: 5.9 KiB |
BIN
res/drawable-hdpi/jog_tab_bar_right_end_normal.9.png
Normal file
After Width: | Height: | Size: 3.3 KiB |
BIN
res/drawable-hdpi/jog_tab_bar_right_end_pressed.9.png
Normal file
After Width: | Height: | Size: 5.6 KiB |
BIN
res/drawable-hdpi/jog_tab_left_confirm_green.png
Normal file
After Width: | Height: | Size: 4.9 KiB |
BIN
res/drawable-hdpi/jog_tab_left_normal.png
Normal file
After Width: | Height: | Size: 4.4 KiB |
BIN
res/drawable-hdpi/jog_tab_left_pressed.png
Normal file
After Width: | Height: | Size: 4.3 KiB |
BIN
res/drawable-hdpi/jog_tab_right_confirm_red.png
Normal file
After Width: | Height: | Size: 4.6 KiB |
BIN
res/drawable-hdpi/jog_tab_right_normal.png
Normal file
After Width: | Height: | Size: 4.1 KiB |
BIN
res/drawable-hdpi/jog_tab_right_pressed.png
Normal file
After Width: | Height: | Size: 4.1 KiB |
BIN
res/drawable-hdpi/jog_tab_target_green.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
res/drawable-hdpi/jog_tab_target_red.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
res/drawable-hdpi/unknown_person.png
Normal file
After Width: | Height: | Size: 4.5 KiB |
BIN
res/drawable-ldpi/unknown_person.png
Normal file
After Width: | Height: | Size: 5.4 KiB |
BIN
res/drawable-mdpi/unknown_person.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
12
res/drawable/conf_callee_active_bg.xml
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
<padding android:left="7dp"
|
||||||
|
android:top="7dp"
|
||||||
|
android:right="7dp"
|
||||||
|
android:bottom="7dp" />
|
||||||
|
|
||||||
|
<solid android:color="@color/conf_active_bg_color"/>
|
||||||
|
<corners android:radius="15dp" />
|
||||||
|
</shape>
|
||||||
|
|
7
res/drawable/conf_callee_bg.xml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
<solid android:color="#777777"/>
|
||||||
|
<corners android:radius="15dp"/>
|
||||||
|
</shape>
|
||||||
|
|
12
res/drawable/conf_callee_incoming_bg.xml
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
<padding android:left="7dp"
|
||||||
|
android:top="7dp"
|
||||||
|
android:right="7dp"
|
||||||
|
android:bottom="7dp" />
|
||||||
|
|
||||||
|
<solid android:color="#336600"/>
|
||||||
|
<corners android:radius="15dp" />
|
||||||
|
</shape>
|
||||||
|
|
12
res/drawable/conf_callee_inconf_bg.xml
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
<padding android:left="7dp"
|
||||||
|
android:top="7dp"
|
||||||
|
android:right="7dp"
|
||||||
|
android:bottom="7dp" />
|
||||||
|
|
||||||
|
<solid android:color="#444444"/>
|
||||||
|
<corners android:radius="15dp" />
|
||||||
|
</shape>
|
||||||
|
|
12
res/drawable/conf_callee_pressed_bg.xml
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
<solid android:color="#2E64FE"/>
|
||||||
|
<corners android:radius="15dp"/>
|
||||||
|
<padding android:left="7dp"
|
||||||
|
android:top="7dp"
|
||||||
|
android:right="7dp"
|
||||||
|
android:bottom="7dp" />
|
||||||
|
|
||||||
|
</shape>
|
||||||
|
|
7
res/drawable/conf_callee_selected_bg.xml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
<solid android:color="#ff9200"/>
|
||||||
|
<corners android:radius="15dp"/>
|
||||||
|
</shape>
|
||||||
|
|
7
res/drawable/conf_callee_selector_active.xml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:state_pressed="true" android:drawable="@drawable/conf_callee_pressed_bg" />
|
||||||
|
<item android:drawable="@drawable/conf_callee_active_bg" />
|
||||||
|
</selector>
|
||||||
|
|
7
res/drawable/conf_callee_selector_incoming.xml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:state_pressed="true" android:drawable="@drawable/conf_callee_pressed_bg" />
|
||||||
|
<item android:drawable="@drawable/conf_callee_incoming_bg" />
|
||||||
|
</selector>
|
||||||
|
|
7
res/drawable/conf_callee_selector_inconf.xml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:state_pressed="true" android:drawable="@drawable/conf_callee_pressed_bg" />
|
||||||
|
<item android:drawable="@drawable/conf_callee_inconf_bg" />
|
||||||
|
</selector>
|
||||||
|
|
7
res/drawable/conf_callee_selector_normal.xml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:state_pressed="true" android:drawable="@drawable/conf_callee_pressed_bg" />
|
||||||
|
<item android:drawable="@drawable/conf_callee_bg" />
|
||||||
|
</selector>
|
||||||
|
|
BIN
res/drawable/conf_merge.png
Normal file
After Width: | Height: | Size: 1,011 B |
BIN
res/drawable/conf_merge_all.png
Normal file
After Width: | Height: | Size: 1 KiB |
BIN
res/drawable/conf_pause.png
Normal file
After Width: | Height: | Size: 966 B |
BIN
res/drawable/conf_permute.png
Normal file
After Width: | Height: | Size: 1 KiB |
BIN
res/drawable/conf_remove.png
Normal file
After Width: | Height: | Size: 886 B |
BIN
res/drawable/conf_resume.png
Normal file
After Width: | Height: | Size: 1,007 B |
BIN
res/drawable/conf_status_inconf.png
Normal file
After Width: | Height: | Size: 840 B |
BIN
res/drawable/conf_status_paused.png
Normal file
After Width: | Height: | Size: 978 B |
BIN
res/drawable/conf_terminate.png
Normal file
After Width: | Height: | Size: 655 B |
BIN
res/drawable/conf_transfer.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
res/drawable/conf_unhook.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
res/drawable/conf_video.png
Normal file
After Width: | Height: | Size: 402 B |
28
res/drawable/jog_tab_bar_left_answer.xml
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 2009 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!-- StateListDrawable used for buttons in the in-call onscreen touch UI. -->
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:state_pressed="true"
|
||||||
|
android:drawable="@drawable/jog_tab_bar_left_end_pressed" />
|
||||||
|
|
||||||
|
<item android:state_enabled="true"
|
||||||
|
android:drawable="@drawable/jog_tab_bar_left_end_normal" />
|
||||||
|
|
||||||
|
<item android:state_active="true"
|
||||||
|
android:drawable="@drawable/jog_tab_bar_left_end_confirm_green" />
|
||||||
|
|
||||||
|
</selector>
|
BIN
res/drawable/jog_tab_bar_left_end_confirm_green.9.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
res/drawable/jog_tab_bar_left_end_normal.9.png
Normal file
After Width: | Height: | Size: 2.7 KiB |
BIN
res/drawable/jog_tab_bar_left_end_pressed.9.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
28
res/drawable/jog_tab_bar_right_decline.xml
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 2009 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!-- StateListDrawable used for buttons in the in-call onscreen touch UI. -->
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:state_pressed="true"
|
||||||
|
android:drawable="@drawable/jog_tab_bar_right_end_pressed" />
|
||||||
|
|
||||||
|
<item android:state_enabled="true"
|
||||||
|
android:drawable="@drawable/jog_tab_bar_right_end_normal" />
|
||||||
|
|
||||||
|
<item android:state_active="true"
|
||||||
|
android:drawable="@drawable/jog_tab_bar_right_end_confirm_red" />
|
||||||
|
|
||||||
|
</selector>
|
BIN
res/drawable/jog_tab_bar_right_end_confirm_red.9.png
Normal file
After Width: | Height: | Size: 3.1 KiB |
BIN
res/drawable/jog_tab_bar_right_end_normal.9.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
res/drawable/jog_tab_bar_right_end_pressed.9.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
28
res/drawable/jog_tab_left_answer.xml
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 2009 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!-- StateListDrawable used for buttons in the in-call onscreen touch UI. -->
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:state_pressed="true"
|
||||||
|
android:drawable="@drawable/jog_tab_left_pressed" />
|
||||||
|
|
||||||
|
<item android:state_enabled="true"
|
||||||
|
android:drawable="@drawable/jog_tab_left_normal" />
|
||||||
|
|
||||||
|
<item android:state_active="true"
|
||||||
|
android:drawable="@drawable/jog_tab_left_confirm_green" />
|
||||||
|
|
||||||
|
</selector>
|
BIN
res/drawable/jog_tab_left_confirm_green.png
Executable file
After Width: | Height: | Size: 4.4 KiB |
BIN
res/drawable/jog_tab_left_normal.png
Executable file
After Width: | Height: | Size: 3.6 KiB |
BIN
res/drawable/jog_tab_left_pressed.png
Executable file
After Width: | Height: | Size: 3.8 KiB |
BIN
res/drawable/jog_tab_right_confirm_red.png
Normal file
After Width: | Height: | Size: 4 KiB |
28
res/drawable/jog_tab_right_decline.xml
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 2009 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!-- StateListDrawable used for buttons in the in-call onscreen touch UI. -->
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:state_pressed="true"
|
||||||
|
android:drawable="@drawable/jog_tab_right_pressed" />
|
||||||
|
|
||||||
|
<item android:state_enabled="true"
|
||||||
|
android:drawable="@drawable/jog_tab_right_normal" />
|
||||||
|
|
||||||
|
<item android:state_active="true"
|
||||||
|
android:drawable="@drawable/jog_tab_right_confirm_red" />
|
||||||
|
|
||||||
|
</selector>
|
BIN
res/drawable/jog_tab_right_normal.png
Executable file
After Width: | Height: | Size: 3.3 KiB |
BIN
res/drawable/jog_tab_right_pressed.png
Executable file
After Width: | Height: | Size: 3.5 KiB |
BIN
res/drawable/jog_tab_target_green.png
Normal file
After Width: | Height: | Size: 710 B |
BIN
res/drawable/jog_tab_target_red.png
Normal file
After Width: | Height: | Size: 728 B |
BIN
res/drawable/mini_stopcall_red.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
res/drawable/numpad_big.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
res/drawable/picker_plus.png
Normal file
After Width: | Height: | Size: 426 B |
BIN
res/drawable/picker_transfer.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
res/drawable/plus.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
res/drawable/resume_blue.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
res/drawable/unknown_person.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
|
@ -40,6 +40,7 @@
|
||||||
|
|
||||||
|
|
||||||
<LinearLayout android:id="@+id/CallControlRow" android:layout_height="wrap_content" android:layout_width="fill_parent" android:gravity="bottom">
|
<LinearLayout android:id="@+id/CallControlRow" android:layout_height="wrap_content" android:layout_width="fill_parent" android:gravity="bottom">
|
||||||
|
<ImageButton android:id="@+id/BackToConference" android:src="@drawable/resume_blue" android:layout_height="fill_parent" android:layout_width="fill_parent" android:layout_weight="1" android:background="@drawable/clavier_bg" android:visibility="gone"/>
|
||||||
<org.linphone.ui.CallButton android:id="@+id/Call"
|
<org.linphone.ui.CallButton android:id="@+id/Call"
|
||||||
android:layout_height="fill_parent" android:layout_width="fill_parent" android:layout_weight="1" android:background="@drawable/clavier_bg" android:src="@drawable/startcall_green"/>
|
android:layout_height="fill_parent" android:layout_width="fill_parent" android:layout_weight="1" android:background="@drawable/clavier_bg" android:src="@drawable/startcall_green"/>
|
||||||
<org.linphone.ui.HangCallButton android:id="@+id/Decline" android:layout_height="fill_parent" android:layout_width="fill_parent"
|
<org.linphone.ui.HangCallButton android:id="@+id/Decline" android:layout_height="fill_parent" android:layout_width="fill_parent"
|
||||||
|
@ -51,8 +52,6 @@
|
||||||
<org.linphone.ui.HangCallButton android:id="@+id/HangUp" android:layout_height="fill_parent" android:layout_width="fill_parent" android:layout_weight="1" android:src="@drawable/stopcall_red" android:background="@drawable/clavier_bg"/>
|
<org.linphone.ui.HangCallButton android:id="@+id/HangUp" android:layout_height="fill_parent" android:layout_width="fill_parent" android:layout_weight="1" android:src="@drawable/stopcall_red" android:background="@drawable/clavier_bg"/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<EditText android:id="@+id/status_label" android:layout_width="fill_parent"
|
<EditText android:id="@+id/status_label" android:layout_width="fill_parent"
|
||||||
android:clickable="false" android:focusable="false"
|
android:clickable="false" android:focusable="false"
|
||||||
android:cursorVisible="false" android:textSize="12sp" android:height="15sp"
|
android:cursorVisible="false" android:textSize="12sp" android:height="15sp"
|
||||||
|
|
48
res/layout/conf_callee.xml
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:minHeight="60sp"
|
||||||
|
android:layout_width="fill_parent" android:layout_height="fill_parent" >
|
||||||
|
|
||||||
|
<ImageView android:id="@+id/picture" android:layout_width="wrap_content"
|
||||||
|
android:src="@drawable/unknown_person" android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentLeft="true" android:layout_centerVertical="true"
|
||||||
|
android:paddingRight="3sp"/>
|
||||||
|
|
||||||
|
<LinearLayout android:id="@+id/callee_buttons" android:layout_alignParentRight="true"
|
||||||
|
android:layout_width="wrap_content" android:layout_height="fill_parent"
|
||||||
|
android:layout_centerVertical="true">
|
||||||
|
<ImageButton android:id="@+id/addVideo" android:src="@drawable/conf_video"
|
||||||
|
android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||||
|
<ImageButton android:id="@+id/merge_to_conference" android:src="@drawable/conf_merge"
|
||||||
|
android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||||
|
<ImageButton android:id="@+id/remove_from_conference" android:src="@drawable/conf_remove"
|
||||||
|
android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||||
|
<ImageButton android:id="@+id/unhook_call" android:src="@drawable/conf_unhook"
|
||||||
|
android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||||
|
<ImageButton android:id="@+id/terminate_call" android:src="@drawable/conf_terminate"
|
||||||
|
android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||||
|
<ImageButton android:id="@+id/pause" android:src="@drawable/conf_pause"
|
||||||
|
android:layout_width="wrap_content" android:layout_height="wrap_content"/>
|
||||||
|
<ImageButton android:id="@+id/resume" android:src="@drawable/conf_resume"
|
||||||
|
android:layout_width="wrap_content" android:layout_height="wrap_content"/>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout android:id="@+id/callee_statuses" android:layout_toLeftOf="@id/callee_buttons"
|
||||||
|
android:layout_width="wrap_content" android:layout_height="fill_parent"
|
||||||
|
android:layout_centerVertical="true">
|
||||||
|
<TextView android:id="@+id/status_label" style="@style/callee_status" />
|
||||||
|
<ImageView android:id="@+id/callee_status_paused" style="@style/callee_status" android:src="@drawable/conf_status_paused" />
|
||||||
|
<ImageView android:id="@+id/callee_status_inconf" style="@style/callee_status" android:src="@drawable/conf_status_inconf"/>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
|
<LinearLayout android:id="@+id/callee_block" android:orientation="vertical"
|
||||||
|
android:layout_toRightOf="@id/picture" android:layout_toLeftOf="@id/callee_statuses"
|
||||||
|
android:layout_width="fill_parent" android:layout_height="fill_parent"
|
||||||
|
android:layout_centerVertical="true">
|
||||||
|
<TextView android:id="@+id/name" style="@style/callee_name" />
|
||||||
|
<TextView android:id="@+id/address" style="@style/callee_address" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
|
</RelativeLayout>
|
42
res/layout/conf_callee_older_devices.xml
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="fill_parent" android:layout_height="48px" >
|
||||||
|
|
||||||
|
<ImageView android:id="@+id/picture" android:layout_width="48px"
|
||||||
|
android:src="@drawable/unknown_person" android:layout_height="48px"
|
||||||
|
android:paddingLeft="5px" android:scaleType="centerInside"/>
|
||||||
|
|
||||||
|
|
||||||
|
<LinearLayout android:id="@+id/callee_block" android:orientation="vertical"
|
||||||
|
android:layout_width="wrap_content" android:layout_height="48px">
|
||||||
|
<TextView android:id="@+id/name" style="@style/callee_name" />
|
||||||
|
<TextView android:id="@+id/address" style="@style/callee_address" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<View android:layout_height="fill_parent" android:layout_width="wrap_content" android:layout_weight="1"/>
|
||||||
|
|
||||||
|
|
||||||
|
<ImageButton android:id="@+id/addVideo" android:src="@drawable/conf_video"
|
||||||
|
android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||||
|
<ImageButton android:id="@+id/merge_to_conference"
|
||||||
|
android:src="@drawable/conf_merge" android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
<ImageButton android:id="@+id/remove_from_conference"
|
||||||
|
android:src="@drawable/conf_remove" android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
<ImageButton android:id="@+id/unhook_call" android:src="@drawable/conf_unhook"
|
||||||
|
android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||||
|
<ImageButton android:id="@+id/terminate_call" android:src="@drawable/conf_terminate"
|
||||||
|
android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||||
|
<ImageButton android:id="@+id/pause" android:src="@drawable/conf_pause"
|
||||||
|
android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||||
|
<ImageButton android:id="@+id/resume" android:src="@drawable/conf_resume"
|
||||||
|
android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||||
|
|
||||||
|
<TextView android:id="@+id/status_label" style="@style/callee_status"
|
||||||
|
android:layout_height="fill_parent" />
|
||||||
|
<ImageView android:id="@+id/callee_status_paused" style="@style/callee_status"
|
||||||
|
android:src="@drawable/conf_status_paused" />
|
||||||
|
<ImageView android:id="@+id/callee_status_inconf" style="@style/callee_status"
|
||||||
|
android:src="@drawable/conf_status_inconf" />
|
||||||
|
</LinearLayout>
|
37
res/layout/conf_choices_admin.xml
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="fill_parent" android:layout_height="fill_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<LinearLayout android:id="@+id/conf_add_all_to_conference_button"
|
||||||
|
android:layout_width="fill_parent" android:layout_height="wrap_content">
|
||||||
|
<ImageButton android:src="@drawable/conf_merge_all"
|
||||||
|
android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||||
|
<TextView android:text="@string/conf_choice_merge_all_to_conference" android:layout_gravity="center_vertical"
|
||||||
|
android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout android:id="@+id/conf_enter_button"
|
||||||
|
android:layout_width="fill_parent" android:layout_height="wrap_content">
|
||||||
|
<ImageButton android:src="@drawable/conf_resume"
|
||||||
|
android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||||
|
<TextView android:text="@string/conf_admin_choice_enter" android:layout_gravity="center_vertical"
|
||||||
|
android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout android:id="@+id/conf_leave_button"
|
||||||
|
android:layout_width="fill_parent" android:layout_height="wrap_content">
|
||||||
|
<ImageButton android:src="@drawable/conf_pause"
|
||||||
|
android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||||
|
<TextView android:text="@string/conf_admin_choice_leave" android:layout_gravity="center_vertical"
|
||||||
|
android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout android:id="@+id/conf_terminate_button"
|
||||||
|
android:layout_width="fill_parent" android:layout_height="wrap_content">
|
||||||
|
<ImageButton android:src="@drawable/conf_terminate"
|
||||||
|
android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||||
|
<TextView android:text="@string/conf_admin_choice_terminate" android:layout_gravity="center_vertical"
|
||||||
|
android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
67
res/layout/conf_choices_dialog.xml
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="fill_parent" android:layout_height="fill_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<LinearLayout android:id="@+id/transfer_new"
|
||||||
|
android:layout_width="fill_parent" android:layout_height="wrap_content">
|
||||||
|
<ImageButton android:src="@drawable/conf_transfer"
|
||||||
|
android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||||
|
<TextView android:text="@string/conf_choice_transfer_new" android:layout_gravity="center_vertical"
|
||||||
|
android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout android:id="@+id/transfer_existing"
|
||||||
|
android:layout_width="fill_parent" android:layout_height="wrap_content">
|
||||||
|
<ImageButton android:src="@drawable/conf_transfer"
|
||||||
|
android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||||
|
<TextView android:text="@string/conf_choice_transfer_existing" android:layout_gravity="center_vertical"
|
||||||
|
android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout android:id="@+id/remove_from_conference"
|
||||||
|
android:layout_width="fill_parent" android:layout_height="wrap_content">
|
||||||
|
<ImageButton android:src="@drawable/conf_remove"
|
||||||
|
android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||||
|
<TextView android:text="@string/conf_choice_remove_from_conference" android:layout_gravity="center_vertical"
|
||||||
|
android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
|
<LinearLayout android:id="@+id/merge_to_conference"
|
||||||
|
android:layout_width="fill_parent" android:layout_height="wrap_content">
|
||||||
|
<ImageButton android:src="@drawable/conf_merge"
|
||||||
|
android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||||
|
<TextView android:text="@string/conf_choice_merge_to_conference" android:layout_gravity="center_vertical"
|
||||||
|
android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout android:id="@+id/pause"
|
||||||
|
android:layout_width="fill_parent" android:layout_height="wrap_content">
|
||||||
|
<ImageButton android:src="@drawable/conf_pause"
|
||||||
|
android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||||
|
<TextView android:text="@string/conf_choice_pause" android:layout_gravity="center_vertical"
|
||||||
|
android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout android:id="@+id/resume"
|
||||||
|
android:layout_width="fill_parent" android:layout_height="wrap_content">
|
||||||
|
<ImageButton android:src="@drawable/conf_resume"
|
||||||
|
android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||||
|
<TextView android:text="@string/conf_choice_resume" android:layout_gravity="center_vertical"
|
||||||
|
android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout android:id="@+id/terminate_call"
|
||||||
|
android:layout_width="fill_parent" android:layout_height="wrap_content">
|
||||||
|
<ImageButton android:src="@drawable/conf_terminate"
|
||||||
|
android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||||
|
<TextView android:text="@string/conf_choice_terminate" android:layout_gravity="center_vertical"
|
||||||
|
android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
</ScrollView>
|
84
res/layout/conferencing.xml
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:paddingLeft="8dp"
|
||||||
|
android:paddingRight="8dp">
|
||||||
|
|
||||||
|
|
||||||
|
<LinearLayout android:id="@+id/conf_control_buttons"
|
||||||
|
android:layout_width="fill_parent" android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentTop="true">
|
||||||
|
<Button android:id="@+id/conf_simple_permute" style="@style/conf_icon_text_button"
|
||||||
|
android:drawableTop="@drawable/conf_permute" android:text="@string/conf_simple_permute_bt_txt"/>
|
||||||
|
<Button android:id="@+id/conf_simple_merge" style="@style/conf_icon_text_button"
|
||||||
|
android:drawableTop="@drawable/conf_merge"
|
||||||
|
android:text="@string/conf_simple_merge_bt_txt"/>
|
||||||
|
<Button android:id="@+id/conf_simple_transfer" style="@style/conf_icon_text_button"
|
||||||
|
android:drawableTop="@drawable/conf_transfer"
|
||||||
|
android:text="@string/conf_simple_transfer_bt_txt" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout android:id="@+id/conf_header" android:layout_below="@id/conf_control_buttons"
|
||||||
|
android:orientation="vertical" android:layout_marginBottom="10dip"
|
||||||
|
android:layout_width="fill_parent" android:layout_height="wrap_content"
|
||||||
|
android:layout_alignWithParentIfMissing="true">
|
||||||
|
<TextView android:text="@string/conf_text_you_host_a_conference"
|
||||||
|
android:layout_width="fill_parent" android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"/>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<LinearLayout android:id="@+id/conf_speaker_mic_row"
|
||||||
|
android:layout_alignParentBottom="true"
|
||||||
|
android:layout_width="fill_parent" android:layout_height="wrap_content">
|
||||||
|
<ToggleButton android:id="@+id/toggleMuteMic" style="@style/conf_toggle_button"
|
||||||
|
android:textOn="@string/mutemic_button_txt" android:textOff="@string/mutemic_button_txt" />
|
||||||
|
<ToggleButton android:id="@+id/toggleSpeaker" style="@style/conf_toggle_button"
|
||||||
|
android:textOn="@string/speaker_button_txt" android:textOff="@string/speaker_button_txt" />
|
||||||
|
<ToggleButton android:id="@+id/toggleBluetooth" style="@style/conf_toggle_button"
|
||||||
|
android:textOn="@string/bluetooth_button_txt" android:textOff="@string/bluetooth_button_txt"
|
||||||
|
android:visibility="gone"/>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout android:id="@+id/conf_terminate_row"
|
||||||
|
android:layout_above="@id/conf_speaker_mic_row"
|
||||||
|
android:layout_width="fill_parent" android:layout_height="wrap_content">
|
||||||
|
<Button android:text="@string/AddCallButtonText" android:id="@+id/addCall"
|
||||||
|
style="@style/conf_icon_text_button" android:drawableTop="@drawable/plus" />
|
||||||
|
|
||||||
|
<Button android:id="@+id/incallHang" style="@style/conf_icon_text_button"
|
||||||
|
android:drawableTop="@drawable/stopcall_red" android:text="@string/hangup"/>
|
||||||
|
|
||||||
|
<Button android:id="@+id/incallNumpadShow" style="@style/conf_icon_text_button"
|
||||||
|
android:text="@string/show_send_dtmfs_button" android:drawableTop="@drawable/numpad_big" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<FrameLayout android:id="@+id/incall_picture_box"
|
||||||
|
android:layout_height="wrap_content" android:layout_width="wrap_content"
|
||||||
|
android:layout_centerInParent="true" android:paddingBottom="30sp">
|
||||||
|
<ImageView android:id="@+id/incall_picture" android:visibility="gone"
|
||||||
|
android:layout_height="wrap_content" android:layout_width="wrap_content"
|
||||||
|
android:layout_gravity="center" android:scaleType="fitCenter"
|
||||||
|
android:minWidth="192px" android:minHeight="192px"
|
||||||
|
/>
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
<ListView android:id="@android:id/list"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:drawSelectorOnTop="true"
|
||||||
|
android:dividerHeight="10dip"
|
||||||
|
android:divider="@android:color/transparent"
|
||||||
|
android:layout_below="@id/conf_header"
|
||||||
|
android:layout_above="@id/incall_picture_box"
|
||||||
|
android:layout_alignWithParentIfMissing="true"
|
||||||
|
android:fadeScrollbars="false"
|
||||||
|
/>
|
||||||
|
</RelativeLayout>
|
|
@ -39,13 +39,14 @@
|
||||||
|
|
||||||
<LinearLayout android:layout_height="wrap_content" android:orientation="vertical" android:layout_width="fill_parent">
|
<LinearLayout android:layout_height="wrap_content" android:orientation="vertical" android:layout_width="fill_parent">
|
||||||
<LinearLayout android:id="@+id/CallControlRow" android:layout_height="fill_parent" android:layout_width="fill_parent">
|
<LinearLayout android:id="@+id/CallControlRow" android:layout_height="fill_parent" android:layout_width="fill_parent">
|
||||||
<org.linphone.ui.CallButton android:id="@+id/Call" android:layout_height="fill_parent" android:layout_width="fill_parent" android:layout_weight="0.25" android:src="@drawable/startcall_green" android:background="@drawable/clavier_bg"/>
|
<ImageButton android:id="@+id/BackToConference" android:src="@drawable/resume_blue" android:layout_height="fill_parent" android:layout_width="fill_parent" android:layout_weight="1" android:background="@drawable/clavier_bg" android:visibility="gone"/>
|
||||||
<org.linphone.ui.HangCallButton android:id="@+id/Decline" android:layout_height="fill_parent" android:layout_width="fill_parent" android:layout_weight="0.25" android:src="@drawable/stopcall_red" android:background="@drawable/clavier_bg"/>
|
<org.linphone.ui.CallButton android:id="@+id/Call" android:layout_height="fill_parent" android:layout_width="fill_parent" android:layout_weight="1" android:src="@drawable/startcall_green" android:background="@drawable/clavier_bg"/>
|
||||||
|
<org.linphone.ui.HangCallButton android:id="@+id/Decline" android:layout_height="fill_parent" android:layout_width="fill_parent" android:layout_weight="1" android:src="@drawable/stopcall_red" android:background="@drawable/clavier_bg"/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout android:id="@+id/IncallControlRow" android:layout_height="fill_parent" android:layout_width="fill_parent" android:visibility="gone">
|
<LinearLayout android:id="@+id/IncallControlRow" android:layout_height="fill_parent" android:layout_width="fill_parent" android:visibility="gone">
|
||||||
<org.linphone.ui.AddVideoButton android:id="@+id/AddVideo" android:src="@drawable/startvideo_green" android:layout_height="fill_parent" android:layout_width="fill_parent" android:layout_weight="0.25" android:background="@drawable/clavier_bg"/>
|
<org.linphone.ui.AddVideoButton android:id="@+id/AddVideo" android:src="@drawable/startvideo_green" android:layout_height="fill_parent" android:layout_width="fill_parent" android:layout_weight="1" android:background="@drawable/clavier_bg"/>
|
||||||
<org.linphone.ui.HangCallButton android:id="@+id/HangUp" android:src="@drawable/stopcall_red" android:layout_height="fill_parent" android:layout_width="fill_parent" android:layout_weight="0.25" android:background="@drawable/clavier_bg"/>
|
<org.linphone.ui.HangCallButton android:id="@+id/HangUp" android:src="@drawable/stopcall_red" android:layout_height="fill_parent" android:layout_width="fill_parent" android:layout_weight="1" android:background="@drawable/clavier_bg"/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<EditText android:id="@+id/status_label" android:clickable="false" android:focusable="false" android:cursorVisible="false" android:textSize="12sp" android:height="15sp" android:layout_height="wrap_content" android:layout_width="fill_parent" android:background="@android:color/transparent" android:textColor="@android:color/white" />
|
<EditText android:id="@+id/status_label" android:clickable="false" android:focusable="false" android:cursorVisible="false" android:textSize="12sp" android:height="15sp" android:layout_height="wrap_content" android:layout_width="fill_parent" android:background="@android:color/transparent" android:textColor="@android:color/white" />
|
||||||
|
|
|
@ -24,9 +24,7 @@
|
||||||
</TableRow>
|
</TableRow>
|
||||||
|
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<org.linphone.ui.AddVideoButton android:id="@+id/AddVideo" android:src="@drawable/startvideo_green"
|
|
||||||
android:layout_height="wrap_content" android:layout_width="wrap_content" android:height="10px"
|
|
||||||
android:layout_column="1" />
|
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableLayout>
|
</TableLayout>
|
||||||
|
|
||||||
|
@ -35,7 +33,20 @@
|
||||||
|
|
||||||
<View android:layout_weight="1" android:layout_width="0px" android:layout_height="0px" android:visibility="invisible"/>
|
<View android:layout_weight="1" android:layout_width="0px" android:layout_height="0px" android:visibility="invisible"/>
|
||||||
|
|
||||||
|
<LinearLayout android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content">
|
||||||
|
<Button android:text="+ Add call" android:id="@+id/toggleButton4" android:width="0px" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1"/>
|
||||||
|
<Button android:text="Video" android:id="@+id/toggleButton4" android:width="0px" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1"/>
|
||||||
|
<Button android:text="Chat" android:id="@+id/toggleButton4" android:width="0px" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1"/>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content">
|
||||||
|
<ToggleButton android:text="Mute" android:id="@+id/toggleButton1" android:width="0px" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1"></ToggleButton>
|
||||||
|
<ToggleButton android:text="Speaker" android:id="@+id/toggleButton2" android:width="0px" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1"></ToggleButton>
|
||||||
|
<ToggleButton android:text="Bluetooth" android:id="@+id/toggleButton3" android:width="0px" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1"></ToggleButton>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<!-- <org.linphone.ui.AddVideoButton android:id="@+id/AddVideo" android:src="@drawable/startvideo_green"-->
|
||||||
|
<!-- android:layout_height="wrap_content" android:layout_width="fill_parent" android:width="0px" android:layout_weight="1"/>-->
|
||||||
<LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content">
|
<LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content">
|
||||||
<org.linphone.ui.HangCallButton android:id="@+id/incallHang" android:layout_width="wrap_content" android:layout_height="wrap_content"
|
<org.linphone.ui.HangCallButton android:id="@+id/incallHang" android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||||
android:src="@drawable/stopcall_red" android:background="@drawable/clavier_bg" android:layout_weight="10" />
|
android:src="@drawable/stopcall_red" android:background="@drawable/clavier_bg" android:layout_weight="10" />
|
||||||
|
|
55
res/layout/incoming.xml
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout android:orientation="vertical"
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="fill_parent" android:layout_height="fill_parent">
|
||||||
|
|
||||||
|
|
||||||
|
<TextView android:id="@+id/incoming_text"
|
||||||
|
android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:layout_marginTop="25sp" android:layout_alignParentTop="true"
|
||||||
|
android:text="Incoming call" android:textAppearance="?android:attr/textAppearanceLarge">
|
||||||
|
</TextView>
|
||||||
|
|
||||||
|
<LinearLayout android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content" android:orientation="vertical"
|
||||||
|
android:layout_below="@id/incoming_text"
|
||||||
|
android:layout_centerHorizontal="true" android:paddingTop="30dip">
|
||||||
|
<ImageView android:id="@+id/incoming_picture"
|
||||||
|
android:layout_height="wrap_content" android:layout_width="wrap_content"
|
||||||
|
android:layout_gravity="center" android:scaleType="fitCenter"
|
||||||
|
android:minWidth="192px" android:minHeight="192px"
|
||||||
|
android:paddingBottom="10sp"/>
|
||||||
|
<TextView android:id="@+id/incoming_caller_name"
|
||||||
|
android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||||
|
android:text="Caller name" android:textAppearance="?android:attr/textAppearanceLarge"
|
||||||
|
android:layout_gravity="center_horizontal">
|
||||||
|
</TextView>
|
||||||
|
<TextView android:id="@+id/incoming_caller_number"
|
||||||
|
android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8sp"
|
||||||
|
android:text="Caller phone"
|
||||||
|
android:textAppearance="?android:attr/textAppearance"
|
||||||
|
android:layout_gravity="center_horizontal">
|
||||||
|
</TextView>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
|
<org.linphone.ui.SlidingTab
|
||||||
|
android:id="@+id/sliding_widget"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentBottom="true"
|
||||||
|
android:layout_marginBottom="80dip"
|
||||||
|
/>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- <org.linphone.ui.CallButton android:src="@drawable/startvideo_green" android:layout_width="wrap_content"-->
|
||||||
|
<!-- android:layout_height="wrap_content" android:id="@+id/AnswerWithVideo"-->
|
||||||
|
<!-- android:text="answer with video"-->
|
||||||
|
<!-- android:textAppearance="?android:attr/textAppearanceLarge"-->
|
||||||
|
<!-- android:layout_alignParentLeft="true" android:layout_marginBottom="30sp"-->
|
||||||
|
<!-- android:layout_above="@id/Answer"/>-->
|
||||||
|
|
||||||
|
|
||||||
|
</RelativeLayout>
|
31
res/layout/simplified_dialer.xml
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:linphone="http://schemas.android.com/apk/res/org.linphone"
|
||||||
|
android:orientation="vertical" android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent">
|
||||||
|
|
||||||
|
<LinearLayout android:layout_height="wrap_content"
|
||||||
|
android:layout_width="fill_parent" android:id="@+id/Addresslayout">
|
||||||
|
<org.linphone.ui.AddressText android:id="@+id/SipUri"
|
||||||
|
android:background="@drawable/clavier_bg_grey" android:hint="sip:"
|
||||||
|
android:layout_width="fill_parent" android:lines="1"
|
||||||
|
android:layout_weight="0.2" android:layout_height="fill_parent"
|
||||||
|
android:padding="10px" android:maxLines="1" android:editable="@bool/allow_edit_in_dialer" />
|
||||||
|
<org.linphone.ui.EraseButton
|
||||||
|
android:layout_height="fill_parent" android:background="@drawable/clavier_bg"
|
||||||
|
android:id="@+id/Erase" android:layout_width="fill_parent"
|
||||||
|
android:layout_weight="0.8" android:textSize="20sp"
|
||||||
|
android:textStyle="bold" android:text="<" android:layout_gravity="top"
|
||||||
|
android:textColor="@android:color/black" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<org.linphone.ui.Numpad android:id="@+id/Dialer"
|
||||||
|
linphone:play_dtmf="dont"
|
||||||
|
android:layout_width="fill_parent" android:layout_height="fill_parent"
|
||||||
|
android:layout_weight="4" />
|
||||||
|
|
||||||
|
<Button android:id="@+id/AddCallButton" android:text="@string/AddCallButtonText"
|
||||||
|
android:gravity="bottom|center_horizontal" android:layout_height="wrap_content"
|
||||||
|
android:layout_width="fill_parent" android:background="@drawable/clavier_bg" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
19
res/layout/uri_picker.xml
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/main_frame" android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent">
|
||||||
|
<TabHost android:id="@android:id/tabhost" android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent">
|
||||||
|
<LinearLayout android:orientation="vertical"
|
||||||
|
android:layout_width="fill_parent" android:layout_height="fill_parent">
|
||||||
|
<!--
|
||||||
|
android:padding="5dp"
|
||||||
|
-->
|
||||||
|
<TabWidget android:id="@android:id/tabs"
|
||||||
|
android:layout_width="fill_parent" android:layout_height="wrap_content" />
|
||||||
|
<FrameLayout android:id="@android:id/tabcontent"
|
||||||
|
android:layout_width="fill_parent" android:layout_height="fill_parent" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</TabHost>
|
||||||
|
</FrameLayout>
|
38
res/values/callee_style.xml
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<style name="callee_name" parent="@android:style/TextAppearance.Large">
|
||||||
|
<item name="android:layout_width">wrap_content</item>
|
||||||
|
<item name="android:layout_height">fill_parent</item>
|
||||||
|
<item name="android:layout_weight">1</item>
|
||||||
|
<item name="android:gravity">fill_vertical</item>
|
||||||
|
<item name="android:singleLine">true</item>
|
||||||
|
<item name="android:ellipsize">marquee</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="callee_address" parent="@android:style/TextAppearance.Medium">
|
||||||
|
<item name="android:layout_width">wrap_content</item>
|
||||||
|
<item name="android:layout_height">fill_parent</item>
|
||||||
|
<item name="android:layout_weight">1</item>
|
||||||
|
<item name="android:gravity">fill_vertical</item>
|
||||||
|
<item name="android:singleLine">true</item>
|
||||||
|
<item name="android:ellipsize">marquee</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="callee_status">
|
||||||
|
<item name="android:layout_width">wrap_content</item>
|
||||||
|
<item name="android:layout_height">wrap_content</item>
|
||||||
|
<item name="android:gravity">center_vertical</item>
|
||||||
|
<item name="android:layout_gravity">center_vertical</item>
|
||||||
|
<item name="android:scaleType">center</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="conf_toggle_button" parent="@android:style/Widget.Button.Toggle">
|
||||||
|
<item name="android:width">0px</item>
|
||||||
|
<item name="android:layout_width">fill_parent</item>
|
||||||
|
<item name="android:layout_height">wrap_content</item>
|
||||||
|
<item name="android:layout_weight">1</item>
|
||||||
|
<!-- <item name="android:layout_width">wrap_content</item>-->
|
||||||
|
<!-- <item name="android:layout_height">wrap_content</item>-->
|
||||||
|
</style>
|
||||||
|
|
||||||
|
</resources>
|
12
res/values/conf_style.xml
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<style name="conf_icon_text_button" parent="@android:style/Widget.Button">
|
||||||
|
<item name="android:layout_height">wrap_content</item>
|
||||||
|
<item name="android:layout_width">0dip</item>
|
||||||
|
<item name="android:layout_weight">1</item>
|
||||||
|
<item name="android:gravity">bottom|center_horizontal</item>
|
||||||
|
<item name="android:paddingLeft">15sp</item>
|
||||||
|
<item name="android:paddingRight">15sp</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
</resources>
|
|
@ -3,23 +3,9 @@
|
||||||
|
|
||||||
|
|
||||||
<string name="app_name">Linphone</string>
|
<string name="app_name">Linphone</string>
|
||||||
<string name="default_domain">test.linphone.org</string>
|
|
||||||
|
|
||||||
<bool name="use_android_contact_picker">true</bool>
|
|
||||||
|
|
||||||
<bool name="useFirstLoginActivity">false</bool>
|
|
||||||
<bool name="useMenuSettings">true</bool>
|
|
||||||
<bool name="useMenuAbout">true</bool>
|
|
||||||
<bool name="use_incall_activity">false</bool>
|
|
||||||
<bool name="use_video_activity">true</bool>
|
|
||||||
<bool name="show_full_remote_address_on_incoming_call">true</bool>
|
|
||||||
|
|
||||||
<string name="notification_title">Linphone</string>
|
<string name="notification_title">Linphone</string>
|
||||||
<bool name="allow_edit_in_dialer">true</bool>
|
|
||||||
<string name="notification_registered">Registered to %s </string>
|
<string name="notification_registered">Registered to %s </string>
|
||||||
<string name="notification_register_failure">Fails to register to %s</string>
|
<string name="notification_register_failure">Fails to register to %s</string>
|
||||||
|
|
||||||
<string name="about_text">Linphone %s SIP (rfc 3261) compatible phone under GNU Public License V2\n http://www.linphone.org\n\nInstructions\nhttp://www.linphone.org/m/help\n\n© 2011 Belledonne Communications</string>
|
<string name="about_text">Linphone %s SIP (rfc 3261) compatible phone under GNU Public License V2\n http://www.linphone.org\n\nInstructions\nhttp://www.linphone.org/m/help\n\n© 2011 Belledonne Communications</string>
|
||||||
<string name="about_bugreport_email">linphone-android@belledonne-communications.com</string>
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -9,4 +9,13 @@
|
||||||
<item name="android:textSize">20sp</item>
|
<item name="android:textSize">20sp</item>
|
||||||
<item name="android:layout_weight">1</item>
|
<item name="android:layout_weight">1</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<declare-styleable name="Numpad">
|
||||||
|
<attr name="play_dtmf">
|
||||||
|
<enum name="dont" value="0" />
|
||||||
|
<enum name="play" value="1" />
|
||||||
|
</attr>
|
||||||
|
</declare-styleable>
|
||||||
</resources>
|
</resources>
|
25
res/values/non_localizable_custom.xml
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
|
||||||
|
|
||||||
|
<string name="default_domain">test.linphone.org</string>
|
||||||
|
|
||||||
|
<bool name="use_android_contact_picker">true</bool>
|
||||||
|
|
||||||
|
<bool name="useFirstLoginActivity">false</bool>
|
||||||
|
<bool name="useMenuSettings">true</bool>
|
||||||
|
<bool name="useMenuAbout">true</bool>
|
||||||
|
<bool name="use_incall_activity">false</bool>
|
||||||
|
<bool name="use_conference_activity">true</bool>
|
||||||
|
<bool name="use_video_activity">true</bool>
|
||||||
|
<bool name="autostart_video_activity">false</bool>
|
||||||
|
<bool name="show_full_remote_address_on_incoming_call">true</bool>
|
||||||
|
|
||||||
|
<bool name="allow_transfers">true</bool>
|
||||||
|
|
||||||
|
<bool name="allow_edit_in_dialer">true</bool>
|
||||||
|
<color name="conf_active_bg_color">#191970</color>
|
||||||
|
|
||||||
|
<string name="about_bugreport_email">linphone-android@belledonne-communications.com</string>
|
||||||
|
</resources>
|
||||||
|
|
31
res/values/slidingtab_style.xml
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<style name="TextAppearance.SlidingTabNormal"
|
||||||
|
parent="@android:attr/textAppearanceMedium">
|
||||||
|
<item name="android:textColor">?android:attr/textColorTertiary</item>
|
||||||
|
<item name="android:textSize">28sp</item>
|
||||||
|
<item name="android:shadowColor">@android:color/black</item>
|
||||||
|
<item name="android:shadowDx">0.0</item>
|
||||||
|
<item name="android:shadowDy">1.0</item>
|
||||||
|
<item name="android:shadowRadius">5.0</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="TextAppearance.SlidingTabActive"
|
||||||
|
parent="@android:attr/textAppearanceMedium">
|
||||||
|
<item name="android:textColor">@android:color/black</item>
|
||||||
|
<item name="android:textSize">28sp</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<attr name="orientation">
|
||||||
|
<!-- Defines an horizontal widget. -->
|
||||||
|
<enum name="horizontal" value="0" />
|
||||||
|
<!-- Defines a vertical widget. -->
|
||||||
|
<enum name="vertical" value="1" />
|
||||||
|
</attr>
|
||||||
|
|
||||||
|
<declare-styleable name="SlidingTab">
|
||||||
|
<!-- Use "horizontal" for a row, "vertical" for a column. The default is horizontal. -->
|
||||||
|
<attr name="orientation" />
|
||||||
|
</declare-styleable>
|
||||||
|
|
||||||
|
</resources>
|
|
@ -1,6 +1,60 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
|
|
||||||
|
<string name="waiting_for_startup">Starting up...</string>
|
||||||
|
<string name="couldnt_accept_call">An error occurred while accepting call</string>
|
||||||
|
|
||||||
|
<string name="uri_picking_canceled">Canceled</string>
|
||||||
|
<string name="error_adding_new_call">Error adding new call</string>
|
||||||
|
<string name="transfer_started">Transfer initiated</string>
|
||||||
|
<string name="transfer_dialog_title">Transfer call to</string>
|
||||||
|
|
||||||
|
<string name="skipable_error_service_not_ready">Warning: service is not ready</string>
|
||||||
|
|
||||||
|
<string name="close_button_text">Close</string>
|
||||||
|
|
||||||
|
<string name="status_conf_call">conf</string>
|
||||||
|
<string name="status_active_call">active</string>
|
||||||
|
<string name="state_paused">paused</string>
|
||||||
|
<string name="state_paused_by_remote">paused</string>
|
||||||
|
<string name="state_streams_running"></string>
|
||||||
|
<string name="state_incoming_received">incoming</string>
|
||||||
|
<string name="state_outgoing_ringing">ringing</string>
|
||||||
|
|
||||||
|
<string name="mutemic_button_txt">Mute</string>
|
||||||
|
<string name="speaker_button_txt">Speaker</string>
|
||||||
|
<string name="bluetooth_button_txt">Bluetooth</string>
|
||||||
|
|
||||||
|
<string name="CancelButtonText">Cancel</string>
|
||||||
|
<string name="AddCallButtonText">Add call</string>
|
||||||
|
<string name="TransferCallButtonText">Transfer call</string>
|
||||||
|
|
||||||
|
<string name="conf_admin_choice_enter">Enter conference</string>
|
||||||
|
<string name="conf_admin_choice_leave">Momentarily leave conference</string>
|
||||||
|
<string name="conf_admin_choice_terminate">Terminate conference</string>
|
||||||
|
|
||||||
|
<string name="conf_choice_transfer_existing">Transfer to existing call</string>
|
||||||
|
<string name="conf_choice_transfer_new">Transfer to new call</string>
|
||||||
|
<string name="conf_choice_resume">Resume</string>
|
||||||
|
<string name="conf_choice_pause">Pause</string>
|
||||||
|
<string name="conf_choice_merge_to_conference">Add to conference</string>
|
||||||
|
<string name="conf_choice_merge_all_to_conference">Add all calls to conference</string>
|
||||||
|
<string name="conf_choice_remove_from_conference">Remove from the conference</string>
|
||||||
|
<string name="conf_choice_terminate">Terminate</string>
|
||||||
|
|
||||||
|
<string name="hangup">Hang up</string>
|
||||||
|
<string name="conf_simple_merge_bt_txt">Merge</string>
|
||||||
|
<string name="conf_simple_transfer_bt_txt">Transfer</string>
|
||||||
|
<string name="conf_simple_permute_bt_txt">Permute</string>
|
||||||
|
<string name="conf_simple_no_current_call">No active call</string>
|
||||||
|
<string name="show_send_dtmfs_button">DTMFs</string>
|
||||||
|
|
||||||
|
<string name="conf_text_you_host_a_conference">You host a conference</string>
|
||||||
|
<string name="in_conf">You are part of it</string>
|
||||||
|
<string name="in_conf_leave">Go out</string>
|
||||||
|
<string name="out_conf">You are out of it</string>
|
||||||
|
<string name="out_conf_enter">Go in</string>
|
||||||
|
|
||||||
<string name="pref_audio_hacks_title">Audio hacks</string>
|
<string name="pref_audio_hacks_title">Audio hacks</string>
|
||||||
<string name="pref_audio_use_specific_mode_title">Use specific mode hack</string>
|
<string name="pref_audio_use_specific_mode_title">Use specific mode hack</string>
|
||||||
<string name="pref_audio_use_specific_mode_summary">0=MODE_NORMAL (default), 2=MODE_IN_CALL</string>
|
<string name="pref_audio_use_specific_mode_summary">0=MODE_NORMAL (default), 2=MODE_IN_CALL</string>
|
||||||
|
@ -54,9 +108,9 @@
|
||||||
<string name="menu_videocall_terminate_call_title">Terminate call</string>
|
<string name="menu_videocall_terminate_call_title">Terminate call</string>
|
||||||
<string name="pref_video_settings_title">Video settings</string>
|
<string name="pref_video_settings_title">Video settings</string>
|
||||||
<string name="pref_video_automatically_share_my_video_title">Share my camera</string>
|
<string name="pref_video_automatically_share_my_video_title">Share my camera</string>
|
||||||
<string name="pref_video_automatically_share_my_video">Automatically send my camera on incoming calls</string>
|
<string name="pref_video_automatically_share_my_video">Send my camera on video capable calls</string>
|
||||||
<string name="pref_video_initiate_call_with_video_title">Initiate video calls</string>
|
<string name="pref_video_initiate_call_with_video_title">Initiate video capable calls</string>
|
||||||
<string name="pref_video_initiate_call_with_video">Always send my camera on outgoing calls</string>
|
<string name="pref_video_initiate_call_with_video">Disable to remove negotiation of video codecs for outgoing calls</string>
|
||||||
<string name="pref_video_enable_title">Enable Video</string>
|
<string name="pref_video_enable_title">Enable Video</string>
|
||||||
<string name="pref_escape_plus">Replace + by 00</string>
|
<string name="pref_escape_plus">Replace + by 00</string>
|
||||||
<string name="pref_ilbc_summary">iLBC might be unavailable depending on ARM processor and Android OS version.</string>
|
<string name="pref_ilbc_summary">iLBC might be unavailable depending on ARM processor and Android OS version.</string>
|
||||||
|
|
|
@ -4,16 +4,16 @@
|
||||||
|
|
||||||
<PreferenceCategory android:title="@string/pref_sipaccount">
|
<PreferenceCategory android:title="@string/pref_sipaccount">
|
||||||
<EditTextPreference android:title="@string/pref_username"
|
<EditTextPreference android:title="@string/pref_username"
|
||||||
android:key="@string/pref_username_key"></EditTextPreference>
|
android:key="@string/pref_username_key" android:inputType="text|textEmailAddress"></EditTextPreference>
|
||||||
|
|
||||||
<EditTextPreference android:title="@string/pref_passwd"
|
<EditTextPreference android:title="@string/pref_passwd"
|
||||||
android:key="@string/pref_passwd_key" android:password="true"></EditTextPreference>
|
android:key="@string/pref_passwd_key" android:password="true"></EditTextPreference>
|
||||||
|
|
||||||
<EditTextPreference android:title="@string/pref_domain"
|
<EditTextPreference android:title="@string/pref_domain"
|
||||||
android:key="@string/pref_domain_key"></EditTextPreference>
|
android:key="@string/pref_domain_key" android:inputType="text|textEmailAddress"></EditTextPreference>
|
||||||
|
|
||||||
<EditTextPreference android:title="@string/pref_proxy"
|
<EditTextPreference android:title="@string/pref_proxy"
|
||||||
android:key="@string/pref_proxy_key"></EditTextPreference>
|
android:key="@string/pref_proxy_key" android:inputType="text|textEmailAddress"></EditTextPreference>
|
||||||
|
|
||||||
<CheckBoxPreference android:enabled="true"
|
<CheckBoxPreference android:enabled="true"
|
||||||
android:selectable="true" android:key="@string/pref_enable_outbound_proxy_key"
|
android:selectable="true" android:key="@string/pref_enable_outbound_proxy_key"
|
||||||
|
|
|
@ -73,26 +73,32 @@ public class AboutActivity extends Activity implements OnClickListener {
|
||||||
thread.start();
|
thread.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private File writeLogs(String logs, File directory) {
|
||||||
|
File tempFile = null;
|
||||||
|
try {
|
||||||
|
tempFile = File.createTempFile("bugreport", ".txt", directory);
|
||||||
|
tempFile.deleteOnExit();
|
||||||
|
FileWriter writer = new FileWriter(tempFile);
|
||||||
|
writer.append(logs);
|
||||||
|
return tempFile;
|
||||||
|
} catch (IOException e) {
|
||||||
|
Toast.makeText(this, getString(R.string.about_error_generating_bugreport_attachement), Toast.LENGTH_LONG).show();
|
||||||
|
Log.e(e, "couldn't write to temporary file");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void onLogsRead(String logs) {
|
private void onLogsRead(String logs) {
|
||||||
File tempFile;
|
|
||||||
if (logs == null) {
|
if (logs == null) {
|
||||||
Toast.makeText(this, getString(R.string.about_logs_not_found), Toast.LENGTH_SHORT).show();
|
Toast.makeText(this, getString(R.string.about_logs_not_found), Toast.LENGTH_SHORT).show();
|
||||||
} else {
|
} else {
|
||||||
|
File tempFile = writeLogs(logs, null);
|
||||||
try {
|
if (tempFile == null) {
|
||||||
tempFile = File.createTempFile("bugreport", ".txt");
|
// If writing to temporary file to default location failed
|
||||||
tempFile.deleteOnExit();
|
// Write one to our storage place
|
||||||
FileWriter writer = new FileWriter(tempFile);
|
tempFile = writeLogs(logs, getFilesDir());
|
||||||
writer.append(logs);
|
|
||||||
} catch (IOException e) {
|
|
||||||
Toast.makeText(this, getString(R.string.about_error_generating_bugreport_attachement), Toast.LENGTH_LONG).show();
|
|
||||||
Log.e(e, "couldn't write to temporary file");
|
|
||||||
return;
|
|
||||||
} finally {
|
|
||||||
thread = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Intent intent = new Intent(Intent.ACTION_SEND);
|
Intent intent = new Intent(Intent.ACTION_SEND);
|
||||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
intent.setType("plain/text");
|
intent.setType("plain/text");
|
||||||
|
@ -114,6 +120,7 @@ public class AboutActivity extends Activity implements OnClickListener {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
onLogsRead(logs);
|
onLogsRead(logs);
|
||||||
|
thread=null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
super.run();
|
super.run();
|
||||||
|
|
|
@ -21,6 +21,8 @@ package org.linphone;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.linphone.mediastream.Version;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
|
@ -155,7 +157,7 @@ public abstract class AbstractContactPickerActivity extends Activity implements
|
||||||
finish();
|
finish();
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
LinphoneActivity.setAddressAndGoToDialer(number, name, photo);
|
((ContactPicked) getParent()).setAddressAndGoToDialer(number, name, photo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
863
src/org/linphone/ConferenceActivity.java
Normal file
|
@ -0,0 +1,863 @@
|
||||||
|
/*
|
||||||
|
ConferenceActivity.java
|
||||||
|
Copyright (C) 2011 Belledonne Communications, Grenoble, France
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
package org.linphone;
|
||||||
|
|
||||||
|
import static android.view.View.GONE;
|
||||||
|
import static android.view.View.VISIBLE;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.linphone.LinphoneManagerWaitHelper.LinphoneManagerReadyListener;
|
||||||
|
import org.linphone.LinphoneSimpleListener.LinphoneOnAudioChangedListener;
|
||||||
|
import org.linphone.LinphoneSimpleListener.LinphoneOnCallStateChangedListener;
|
||||||
|
import org.linphone.LinphoneSimpleListener.LinphoneOnVideoCallReadyListener;
|
||||||
|
import org.linphone.core.LinphoneAddress;
|
||||||
|
import org.linphone.core.LinphoneCall;
|
||||||
|
import org.linphone.core.LinphoneCore;
|
||||||
|
import org.linphone.core.LinphoneCoreException;
|
||||||
|
import org.linphone.core.Log;
|
||||||
|
import org.linphone.core.LinphoneCall.State;
|
||||||
|
import org.linphone.mediastream.Version;
|
||||||
|
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.app.Dialog;
|
||||||
|
import android.app.ListActivity;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.res.Resources;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.view.KeyEvent;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.view.WindowManager;
|
||||||
|
import android.view.View.OnClickListener;
|
||||||
|
import android.widget.ArrayAdapter;
|
||||||
|
import android.widget.BaseAdapter;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.ListAdapter;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
import android.widget.ToggleButton;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Guillaume Beraudo
|
||||||
|
*/
|
||||||
|
public class ConferenceActivity extends ListActivity implements
|
||||||
|
LinphoneManagerReadyListener,
|
||||||
|
LinphoneOnAudioChangedListener,
|
||||||
|
LinphoneOnVideoCallReadyListener,
|
||||||
|
LinphoneOnCallStateChangedListener,
|
||||||
|
Comparator<LinphoneCall>,
|
||||||
|
OnClickListener {
|
||||||
|
|
||||||
|
private View confHeaderView;
|
||||||
|
static boolean active;
|
||||||
|
|
||||||
|
private boolean unMuteOnReturnFromUriPicker;
|
||||||
|
|
||||||
|
// Start Override to test block
|
||||||
|
protected LinphoneCore lc() {
|
||||||
|
return LinphoneManager.getLc();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected List<LinphoneCall> getInitialCalls() {
|
||||||
|
return LinphoneUtils.getLinphoneCalls(lc());
|
||||||
|
}
|
||||||
|
|
||||||
|
// End override to test block
|
||||||
|
|
||||||
|
private static final int numpad_dialog_id = 1;
|
||||||
|
public static final String ADD_CALL = "add_call";
|
||||||
|
public static final String TRANSFER_TO_NEW_CALL = "transfer_to_new_call";
|
||||||
|
public static final String CALL_NATIVE_ID = "call_native_id";
|
||||||
|
private static final int ID_ADD_CALL = 1;
|
||||||
|
private static final int ID_TRANSFER_CALL = 2;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private void workaroundStatusBarBug() {
|
||||||
|
// call from onCreate to get a clean display on full screen no icons
|
||||||
|
// otherwise the upper side of the activity may be corrupted
|
||||||
|
getWindow().setFlags(
|
||||||
|
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
|
||||||
|
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void pauseCurrentCallOrLeaveConference() {
|
||||||
|
LinphoneCall call = lc().getCurrentCall();
|
||||||
|
if (call != null) lc().pauseCall(call);
|
||||||
|
lc().leaveConference();
|
||||||
|
}
|
||||||
|
|
||||||
|
private LinphoneManagerWaitHelper waitHelper;
|
||||||
|
private ToggleButton mMuteMicButton;
|
||||||
|
private ToggleButton mSpeakerButton;
|
||||||
|
private boolean useVideoActivity;
|
||||||
|
private int multipleCallsLimit;
|
||||||
|
private boolean allowTransfers;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
setContentView(R.layout.conferencing);
|
||||||
|
|
||||||
|
allowTransfers = getResources().getBoolean(R.bool.allow_transfers);
|
||||||
|
|
||||||
|
confHeaderView = findViewById(R.id.conf_header);
|
||||||
|
confHeaderView.setOnClickListener(this);
|
||||||
|
|
||||||
|
findViewById(R.id.addCall).setOnClickListener(this);
|
||||||
|
|
||||||
|
findViewById(R.id.incallNumpadShow).setOnClickListener(this);
|
||||||
|
findViewById(R.id.conf_simple_merge).setOnClickListener(this);
|
||||||
|
View transferView = findViewById(R.id.conf_simple_transfer);
|
||||||
|
transferView.setOnClickListener(this);
|
||||||
|
if (!allowTransfers) {
|
||||||
|
transferView.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
findViewById(R.id.conf_simple_permute).setOnClickListener(this);
|
||||||
|
|
||||||
|
mMuteMicButton = (ToggleButton) findViewById(R.id.toggleMuteMic);
|
||||||
|
mMuteMicButton.setOnClickListener(this);
|
||||||
|
mSpeakerButton = (ToggleButton) findViewById(R.id.toggleSpeaker);
|
||||||
|
mSpeakerButton.setOnClickListener(this);
|
||||||
|
|
||||||
|
waitHelper = new LinphoneManagerWaitHelper(this, this);
|
||||||
|
waitHelper.doManagerDependentOnCreate();
|
||||||
|
useVideoActivity = getResources().getBoolean(R.bool.use_video_activity);
|
||||||
|
|
||||||
|
// workaroundStatusBarBug();
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreateWhenManagerReady() {
|
||||||
|
List<LinphoneCall> calls = getInitialCalls();
|
||||||
|
setListAdapter(new CalleeListAdapter(calls));
|
||||||
|
|
||||||
|
findViewById(R.id.incallHang).setOnClickListener(this);
|
||||||
|
multipleCallsLimit = lc().getMaxCalls();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void onResumeWhenManagerReady() {
|
||||||
|
registerLinphoneListener(true);
|
||||||
|
updateCalleeImage();
|
||||||
|
updateConfState();
|
||||||
|
updateSimpleControlButtons();
|
||||||
|
CalleeListAdapter adapter = (CalleeListAdapter) getListAdapter();
|
||||||
|
if (adapter.linphoneCalls.size() != lc().getCallsNb()) {
|
||||||
|
adapter.linphoneCalls.clear();
|
||||||
|
adapter.linphoneCalls.addAll(getInitialCalls());
|
||||||
|
}
|
||||||
|
recreateActivity(adapter);
|
||||||
|
LinphoneManager.startProximitySensorForActivity(this);
|
||||||
|
mSpeakerButton.setChecked(LinphoneManager.getInstance().isSpeakerOn());
|
||||||
|
mMuteMicButton.setChecked(LinphoneManager.getLc().isMicMuted());
|
||||||
|
|
||||||
|
if (multipleCallsLimit > 0) {
|
||||||
|
updateAddCallButton();
|
||||||
|
}
|
||||||
|
|
||||||
|
LinphoneCall currentCall = LinphoneManager.getLc().getCurrentCall();
|
||||||
|
if (currentCall != null) {
|
||||||
|
tryToStartVideoActivity(currentCall, currentCall.getState());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateAddCallButton() {
|
||||||
|
boolean limitReached = lc().getCallsNb() >= multipleCallsLimit;
|
||||||
|
findViewById(R.id.addCall).setVisibility(limitReached ? GONE : VISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onNewIntent(Intent intent) {
|
||||||
|
super.onNewIntent(intent);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void registerLinphoneListener(boolean register) {
|
||||||
|
if (register)
|
||||||
|
LinphoneManager.addListener(this);
|
||||||
|
else
|
||||||
|
LinphoneManager.removeListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResume() {
|
||||||
|
active=true;
|
||||||
|
waitHelper.doManagerDependentOnResume();
|
||||||
|
super.onResume();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPause() {
|
||||||
|
active=false;
|
||||||
|
registerLinphoneListener(false);
|
||||||
|
LinphoneManager.stopProximitySensorForActivity(this);
|
||||||
|
super.onPause();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateCalleeImage() {
|
||||||
|
ImageView view = (ImageView) findViewById(R.id.incall_picture);
|
||||||
|
LinphoneCall currentCall = lc().getCurrentCall();
|
||||||
|
|
||||||
|
if (lc().getCallsNb() != 1 || currentCall == null) {
|
||||||
|
view.setVisibility(GONE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Uri picture = LinphoneUtils.findUriPictureOfContactAndSetDisplayName(
|
||||||
|
currentCall.getRemoteAddress(), getContentResolver());
|
||||||
|
LinphoneUtils.setImagePictureFromUri(this, view, picture, R.drawable.unknown_person);
|
||||||
|
view.setVisibility(VISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void enableView(View root, int id, OnClickListener l, boolean enable) {
|
||||||
|
View v = root.findViewById(id);
|
||||||
|
v.setVisibility(enable ? VISIBLE : GONE);
|
||||||
|
v.setOnClickListener(l);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
protected Dialog onCreateDialog(final int id) {
|
||||||
|
if (id == LinphoneManagerWaitHelper.DIALOG_ID) {
|
||||||
|
return waitHelper.createWaitDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (id) {
|
||||||
|
case numpad_dialog_id:
|
||||||
|
return new AlertDialog.Builder(this).setView(
|
||||||
|
getLayoutInflater().inflate(R.layout.numpad, null))
|
||||||
|
// .setIcon(R.drawable.logo_linphone_57x57)
|
||||||
|
// .setTitle("Send DTMFs")
|
||||||
|
.setPositiveButton(getString(R.string.close_button_text), new
|
||||||
|
DialogInterface.OnClickListener() {
|
||||||
|
public void onClick(DialogInterface dialog, int whichButton)
|
||||||
|
{
|
||||||
|
dismissDialog(id);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.create();
|
||||||
|
default:
|
||||||
|
throw new RuntimeException("unkown dialog id " + id);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// protected void conferenceMerge(boolean hostInTheConference, LinphoneCall
|
||||||
|
// ... calls) {
|
||||||
|
// for (LinphoneCall call: calls) {
|
||||||
|
// getLc().addToConference(call, false);
|
||||||
|
// }
|
||||||
|
// getLc().enterConference(hostInTheConference);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// FIXME hack; should have an event?
|
||||||
|
protected final void hackTriggerConfStateUpdate() {
|
||||||
|
updateConfState();
|
||||||
|
}
|
||||||
|
|
||||||
|
private final void updateConfState() {
|
||||||
|
if (lc().getCallsNb() == 0) {
|
||||||
|
setResult(RESULT_OK);
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean inConf = lc().isInConference();
|
||||||
|
|
||||||
|
int bgColor = getResources().getColor(inConf? R.color.conf_active_bg_color : android.R.color.transparent);
|
||||||
|
confHeaderView.setBackgroundColor(bgColor);
|
||||||
|
confHeaderView.setVisibility(lc().getConferenceSize() > 0 ? VISIBLE: GONE);
|
||||||
|
|
||||||
|
// TextView v = (TextView) confHeaderView
|
||||||
|
// .findViewById(R.id.conf_self_attending);
|
||||||
|
// v.setText(inConf ? R.string.in_conf : R.string.out_conf);
|
||||||
|
}
|
||||||
|
|
||||||
|
private LinphoneCall activateCallOnReturnFromUriPicker;
|
||||||
|
private boolean enterConferenceOnReturnFromUriPicker;
|
||||||
|
private void openUriPicker(String pickerType, int requestCode) {
|
||||||
|
activateCallOnReturnFromUriPicker = lc().getCurrentCall();
|
||||||
|
enterConferenceOnReturnFromUriPicker = lc().isInConference();
|
||||||
|
pauseCurrentCallOrLeaveConference();
|
||||||
|
Intent intent = new Intent().setClass(this, UriPickerActivity.class);
|
||||||
|
intent.putExtra(UriPickerActivity.EXTRA_PICKER_TYPE, pickerType);
|
||||||
|
startActivityForResult(intent, requestCode);
|
||||||
|
if (!lc().isMicMuted()) {
|
||||||
|
unMuteOnReturnFromUriPicker = true;
|
||||||
|
lc().muteMic(true);
|
||||||
|
((ToggleButton) findViewById(R.id.toggleMuteMic)).setChecked(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onClick(View v) {
|
||||||
|
switch (v.getId()) {
|
||||||
|
case R.id.addCall:
|
||||||
|
openUriPicker(UriPickerActivity.EXTRA_PICKER_TYPE_ADD, ID_ADD_CALL);
|
||||||
|
break;
|
||||||
|
case R.id.conf_header:
|
||||||
|
View content = getLayoutInflater().inflate(R.layout.conf_choices_admin, null);
|
||||||
|
final Dialog dialog = new AlertDialog.Builder(ConferenceActivity.this).setView(content).create();
|
||||||
|
boolean isInConference = lc().isInConference();
|
||||||
|
OnClickListener l = new OnClickListener() {
|
||||||
|
public void onClick(View v) {
|
||||||
|
switch (v.getId()) {
|
||||||
|
case R.id.conf_add_all_to_conference_button:
|
||||||
|
lc().addAllToConference();
|
||||||
|
updateConfState();
|
||||||
|
break;
|
||||||
|
case R.id.conf_enter_button:
|
||||||
|
lc().enterConference();
|
||||||
|
updateConfState();
|
||||||
|
break;
|
||||||
|
case R.id.conf_leave_button:
|
||||||
|
lc().leaveConference();
|
||||||
|
updateConfState();
|
||||||
|
break;
|
||||||
|
case R.id.conf_terminate_button:
|
||||||
|
lc().terminateConference();
|
||||||
|
findViewById(R.id.conf_header).setVisibility(GONE);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
dialog.dismiss();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
enableView(content, R.id.conf_enter_button, l, !isInConference);
|
||||||
|
enableView(content, R.id.conf_leave_button, l, isInConference);
|
||||||
|
content.findViewById(R.id.conf_terminate_button).setOnClickListener(l);
|
||||||
|
content.findViewById(R.id.conf_add_all_to_conference_button).setOnClickListener(l);
|
||||||
|
|
||||||
|
dialog.show();
|
||||||
|
break;
|
||||||
|
case R.id.incallHang:
|
||||||
|
lc().terminateAllCalls();
|
||||||
|
setResult(RESULT_OK);
|
||||||
|
finish();
|
||||||
|
break;
|
||||||
|
case R.id.incallNumpadShow:
|
||||||
|
showDialog(numpad_dialog_id);
|
||||||
|
break;
|
||||||
|
case R.id.conf_simple_merge:
|
||||||
|
findViewById(R.id.conf_control_buttons).setVisibility(GONE);
|
||||||
|
lc().addAllToConference();
|
||||||
|
break;
|
||||||
|
case R.id.conf_simple_transfer:
|
||||||
|
findViewById(R.id.conf_control_buttons).setVisibility(GONE);
|
||||||
|
LinphoneCall tCall = lc().getCurrentCall();
|
||||||
|
if (tCall != null) {
|
||||||
|
prepareForTransferingExistingCall(tCall);
|
||||||
|
} else {
|
||||||
|
Toast.makeText(this, R.string.conf_simple_no_current_call, Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case R.id.conf_simple_permute:
|
||||||
|
findViewById(R.id.conf_control_buttons).setVisibility(GONE);
|
||||||
|
for (LinphoneCall call : LinphoneUtils.getLinphoneCalls(lc())) {
|
||||||
|
if (State.Paused == call.getState()) {
|
||||||
|
lc().resumeCall(call);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case R.id.toggleMuteMic:
|
||||||
|
lc().muteMic(((ToggleButton) v).isChecked());
|
||||||
|
break;
|
||||||
|
case R.id.toggleSpeaker:
|
||||||
|
if (((ToggleButton) v).isChecked()) {
|
||||||
|
LinphoneManager.getInstance().routeAudioToSpeaker(true);
|
||||||
|
} else {
|
||||||
|
LinphoneManager.getInstance().routeAudioToReceiver(true);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void prepareForTransferingExistingCall(final LinphoneCall call) {
|
||||||
|
final List<LinphoneCall> existingCalls = LinphoneUtils.getLinphoneCalls(lc());
|
||||||
|
existingCalls.remove(call);
|
||||||
|
final List<String> numbers = new ArrayList<String>(existingCalls.size());
|
||||||
|
Resources r = getResources();
|
||||||
|
for(LinphoneCall c : existingCalls) {
|
||||||
|
numbers.add(LinphoneManager.extractADisplayName(r, c.getRemoteAddress()));
|
||||||
|
}
|
||||||
|
ListAdapter adapter = new ArrayAdapter<String>(ConferenceActivity.this, android.R.layout.select_dialog_item, numbers);
|
||||||
|
DialogInterface.OnClickListener l = new DialogInterface.OnClickListener() {
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
lc().transferCallToAnother(call, existingCalls.get(which));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
new AlertDialog.Builder(ConferenceActivity.this).setTitle(R.string.transfer_dialog_title).setAdapter(adapter, l).create().show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private class CallActionListener implements OnClickListener {
|
||||||
|
private LinphoneCall call;
|
||||||
|
private Dialog dialog;
|
||||||
|
public CallActionListener(LinphoneCall call, Dialog dialog) {
|
||||||
|
this.call = call;
|
||||||
|
this.dialog = dialog;
|
||||||
|
}
|
||||||
|
public CallActionListener(LinphoneCall call) {
|
||||||
|
this.call = call;
|
||||||
|
}
|
||||||
|
public void onClick(View v) {
|
||||||
|
switch (v.getId()) {
|
||||||
|
case R.id.merge_to_conference:
|
||||||
|
lc().addToConference(call);
|
||||||
|
break;
|
||||||
|
case R.id.terminate_call:
|
||||||
|
lc().terminateCall(call);
|
||||||
|
break;
|
||||||
|
case R.id.pause:
|
||||||
|
lc().pauseCall(call);
|
||||||
|
break;
|
||||||
|
case R.id.resume:
|
||||||
|
lc().resumeCall(call);
|
||||||
|
break;
|
||||||
|
case R.id.unhook_call:
|
||||||
|
try {
|
||||||
|
lc().acceptCall(call);
|
||||||
|
} catch (LinphoneCoreException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case R.id.transfer_existing:
|
||||||
|
prepareForTransferingExistingCall(call);
|
||||||
|
break;
|
||||||
|
case R.id.transfer_new:
|
||||||
|
openUriPicker(UriPickerActivity.EXTRA_PICKER_TYPE_TRANSFER, ID_TRANSFER_CALL);
|
||||||
|
callToTransfer = call;
|
||||||
|
break;
|
||||||
|
case R.id.remove_from_conference:
|
||||||
|
lc().removeFromConference(call);
|
||||||
|
break;
|
||||||
|
case R.id.addVideo:
|
||||||
|
LinphoneManager.getInstance().addVideo();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new RuntimeException("unknown id " + v.getId());
|
||||||
|
}
|
||||||
|
if (dialog != null) dialog.dismiss();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private class CalleeListAdapter extends BaseAdapter {
|
||||||
|
private List<LinphoneCall> linphoneCalls;
|
||||||
|
|
||||||
|
public CalleeListAdapter(List<LinphoneCall> calls) {
|
||||||
|
linphoneCalls = calls;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCount() {
|
||||||
|
return linphoneCalls != null ? linphoneCalls.size() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getItem(int position) {
|
||||||
|
return linphoneCalls.get(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getItemId(int position) {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean aConferenceIsPossible() {
|
||||||
|
if (lc().getCallsNb() < 2) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int count = 0;
|
||||||
|
for (LinphoneCall call : linphoneCalls) {
|
||||||
|
final LinphoneCall.State state = call.getState();
|
||||||
|
boolean connectionEstablished = state == State.StreamsRunning
|
||||||
|
|| state == State.Paused
|
||||||
|
|| state == State.PausedByRemote;
|
||||||
|
if (connectionEstablished)
|
||||||
|
count++;
|
||||||
|
if (count >= 2)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setVisibility(View v, int id, boolean visible) {
|
||||||
|
v.findViewById(id).setVisibility(visible ? VISIBLE : GONE);
|
||||||
|
}
|
||||||
|
private void setVisibility(View v, boolean visible) {
|
||||||
|
v.setVisibility(visible ? VISIBLE : GONE);
|
||||||
|
}
|
||||||
|
private void setStatusLabel(View v, State state, boolean inConf, boolean activeOne) {
|
||||||
|
String statusLabel = getStateText(state);
|
||||||
|
|
||||||
|
if (activeOne)
|
||||||
|
statusLabel=getString(R.string.status_active_call);
|
||||||
|
|
||||||
|
if (inConf)
|
||||||
|
statusLabel=getString(R.string.status_conf_call);
|
||||||
|
|
||||||
|
((TextView) v.findViewById(R.id.status_label)).setText(statusLabel);
|
||||||
|
}
|
||||||
|
|
||||||
|
public View getView(int position, View v, ViewGroup parent) {
|
||||||
|
Log.i("ConferenceActivity.getView(",position,") out of ", linphoneCalls.size());
|
||||||
|
if (v == null) {
|
||||||
|
if (Version.sdkAboveOrEqual(Version.API06_ECLAIR_201)) {
|
||||||
|
v = getLayoutInflater().inflate(R.layout.conf_callee, null);
|
||||||
|
} else {
|
||||||
|
v = getLayoutInflater().inflate(R.layout.conf_callee_older_devices, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final LinphoneCall call = linphoneCalls.get(position);
|
||||||
|
final LinphoneCall.State state = call.getState();
|
||||||
|
|
||||||
|
LinphoneAddress address = call.getRemoteAddress();
|
||||||
|
String mainText = address.getDisplayName();
|
||||||
|
String complText = address.getUserName();
|
||||||
|
if ((getResources().getBoolean(R.bool.show_full_remote_address_on_incoming_call))) {
|
||||||
|
complText += "@" + address.getDomain();
|
||||||
|
}
|
||||||
|
TextView mainTextView = (TextView) v.findViewById(R.id.name);
|
||||||
|
TextView complTextView = (TextView) v.findViewById(R.id.address);
|
||||||
|
if (TextUtils.isEmpty(mainText)) {
|
||||||
|
mainTextView.setText(complText);
|
||||||
|
complTextView.setVisibility(View.GONE);
|
||||||
|
} else {
|
||||||
|
mainTextView.setText(mainText);
|
||||||
|
complTextView.setText(complText);
|
||||||
|
complTextView.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
final boolean isInConference = call.isInConference();
|
||||||
|
boolean currentlyActiveCall = !isInConference
|
||||||
|
&& state == State.StreamsRunning;
|
||||||
|
|
||||||
|
setStatusLabel(v, state, isInConference, currentlyActiveCall);
|
||||||
|
|
||||||
|
|
||||||
|
int bgDrawableId = R.drawable.conf_callee_selector_normal;
|
||||||
|
if (state == State.IncomingReceived) {
|
||||||
|
bgDrawableId = R.drawable.conf_callee_selector_incoming;
|
||||||
|
} else if (currentlyActiveCall) {
|
||||||
|
bgDrawableId = R.drawable.conf_callee_selector_active;
|
||||||
|
} else if (isInConference) {
|
||||||
|
bgDrawableId = R.drawable.conf_callee_selector_inconf;
|
||||||
|
}
|
||||||
|
v.setBackgroundResource(bgDrawableId);
|
||||||
|
|
||||||
|
boolean connectionEstablished = state == State.StreamsRunning
|
||||||
|
|| state == State.Paused
|
||||||
|
|| state == State.PausedByRemote;
|
||||||
|
View confButton = v.findViewById(R.id.merge_to_conference);
|
||||||
|
final boolean showMergeToConf = !isInConference && connectionEstablished
|
||||||
|
&& aConferenceIsPossible();
|
||||||
|
setVisibility(confButton, false);
|
||||||
|
|
||||||
|
View unhookCallButton = v.findViewById(R.id.unhook_call);
|
||||||
|
boolean showUnhook = state == State.IncomingReceived;
|
||||||
|
setVisibility(unhookCallButton, showUnhook);
|
||||||
|
|
||||||
|
View terminateCallButton = v.findViewById(R.id.terminate_call);
|
||||||
|
boolean showTerminate = state == State.IncomingReceived;
|
||||||
|
setVisibility(terminateCallButton, showTerminate);
|
||||||
|
|
||||||
|
View pauseButton = v.findViewById(R.id.pause);
|
||||||
|
final boolean showPause = !isInConference
|
||||||
|
&& state == State.StreamsRunning;
|
||||||
|
setVisibility(pauseButton, false);
|
||||||
|
|
||||||
|
View resumeButton = v.findViewById(R.id.resume);
|
||||||
|
final boolean showResume = !isInConference
|
||||||
|
&& state == State.Paused;
|
||||||
|
setVisibility(resumeButton, false);
|
||||||
|
|
||||||
|
View removeFromConfButton = v.findViewById(R.id.remove_from_conference);
|
||||||
|
setVisibility(removeFromConfButton, false);
|
||||||
|
|
||||||
|
final int numberOfCalls = linphoneCalls.size();
|
||||||
|
boolean showAddVideo = State.StreamsRunning == state && !isInConference
|
||||||
|
&& useVideoActivity
|
||||||
|
&& Version.isVideoCapable()
|
||||||
|
&& LinphoneManager.getInstance().isVideoEnabled();
|
||||||
|
View addVideoButton = v.findViewById(R.id.addVideo);
|
||||||
|
setVisibility(addVideoButton, showAddVideo);
|
||||||
|
|
||||||
|
boolean statusPaused = state== State.Paused || state == State.PausedByRemote;
|
||||||
|
setVisibility(v, R.id.callee_status_paused, statusPaused);
|
||||||
|
|
||||||
|
setVisibility(v, R.id.callee_status_inconf, isInConference);
|
||||||
|
|
||||||
|
final OnClickListener l = new CallActionListener(call);
|
||||||
|
confButton.setOnClickListener(l);
|
||||||
|
terminateCallButton.setOnClickListener(l);
|
||||||
|
pauseButton.setOnClickListener(l);
|
||||||
|
resumeButton.setOnClickListener(l);
|
||||||
|
unhookCallButton.setOnClickListener(l);
|
||||||
|
removeFromConfButton.setOnClickListener(l);
|
||||||
|
addVideoButton.setOnClickListener(l);
|
||||||
|
|
||||||
|
v.setOnClickListener(new OnClickListener() {
|
||||||
|
public void onClick(View v) {
|
||||||
|
View content = getLayoutInflater().inflate(R.layout.conf_choices_dialog, null);
|
||||||
|
Dialog dialog = new AlertDialog.Builder(ConferenceActivity.this).setView(content).create();
|
||||||
|
OnClickListener l = new CallActionListener(call, dialog);
|
||||||
|
enableView(content, R.id.transfer_existing, l, allowTransfers && !isInConference && numberOfCalls >=2);
|
||||||
|
enableView(content, R.id.transfer_new, l, allowTransfers && !isInConference);
|
||||||
|
enableView(content, R.id.remove_from_conference, l, isInConference);
|
||||||
|
enableView(content, R.id.merge_to_conference, l, showMergeToConf);
|
||||||
|
enableView(content, R.id.pause, l,!isInConference && showPause);
|
||||||
|
enableView(content, R.id.resume, l, !isInConference && showResume);
|
||||||
|
enableView(content, R.id.terminate_call, l, true);
|
||||||
|
dialog.show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
ImageView pictureView = (ImageView) v.findViewById(R.id.picture);
|
||||||
|
if (numberOfCalls != 1) {
|
||||||
|
// May be greatly sped up using a drawable cache
|
||||||
|
Uri uri = LinphoneUtils.findUriPictureOfContactAndSetDisplayName(address, getContentResolver());
|
||||||
|
LinphoneUtils.setImagePictureFromUri(ConferenceActivity.this, pictureView, uri, R.drawable.unknown_person);
|
||||||
|
pictureView.setVisibility(VISIBLE);
|
||||||
|
} else {
|
||||||
|
pictureView.setVisibility(GONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getStateText(State state) {
|
||||||
|
int id;
|
||||||
|
if (state == State.IncomingReceived) {
|
||||||
|
id=R.string.state_incoming_received;
|
||||||
|
} else if (state == State.OutgoingRinging) {
|
||||||
|
id=R.string.state_outgoing_ringing;
|
||||||
|
} else if (state == State.Paused) {
|
||||||
|
id=R.string.state_paused;
|
||||||
|
} else if (state == State.PausedByRemote) {
|
||||||
|
id=R.string.state_paused_by_remote;
|
||||||
|
} else {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return getString(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Handler mHandler = new Handler();
|
||||||
|
|
||||||
|
private void updateSimpleControlButtons() {
|
||||||
|
LinphoneCall activeCall = lc().getCurrentCall();
|
||||||
|
View controlLayout = findViewById(R.id.conf_control_buttons);
|
||||||
|
int callNb = lc().getCallsNb();
|
||||||
|
boolean hide = activeCall == null || callNb !=2 || lc().getConferenceSize() > 0;
|
||||||
|
controlLayout.setVisibility(hide ? GONE : VISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void tryToStartVideoActivity(LinphoneCall call, State state) {
|
||||||
|
if (State.StreamsRunning == state && call.getCurrentParamsCopy().getVideoEnabled()) {
|
||||||
|
if (call.cameraEnabled() ) {
|
||||||
|
LinphoneActivity.instance().startVideoActivity();
|
||||||
|
} else {
|
||||||
|
Log.i("Not starting video call activity as the camera is disabled");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onCallStateChanged(final LinphoneCall call, final State state,
|
||||||
|
final String message) {
|
||||||
|
final String stateStr = call + " " + state.toString();
|
||||||
|
Log.d("ConferenceActivity received state ",stateStr);
|
||||||
|
|
||||||
|
tryToStartVideoActivity(call, state);
|
||||||
|
|
||||||
|
mHandler.post(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
CalleeListAdapter adapter = (CalleeListAdapter) getListAdapter();
|
||||||
|
Log.d("ConferenceActivity applying state ",stateStr);
|
||||||
|
updateSimpleControlButtons();
|
||||||
|
updateCalleeImage();
|
||||||
|
if (state == State.IncomingReceived || state == State.OutgoingRinging) {
|
||||||
|
if (!adapter.linphoneCalls.contains(call)) {
|
||||||
|
adapter.linphoneCalls.add(call);
|
||||||
|
Collections.sort(adapter.linphoneCalls, ConferenceActivity.this);
|
||||||
|
recreateActivity(adapter);
|
||||||
|
} else {
|
||||||
|
Log.e("Call should not be in the call lists : ", stateStr);
|
||||||
|
}
|
||||||
|
} else if (state == State.Paused || state == State.PausedByRemote || state == State.StreamsRunning) {
|
||||||
|
Collections.sort(adapter.linphoneCalls, ConferenceActivity.this);
|
||||||
|
adapter.notifyDataSetChanged();
|
||||||
|
} else if (state == State.CallEnd) {
|
||||||
|
adapter.linphoneCalls.remove(call);
|
||||||
|
Collections.sort(adapter.linphoneCalls, ConferenceActivity.this);
|
||||||
|
updateAddCallButton();
|
||||||
|
recreateActivity(adapter);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateConfState();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void recreateActivity(CalleeListAdapter adapter) {
|
||||||
|
adapter.notifyDataSetInvalidated();
|
||||||
|
adapter.notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int compare(LinphoneCall c1, LinphoneCall c2) {
|
||||||
|
if (c1 == c2)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
boolean inConfC1 = c1.isInConference();
|
||||||
|
boolean inConfC2 = c2.isInConference();
|
||||||
|
if (inConfC1 && !inConfC2)
|
||||||
|
return -1;
|
||||||
|
if (!inConfC1 && inConfC2)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
int durationDiff = c2.getDuration() - c1.getDuration();
|
||||||
|
return durationDiff;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private LinphoneCall callToTransfer;
|
||||||
|
@Override
|
||||||
|
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
|
if (unMuteOnReturnFromUriPicker) {
|
||||||
|
lc().muteMic(false);
|
||||||
|
((ToggleButton) findViewById(R.id.toggleMuteMic)).setChecked(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resultCode != RESULT_OK) {
|
||||||
|
callToTransfer = null;
|
||||||
|
Toast.makeText(this, R.string.uri_picking_canceled, Toast.LENGTH_LONG).show();
|
||||||
|
eventuallyResumeConfOrCallOnPickerReturn(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String uri = data.getStringExtra(UriPickerActivity.EXTRA_CALLEE_URI);
|
||||||
|
switch (requestCode) {
|
||||||
|
case ID_ADD_CALL:
|
||||||
|
try {
|
||||||
|
lc().invite(uri);
|
||||||
|
eventuallyResumeConfOrCallOnPickerReturn(false);
|
||||||
|
} catch (LinphoneCoreException e) {
|
||||||
|
Log.e(e);
|
||||||
|
Toast.makeText(this, R.string.error_adding_new_call, Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ID_TRANSFER_CALL:
|
||||||
|
lc().transferCall(callToTransfer, uri);
|
||||||
|
// don't re-enter conference if call to transfer from conference
|
||||||
|
boolean doResume = !callToTransfer.isInConference();
|
||||||
|
// don't resume call if it is the call to transfer
|
||||||
|
doResume &= activateCallOnReturnFromUriPicker != callToTransfer;
|
||||||
|
eventuallyResumeConfOrCallOnPickerReturn(doResume);
|
||||||
|
Toast.makeText(this, R.string.transfer_started, Toast.LENGTH_LONG).show();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new RuntimeException("unhandled request code " + requestCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void eventuallyResumeConfOrCallOnPickerReturn(boolean doCallConfResuming) {
|
||||||
|
if (doCallConfResuming) {
|
||||||
|
if (activateCallOnReturnFromUriPicker != null) {
|
||||||
|
lc().resumeCall(activateCallOnReturnFromUriPicker);
|
||||||
|
} else if (enterConferenceOnReturnFromUriPicker) {
|
||||||
|
lc().enterConference();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
activateCallOnReturnFromUriPicker = null;
|
||||||
|
enterConferenceOnReturnFromUriPicker = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onKeyUp(int keyCode, KeyEvent event) {
|
||||||
|
if (LinphoneUtils.onKeyBackGoHome(this, keyCode)) return true;
|
||||||
|
return super.onKeyUp(keyCode, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||||
|
if (LinphoneUtils.onKeyVolumeSoftAdjust(keyCode)) return true;
|
||||||
|
return super.onKeyDown(keyCode, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAudioStateChanged(final AudioState state) {
|
||||||
|
mSpeakerButton.post(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
switch (state) {
|
||||||
|
case SPEAKER:
|
||||||
|
mSpeakerButton.setChecked(true);
|
||||||
|
break;
|
||||||
|
case EARPIECE:
|
||||||
|
mSpeakerButton.setChecked(false);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new RuntimeException("Unkown audio state " + state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRequestedVideoCallReady(LinphoneCall call) {
|
||||||
|
LinphoneActivity.instance().startVideoActivity();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* public int compare(LinphoneCall c1, LinphoneCall c2) { if (c1 == c2)
|
||||||
|
* return 0;
|
||||||
|
*
|
||||||
|
* boolean inConfC1 = c1.isInConference(); boolean inConfC2 =
|
||||||
|
* c2.isInConference(); if (inConfC1 && !inConfC2) return -1; if (!inConfC1
|
||||||
|
* && inConfC2) return 1;
|
||||||
|
*
|
||||||
|
* int compUserName =
|
||||||
|
* c1.getRemoteAddress().getUserName().compareToIgnoreCase
|
||||||
|
* (c2.getRemoteAddress().getUserName()); if (inConfC1 && inConfC2) { return
|
||||||
|
* compUserName; }
|
||||||
|
*
|
||||||
|
* // bellow, ringings and incoming int c1State = c1.getState().value(); int
|
||||||
|
* c2State = c2.getState().value();
|
||||||
|
*
|
||||||
|
* boolean c1StateIsEstablishing = c1State == State.IncomingReceived ||
|
||||||
|
* c1State == State.ID_OUTGOING_RINGING; boolean c2StateIsEstablishing =
|
||||||
|
* c2State == State.IncomingReceived || c2State ==
|
||||||
|
* State.ID_OUTGOING_RINGING;
|
||||||
|
*
|
||||||
|
* // Xor only one establishing state if (c1StateIsEstablishing ^
|
||||||
|
* c2StateIsEstablishing) { // below return !c1StateIsEstablishing ? -1 : 1;
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* // Xor only one paused state if (c1State == State.Paused ^ c2State ==
|
||||||
|
* State.Paused) { return c1State == State.Paused ? -1 : 1; }
|
||||||
|
*
|
||||||
|
* return compUserName; //Duration() - c1.getDuration(); }
|
||||||
|
*/
|
||||||
|
}
|
258
src/org/linphone/ContactHelper.java
Normal file
|
@ -0,0 +1,258 @@
|
||||||
|
/*
|
||||||
|
ContactHelper.java
|
||||||
|
Copyright (C) 2011 Belledonne Communications, Grenoble, France
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
package org.linphone;
|
||||||
|
|
||||||
|
import org.linphone.core.LinphoneAddress;
|
||||||
|
import org.linphone.mediastream.Version;
|
||||||
|
|
||||||
|
import android.content.ContentResolver;
|
||||||
|
import android.content.ContentUris;
|
||||||
|
import android.database.Cursor;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.telephony.PhoneNumberUtils;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
public final class ContactHelper {
|
||||||
|
|
||||||
|
private String username;
|
||||||
|
private String domain;
|
||||||
|
private ContentResolver resolver;
|
||||||
|
|
||||||
|
|
||||||
|
private Uri foundPhotoUri;
|
||||||
|
public Uri getUri() {
|
||||||
|
return foundPhotoUri;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private String displayName;
|
||||||
|
// public String getDisplayName() {
|
||||||
|
// return displayName;
|
||||||
|
// }
|
||||||
|
|
||||||
|
private LinphoneAddress address;
|
||||||
|
public ContactHelper(LinphoneAddress address, ContentResolver resolver) {
|
||||||
|
username = address.getUserName();
|
||||||
|
domain = address.getDomain();
|
||||||
|
this.resolver = resolver;
|
||||||
|
this.address = address;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean query() {
|
||||||
|
boolean succeeded;
|
||||||
|
if (Version.sdkAboveOrEqual(Version.API06_ECLAIR_201)) {
|
||||||
|
ContactHelperNew helper = new ContactHelperNew();
|
||||||
|
succeeded = helper.queryNewContactAPI();
|
||||||
|
} else {
|
||||||
|
succeeded = queryOldContactAPI();
|
||||||
|
}
|
||||||
|
if (succeeded && !TextUtils.isEmpty(displayName)) {
|
||||||
|
address.setDisplayName(displayName);
|
||||||
|
}
|
||||||
|
return succeeded;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static boolean testPhotoUri(Cursor c) {
|
||||||
|
if (c == null) return false;
|
||||||
|
if (!c.moveToNext()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
byte[] data = c.getBlob(0);
|
||||||
|
if (data == null) {
|
||||||
|
// TODO: simplify all this stuff
|
||||||
|
// which is here only to check that the
|
||||||
|
// photoUri really points to some data.
|
||||||
|
// Not retrieving the data now would be better.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean testPhotoUriAndCloseCursor(Cursor c) {
|
||||||
|
boolean valid = testPhotoUri(c);
|
||||||
|
if (c != null) c.close();
|
||||||
|
return valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean testPhotoUri(ContentResolver resolver, Uri photoUriToTest, String photoCol) {
|
||||||
|
Cursor cursor = resolver.query(photoUriToTest, new String[]{photoCol}, null, null, null);
|
||||||
|
return testPhotoUriAndCloseCursor(cursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// OLD API
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
private final boolean queryOldContactAPI() {
|
||||||
|
String normalizedNumber = PhoneNumberUtils.getStrippedReversed(username);
|
||||||
|
if (TextUtils.isEmpty(normalizedNumber)) {
|
||||||
|
// non phone username
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
String[] projection = {android.provider.Contacts.Phones.PERSON_ID, android.provider.Contacts.Phones.DISPLAY_NAME};
|
||||||
|
String selection = android.provider.Contacts.Phones.NUMBER_KEY + "=" + normalizedNumber;
|
||||||
|
Cursor c = resolver.query(android.provider.Contacts.Phones.CONTENT_URI, projection, selection, null, null);
|
||||||
|
if (c == null) return false;
|
||||||
|
|
||||||
|
while (c.moveToNext()) {
|
||||||
|
long id = c.getLong(c.getColumnIndex(android.provider.Contacts.Phones.PERSON_ID));
|
||||||
|
Uri personUri = ContentUris.withAppendedId(android.provider.Contacts.People.CONTENT_URI, id);
|
||||||
|
Uri potentialPictureUri = Uri.withAppendedPath(personUri, android.provider.Contacts.Photos.CONTENT_DIRECTORY);
|
||||||
|
boolean valid = testPhotoUri(resolver, potentialPictureUri, android.provider.Contacts.Photos.DATA);
|
||||||
|
if (valid) {
|
||||||
|
displayName = c.getString(c.getColumnIndex(android.provider.Contacts.Phones.DISPLAY_NAME));
|
||||||
|
foundPhotoUri = personUri; // hack (not returning pictureUri as it crashes when reading from it)
|
||||||
|
c.close();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// END OLD API
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// START NEW CONTACT API
|
||||||
|
|
||||||
|
private class ContactHelperNew {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private final boolean checkPhotosUris(ContentResolver resolver, Cursor c, String idCol, String nameCol) {
|
||||||
|
if (c == null) return false;
|
||||||
|
while (c.moveToNext()) {
|
||||||
|
long id = c.getLong(c.getColumnIndex(idCol));
|
||||||
|
Uri contactUri = ContentUris.withAppendedId(android.provider.ContactsContract.Contacts.CONTENT_URI, id);
|
||||||
|
Uri photoUri = Uri.withAppendedPath(contactUri, android.provider.ContactsContract.Contacts.Photo.CONTENT_DIRECTORY);
|
||||||
|
if (photoUri == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
String[] projection = {android.provider.ContactsContract.CommonDataKinds.Photo.PHOTO};
|
||||||
|
Cursor photoCursor = resolver.query(photoUri, projection, null, null, null);
|
||||||
|
boolean valid = testPhotoUriAndCloseCursor(photoCursor);
|
||||||
|
if (valid) {
|
||||||
|
foundPhotoUri = photoUri;
|
||||||
|
displayName = c.getString(c.getColumnIndex(nameCol));
|
||||||
|
c.close();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final boolean queryNewContactAPI() {
|
||||||
|
String sipUri = username + "@" + domain;
|
||||||
|
|
||||||
|
// Try first using sip field
|
||||||
|
Uri uri = android.provider.ContactsContract.Data.CONTENT_URI;
|
||||||
|
String[] projection = {
|
||||||
|
android.provider.ContactsContract.Data.CONTACT_ID,
|
||||||
|
android.provider.ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME};
|
||||||
|
String selection = new StringBuilder()
|
||||||
|
.append(android.provider.ContactsContract.CommonDataKinds.Im.DATA).append(" = ? AND ")
|
||||||
|
.append(android.provider.ContactsContract.Data.MIMETYPE)
|
||||||
|
.append(" = '")
|
||||||
|
.append(android.provider.ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE)
|
||||||
|
.append("' AND lower(")
|
||||||
|
.append(android.provider.ContactsContract.CommonDataKinds.Im.CUSTOM_PROTOCOL)
|
||||||
|
.append(") = 'sip'").toString();
|
||||||
|
Cursor c = resolver.query(uri, projection, selection, new String[] {sipUri}, null);
|
||||||
|
boolean valid = checkPhotosUris(resolver, c,
|
||||||
|
android.provider.ContactsContract.Data.CONTACT_ID,
|
||||||
|
android.provider.ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
|
||||||
|
if (valid) return true;
|
||||||
|
|
||||||
|
|
||||||
|
// Then using custom SIP field
|
||||||
|
if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) {
|
||||||
|
selection = new StringBuilder()
|
||||||
|
.append(android.provider.ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS)
|
||||||
|
.append(" = ? AND ")
|
||||||
|
.append(android.provider.ContactsContract.Data.MIMETYPE)
|
||||||
|
.append(" = '")
|
||||||
|
.append(android.provider.ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE)
|
||||||
|
.append("'")
|
||||||
|
.toString();
|
||||||
|
c = resolver.query(uri, projection, selection, new String[] {sipUri}, null);
|
||||||
|
valid = checkPhotosUris(resolver, c,
|
||||||
|
android.provider.ContactsContract.Data.CONTACT_ID,
|
||||||
|
android.provider.ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
|
||||||
|
if (valid) return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finally using phone number
|
||||||
|
String normalizedNumber = PhoneNumberUtils.getStrippedReversed(username);
|
||||||
|
if (TextUtils.isEmpty(normalizedNumber)) {
|
||||||
|
// non phone username
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Uri lookupUri = Uri.withAppendedPath(android.provider.ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(username));
|
||||||
|
projection = new String[]{
|
||||||
|
android.provider.ContactsContract.PhoneLookup._ID,
|
||||||
|
android.provider.ContactsContract.PhoneLookup.NUMBER,
|
||||||
|
android.provider.ContactsContract.PhoneLookup.DISPLAY_NAME};
|
||||||
|
c = resolver.query(lookupUri, projection, null, null, null);
|
||||||
|
while (c.moveToNext()) {
|
||||||
|
long id = c.getLong(c.getColumnIndex(android.provider.ContactsContract.PhoneLookup._ID));
|
||||||
|
String enteredNumber = c.getString(c.getColumnIndex(android.provider.ContactsContract.PhoneLookup.NUMBER));
|
||||||
|
if (!normalizedNumber.equals(PhoneNumberUtils.getStrippedReversed(enteredNumber))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Uri contactUri = ContentUris.withAppendedId(android.provider.ContactsContract.Contacts.CONTENT_URI, id);
|
||||||
|
Uri photoUri = Uri.withAppendedPath(contactUri, android.provider.ContactsContract.Contacts.Photo.CONTENT_DIRECTORY);
|
||||||
|
if (photoUri == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String[] photoProj = {android.provider.ContactsContract.CommonDataKinds.Photo.PHOTO};
|
||||||
|
Cursor cursor = resolver.query(photoUri, photoProj, null, null, null);
|
||||||
|
valid = testPhotoUriAndCloseCursor(cursor);
|
||||||
|
if (valid) {
|
||||||
|
displayName = c.getString(c.getColumnIndex(android.provider.ContactsContract.PhoneLookup.DISPLAY_NAME));
|
||||||
|
foundPhotoUri = photoUri;
|
||||||
|
c.close();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -23,6 +23,7 @@ import java.util.List;
|
||||||
|
|
||||||
import org.linphone.mediastream.Version;
|
import org.linphone.mediastream.Version;
|
||||||
|
|
||||||
|
import android.content.ContentResolver;
|
||||||
import android.content.ContentUris;
|
import android.content.ContentUris;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
|
@ -52,35 +53,28 @@ public class ContactPickerActivityNew extends AbstractContactPickerActivity {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Uri getPhotoUri(String id) {
|
public Uri getPhotoUri(String id) {
|
||||||
Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, Long.parseLong(id));
|
return retrievePhotoUriAndSetDisplayName(getContentResolver(), Long.parseLong(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Uri retrievePhotoUriAndSetDisplayName(ContentResolver resolver, long id) {
|
||||||
|
Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, id);
|
||||||
Uri photoUri = Uri.withAppendedPath(contactUri, Contacts.Photo.CONTENT_DIRECTORY);
|
Uri photoUri = Uri.withAppendedPath(contactUri, Contacts.Photo.CONTENT_DIRECTORY);
|
||||||
if (photoUri == null) {
|
if (photoUri == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
Cursor cursor = getContentResolver().query(photoUri,
|
if (ContactHelper.testPhotoUri(resolver, photoUri, ContactsContract.CommonDataKinds.Photo.PHOTO)) {
|
||||||
new String[]{ContactsContract.CommonDataKinds.Photo.PHOTO}, null, null, null);
|
|
||||||
try {
|
|
||||||
if (cursor == null || !cursor.moveToNext()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
byte[] data = cursor.getBlob(0);
|
|
||||||
if (data == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return photoUri;
|
return photoUri;
|
||||||
} finally {
|
|
||||||
if (cursor != null) {
|
|
||||||
cursor.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected List<String> extractPhones(String id) {
|
protected List<String> extractPhones(String id) {
|
||||||
List<String> list = new ArrayList<String>();
|
List<String> list = new ArrayList<String>();
|
||||||
Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
|
Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
|
||||||
|
String[] projection = {ContactsContract.CommonDataKinds.Phone.NUMBER};
|
||||||
String selection = ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?";
|
String selection = ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?";
|
||||||
String[] selArgs = new String[] {id};
|
String[] selArgs = new String[] {id};
|
||||||
Cursor c = this.getContentResolver().query(uri, null, selection, selArgs, null);
|
Cursor c = this.getContentResolver().query(uri, projection, selection, selArgs, null);
|
||||||
|
|
||||||
int nbId = c.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
|
int nbId = c.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
|
||||||
|
|
||||||
|
@ -96,35 +90,41 @@ public class ContactPickerActivityNew extends AbstractContactPickerActivity {
|
||||||
protected List<String> extractSipNumbers(String id) {
|
protected List<String> extractSipNumbers(String id) {
|
||||||
List<String> list = new ArrayList<String>();
|
List<String> list = new ArrayList<String>();
|
||||||
Uri uri = ContactsContract.Data.CONTENT_URI;
|
Uri uri = ContactsContract.Data.CONTENT_URI;
|
||||||
|
String[] projection = {ContactsContract.CommonDataKinds.Im.DATA};
|
||||||
String selection = new StringBuilder()
|
String selection = new StringBuilder()
|
||||||
.append(ContactsContract.Data.CONTACT_ID).append(" = ? AND ")
|
.append(ContactsContract.Data.CONTACT_ID).append(" = ? AND ")
|
||||||
.append(ContactsContract.Data.MIMETYPE).append(" = ? ")
|
.append(ContactsContract.Data.MIMETYPE).append(" = '")
|
||||||
.append(" AND lower(")
|
.append(ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE)
|
||||||
.append(ContactsContract.CommonDataKinds.Im.CUSTOM_PROTOCOL)
|
.append("' AND lower(")
|
||||||
.append(") = 'sip'").toString();
|
.append(ContactsContract.CommonDataKinds.Im.CUSTOM_PROTOCOL)
|
||||||
String[] selArgs = new String[] {id, ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE};
|
.append(") = 'sip'")
|
||||||
Cursor c = this.getContentResolver().query(uri, null, selection, selArgs, null);
|
.toString();
|
||||||
|
Cursor c = getContentResolver().query(uri, projection, selection, new String[]{id}, null);
|
||||||
|
|
||||||
int nbId = c.getColumnIndex(ContactsContract.CommonDataKinds.Im.DATA);
|
int nbId = c.getColumnIndex(ContactsContract.CommonDataKinds.Im.DATA);
|
||||||
|
|
||||||
while (c.moveToNext()) {
|
while (c.moveToNext()) {
|
||||||
list.add("sip:" + c.getString(nbId));
|
list.add("sip:" + c.getString(nbId));
|
||||||
}
|
}
|
||||||
|
|
||||||
c.close();
|
c.close();
|
||||||
|
|
||||||
|
|
||||||
// Using the SIP contact field added in SDK 9
|
// Using the SIP contact field added in SDK 9
|
||||||
if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) {
|
if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) {
|
||||||
selection = ContactsContract.Data.CONTACT_ID + " = ? AND " + ContactsContract.Data.MIMETYPE + " = ?";
|
selection = new StringBuilder()
|
||||||
String projection[] = new String[] {ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS};
|
.append(ContactsContract.Data.CONTACT_ID)
|
||||||
selArgs = new String[] {id, ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE};
|
.append(" = ? AND ")
|
||||||
c = this.getContentResolver().query(uri, projection, selection, selArgs, null);
|
.append(ContactsContract.Data.MIMETYPE)
|
||||||
|
.append(" = '")
|
||||||
|
.append(ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE)
|
||||||
|
.append("'")
|
||||||
|
.toString();
|
||||||
|
projection = new String[] {ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS};
|
||||||
|
c = this.getContentResolver().query(uri, projection, selection, new String[]{id}, null);
|
||||||
|
|
||||||
nbId = c.getColumnIndex(ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS);
|
nbId = c.getColumnIndex(ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS);
|
||||||
while (c.moveToNext()) {
|
while (c.moveToNext()) {
|
||||||
list.add("sip:" + c.getString(nbId));
|
list.add("sip:" + c.getString(nbId));
|
||||||
}
|
}
|
||||||
|
|
||||||
c.close();
|
c.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,13 +162,14 @@ public class ContactPickerActivityNew extends AbstractContactPickerActivity {
|
||||||
private String retrieveContactName(String id) {
|
private String retrieveContactName(String id) {
|
||||||
//Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
|
//Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
|
||||||
Uri uri = ContactsContract.Contacts.CONTENT_URI;
|
Uri uri = ContactsContract.Contacts.CONTENT_URI;
|
||||||
|
String[] projection = new String[] {ContactsContract.Contacts.DISPLAY_NAME};
|
||||||
String selection = ContactsContract.Contacts._ID + " = ?";
|
String selection = ContactsContract.Contacts._ID + " = ?";
|
||||||
String[] selArgs = new String[] {id};
|
String[] selArgs = new String[] {id};
|
||||||
Cursor c = this.getContentResolver().query(uri, null, selection, selArgs, null);
|
Cursor c = this.getContentResolver().query(uri, projection, selection, selArgs, null);
|
||||||
|
|
||||||
String name = "";
|
String name = "";
|
||||||
if (c.moveToFirst()) {
|
if (c.moveToFirst()) {
|
||||||
name = c.getString(c.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
|
name = c.getString(c.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
|
||||||
}
|
}
|
||||||
c.close();
|
c.close();
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,6 @@ import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.provider.Contacts;
|
import android.provider.Contacts;
|
||||||
import android.provider.Contacts.People;
|
import android.provider.Contacts.People;
|
||||||
import android.provider.Contacts.Photos;
|
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
public class ContactPickerActivityOld extends Activity {
|
public class ContactPickerActivityOld extends Activity {
|
||||||
|
@ -48,21 +47,6 @@ public class ContactPickerActivityOld extends Activity {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Uri getPhotoUri(Uri photoUri) {
|
|
||||||
Cursor cursor = getContentResolver().query(photoUri, new String[]{Photos.DATA}, null, null, null);
|
|
||||||
try {
|
|
||||||
if (cursor == null || !cursor.moveToNext()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
byte[] data = cursor.getBlob(0);
|
|
||||||
if (data == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return photoUri;
|
|
||||||
} finally {
|
|
||||||
if (cursor != null) cursor.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void onActivityResult(int requestCode, int resultCode,
|
protected void onActivityResult(int requestCode, int resultCode,
|
||||||
Intent data) {
|
Intent data) {
|
||||||
|
@ -81,8 +65,10 @@ public class ContactPickerActivityOld extends Activity {
|
||||||
String lPhoneNo = lCur.getString(lCur.getColumnIndex(People.NUMBER));
|
String lPhoneNo = lCur.getString(lCur.getColumnIndex(People.NUMBER));
|
||||||
long id = lCur.getLong(lCur.getColumnIndex(People._ID));
|
long id = lCur.getLong(lCur.getColumnIndex(People._ID));
|
||||||
Uri personUri = ContentUris.withAppendedId(People.CONTENT_URI, id);
|
Uri personUri = ContentUris.withAppendedId(People.CONTENT_URI, id);
|
||||||
Uri potentialPictureUri = Uri.withAppendedPath(personUri, Contacts.Photos.CONTENT_DIRECTORY);
|
Uri pictureUri = Uri.withAppendedPath(personUri, Contacts.Photos.CONTENT_DIRECTORY);
|
||||||
Uri pictureUri = getPhotoUri(potentialPictureUri);
|
if (!ContactHelper.testPhotoUri(getContentResolver(), pictureUri, Contacts.Photos.CONTENT_DIRECTORY)) {
|
||||||
|
pictureUri = null;
|
||||||
|
}
|
||||||
// FIXME surprisingly all this picture stuff doesn't seem to work
|
// FIXME surprisingly all this picture stuff doesn't seem to work
|
||||||
DialerActivity.instance().setContactAddress(lPhoneNo, lName, pictureUri);
|
DialerActivity.instance().setContactAddress(lPhoneNo, lName, pictureUri);
|
||||||
}
|
}
|
||||||
|
@ -91,4 +77,5 @@ public class ContactPickerActivityOld extends Activity {
|
||||||
LinphoneActivity.instance().getTabHost().setCurrentTabByTag(LinphoneActivity.DIALER_TAB);
|
LinphoneActivity.instance().getTabHost().setCurrentTabByTag(LinphoneActivity.DIALER_TAB);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,13 +19,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
package org.linphone;
|
package org.linphone;
|
||||||
|
|
||||||
import org.linphone.LinphoneManager.NewOutgoingCallUiListener;
|
import org.linphone.LinphoneManager.NewOutgoingCallUiListener;
|
||||||
|
import org.linphone.LinphoneManagerWaitHelper.LinphoneManagerReadyListener;
|
||||||
import org.linphone.LinphoneService.LinphoneGuiListener;
|
import org.linphone.LinphoneService.LinphoneGuiListener;
|
||||||
import org.linphone.core.CallDirection;
|
import org.linphone.core.CallDirection;
|
||||||
|
import org.linphone.core.LinphoneAddress;
|
||||||
import org.linphone.core.LinphoneCall;
|
import org.linphone.core.LinphoneCall;
|
||||||
import org.linphone.core.LinphoneCore;
|
import org.linphone.core.LinphoneCore;
|
||||||
import org.linphone.core.Log;
|
import org.linphone.core.Log;
|
||||||
import org.linphone.core.LinphoneCall.State;
|
import org.linphone.core.LinphoneCall.State;
|
||||||
import org.linphone.mediastream.Version;
|
|
||||||
import org.linphone.ui.AddVideoButton;
|
import org.linphone.ui.AddVideoButton;
|
||||||
import org.linphone.ui.AddressAware;
|
import org.linphone.ui.AddressAware;
|
||||||
import org.linphone.ui.AddressText;
|
import org.linphone.ui.AddressText;
|
||||||
|
@ -35,16 +36,15 @@ import org.linphone.ui.HangCallButton;
|
||||||
import org.linphone.ui.MuteMicButton;
|
import org.linphone.ui.MuteMicButton;
|
||||||
import org.linphone.ui.SpeakerButton;
|
import org.linphone.ui.SpeakerButton;
|
||||||
|
|
||||||
import android.app.AlertDialog;
|
import android.app.Activity;
|
||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.PowerManager;
|
import android.os.PowerManager;
|
||||||
import android.preference.PreferenceManager;
|
import android.view.KeyEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.View.OnClickListener;
|
import android.view.View.OnClickListener;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
@ -62,7 +62,7 @@ import android.widget.Toast;
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class DialerActivity extends LinphoneManagerWaitActivity implements LinphoneGuiListener, NewOutgoingCallUiListener {
|
public class DialerActivity extends Activity implements LinphoneGuiListener, LinphoneManagerReadyListener, NewOutgoingCallUiListener, OnClickListener {
|
||||||
|
|
||||||
private TextView mStatus;
|
private TextView mStatus;
|
||||||
private View mHangup;
|
private View mHangup;
|
||||||
|
@ -81,16 +81,12 @@ public class DialerActivity extends LinphoneManagerWaitActivity implements Linph
|
||||||
private static DialerActivity instance;
|
private static DialerActivity instance;
|
||||||
|
|
||||||
private PowerManager.WakeLock mWakeLock;
|
private PowerManager.WakeLock mWakeLock;
|
||||||
private SharedPreferences mPref;
|
|
||||||
private LinphoneCall mCurrentCall;
|
|
||||||
private boolean useIncallActivity;
|
private boolean useIncallActivity;
|
||||||
private boolean useVideoActivity;
|
private boolean useConferenceActivity;
|
||||||
|
|
||||||
private static final String CURRENT_ADDRESS = "org.linphone.current-address";
|
private static final String CURRENT_ADDRESS = "org.linphone.current-address";
|
||||||
private static final String CURRENT_DISPLAYNAME = "org.linphone.current-displayname";
|
private static final String CURRENT_DISPLAYNAME = "org.linphone.current-displayname";
|
||||||
|
|
||||||
private static final int incomingCallDialogId = 1;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return null if not ready yet
|
* @return null if not ready yet
|
||||||
*/
|
*/
|
||||||
|
@ -98,22 +94,21 @@ public class DialerActivity extends LinphoneManagerWaitActivity implements Linph
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private LinphoneManagerWaitHelper waitHelper;
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
setContentView(R.layout.dialer);
|
setContentView(R.layout.dialer);
|
||||||
|
|
||||||
useIncallActivity = getResources().getBoolean(R.bool.use_incall_activity);
|
useIncallActivity = getResources().getBoolean(R.bool.use_incall_activity);
|
||||||
useVideoActivity = getResources().getBoolean(R.bool.use_video_activity);
|
useConferenceActivity = getResources().getBoolean(R.bool.use_conference_activity);
|
||||||
// Don't use Linphone Manager in the onCreate as it takes time in LinphoneService to initialize it.
|
// Don't use Linphone Manager in the onCreate as it takes time in LinphoneService to initialize it.
|
||||||
|
|
||||||
mPref = PreferenceManager.getDefaultSharedPreferences(this);
|
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
|
||||||
PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE);
|
mWakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK|PowerManager.ON_AFTER_RELEASE,Log.TAG+"#"+getClass().getName());
|
||||||
mWakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK|PowerManager.ON_AFTER_RELEASE,Log.TAG);
|
|
||||||
|
|
||||||
|
|
||||||
mAddress = (AddressText) findViewById(R.id.SipUri);
|
mAddress = (AddressText) findViewById(R.id.SipUri);
|
||||||
mDisplayNameView = (TextView) findViewById(R.id.DisplayNameView);
|
mDisplayNameView = (TextView) findViewById(R.id.DisplayNameView);
|
||||||
((EraseButton) findViewById(R.id.Erase)).setAddressView(mAddress);
|
((EraseButton) findViewById(R.id.Erase)).setAddressWidget(mAddress);
|
||||||
|
|
||||||
|
|
||||||
mCall = (CallButton) findViewById(R.id.Call);
|
mCall = (CallButton) findViewById(R.id.Call);
|
||||||
|
@ -121,6 +116,7 @@ public class DialerActivity extends LinphoneManagerWaitActivity implements Linph
|
||||||
|
|
||||||
|
|
||||||
mCallControlRow = findViewById(R.id.CallControlRow);
|
mCallControlRow = findViewById(R.id.CallControlRow);
|
||||||
|
mCallControlRow.findViewById(R.id.BackToConference).setOnClickListener(this);
|
||||||
mAddressLayout = findViewById(R.id.Addresslayout);
|
mAddressLayout = findViewById(R.id.Addresslayout);
|
||||||
|
|
||||||
mInCallControlRow = findViewById(R.id.IncallControlRow);
|
mInCallControlRow = findViewById(R.id.IncallControlRow);
|
||||||
|
@ -128,15 +124,19 @@ public class DialerActivity extends LinphoneManagerWaitActivity implements Linph
|
||||||
mInCallAddressLayout = findViewById(R.id.IncallAddressLayout);
|
mInCallAddressLayout = findViewById(R.id.IncallAddressLayout);
|
||||||
mInCallAddressLayout.setVisibility(View.GONE);
|
mInCallAddressLayout.setVisibility(View.GONE);
|
||||||
|
|
||||||
if (useIncallActivity) {
|
HangCallButton hang = (HangCallButton) findViewById(R.id.HangUp);
|
||||||
mHangup = findViewById(R.id.HangUp);
|
HangCallButton decline = (HangCallButton) findViewById(R.id.Decline);
|
||||||
|
hang.setTerminateAllCalls(true);
|
||||||
|
decline.setTerminateAllCalls(true);
|
||||||
|
|
||||||
|
if (useConferenceActivity || useIncallActivity) {
|
||||||
|
mHangup = hang;
|
||||||
} else {
|
} else {
|
||||||
mMute = (MuteMicButton) findViewById(R.id.mic_mute_button);
|
mMute = (MuteMicButton) findViewById(R.id.mic_mute_button);
|
||||||
mSpeaker = (SpeakerButton) findViewById(R.id.speaker_button);
|
mSpeaker = (SpeakerButton) findViewById(R.id.speaker_button);
|
||||||
mHangup = findViewById(R.id.Decline);
|
mHangup = decline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
mStatus = (TextView) findViewById(R.id.status_label);
|
mStatus = (TextView) findViewById(R.id.status_label);
|
||||||
|
|
||||||
AddressAware numpad = (AddressAware) findViewById(R.id.Dialer);
|
AddressAware numpad = (AddressAware) findViewById(R.id.Dialer);
|
||||||
|
@ -149,18 +149,19 @@ public class DialerActivity extends LinphoneManagerWaitActivity implements Linph
|
||||||
|
|
||||||
checkIfOutgoingCallIntentReceived();
|
checkIfOutgoingCallIntentReceived();
|
||||||
|
|
||||||
|
waitHelper = new LinphoneManagerWaitHelper(this, this);
|
||||||
|
waitHelper.doManagerDependentOnCreate();
|
||||||
instance = this;
|
instance = this;
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onLinphoneManagerAvailable(LinphoneManager m) {
|
public void onCreateWhenManagerReady() {
|
||||||
LinphoneCore lc = LinphoneManager.getLc();
|
LinphoneCall pendingCall = LinphoneManager.getInstance().getPendingIncomingCall();
|
||||||
if (lc.isIncall()) {
|
if (pendingCall != null) {
|
||||||
if(lc.isInComingInvitePending()) {
|
LinphoneActivity.instance().startIncomingCallActivity(pendingCall);
|
||||||
callPending(lc.getCurrentCall());
|
} else if (LinphoneManager.getLc().isIncall()) {
|
||||||
} else {
|
enterIncallMode();
|
||||||
enterIncallMode(lc);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,17 +222,21 @@ public class DialerActivity extends LinphoneManagerWaitActivity implements Linph
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private void enterIncallMode(LinphoneCore lc) {
|
private void enterIncallMode() {
|
||||||
mDisplayNameView.setText(LinphoneManager.getInstance().extractADisplayName());
|
LinphoneCore lc = LinphoneManager.getLc();
|
||||||
|
LinphoneAddress address = lc.getRemoteAddress();
|
||||||
|
mDisplayNameView.setText(LinphoneManager.extractADisplayName(getResources(), address));
|
||||||
|
|
||||||
// setVolumeControlStream(AudioManager.STREAM_VOICE_CALL);
|
// setVolumeControlStream(AudioManager.STREAM_VOICE_CALL);
|
||||||
|
|
||||||
LinphoneActivity.instance().startProxymitySensor();
|
LinphoneManager.startProximitySensorForActivity(LinphoneActivity.instance());
|
||||||
if (!mWakeLock.isHeld()) mWakeLock.acquire();
|
if (!mWakeLock.isHeld()) mWakeLock.acquire();
|
||||||
|
|
||||||
if (useIncallActivity) {
|
if (useIncallActivity) {
|
||||||
LinphoneActivity.instance().startIncallActivity(
|
LinphoneActivity.instance().startIncallActivity(
|
||||||
mDisplayNameView.getText(), mAddress.getPictureUri());
|
mDisplayNameView.getText(), mAddress.getPictureUri());
|
||||||
|
} else if (useConferenceActivity) {
|
||||||
|
LinphoneActivity.instance().startConferenceActivity();
|
||||||
} else {
|
} else {
|
||||||
loadMicAndSpeakerUiStateFromManager();
|
loadMicAndSpeakerUiStateFromManager();
|
||||||
mCallControlRow.setVisibility(View.GONE);
|
mCallControlRow.setVisibility(View.GONE);
|
||||||
|
@ -247,7 +252,8 @@ public class DialerActivity extends LinphoneManagerWaitActivity implements Linph
|
||||||
|
|
||||||
|
|
||||||
private void updateIncallVideoCallButton() {
|
private void updateIncallVideoCallButton() {
|
||||||
if (useIncallActivity) throw new RuntimeException("Internal error");
|
if (useIncallActivity || useConferenceActivity)
|
||||||
|
throw new RuntimeException("Internal error");
|
||||||
|
|
||||||
boolean prefVideoEnabled = LinphoneManager.getInstance().isVideoEnabled();
|
boolean prefVideoEnabled = LinphoneManager.getInstance().isVideoEnabled();
|
||||||
AddVideoButton mAddVideo = (AddVideoButton) findViewById(R.id.AddVideo);
|
AddVideoButton mAddVideo = (AddVideoButton) findViewById(R.id.AddVideo);
|
||||||
|
@ -262,7 +268,8 @@ public class DialerActivity extends LinphoneManagerWaitActivity implements Linph
|
||||||
|
|
||||||
|
|
||||||
private void loadMicAndSpeakerUiStateFromManager() {
|
private void loadMicAndSpeakerUiStateFromManager() {
|
||||||
if (useIncallActivity) throw new RuntimeException("Internal error"); // only dialer widgets are updated with this
|
if (useIncallActivity || useConferenceActivity)
|
||||||
|
throw new RuntimeException("Internal error"); // only dialer widgets are updated with this
|
||||||
|
|
||||||
mMute.setChecked(LinphoneManager.getLc().isMicMuted());
|
mMute.setChecked(LinphoneManager.getLc().isMicMuted());
|
||||||
mSpeaker.setSpeakerOn(LinphoneManager.getInstance().isSpeakerOn());
|
mSpeaker.setSpeakerOn(LinphoneManager.getInstance().isSpeakerOn());
|
||||||
|
@ -270,14 +277,11 @@ public class DialerActivity extends LinphoneManagerWaitActivity implements Linph
|
||||||
|
|
||||||
|
|
||||||
private void exitCallMode() {
|
private void exitCallMode() {
|
||||||
// Remove dialog if existing
|
|
||||||
try {
|
|
||||||
dismissDialog(incomingCallDialogId);
|
|
||||||
} catch (Throwable e) {/* Exception if never created */}
|
|
||||||
|
|
||||||
if (useIncallActivity) {
|
if (useIncallActivity) {
|
||||||
LinphoneActivity.instance().closeIncallActivity();
|
LinphoneActivity.instance().closeIncallActivity();
|
||||||
} else {
|
} else if(useConferenceActivity) {
|
||||||
|
LinphoneActivity.instance().closeConferenceActivity();
|
||||||
|
}else {
|
||||||
mCallControlRow.setVisibility(View.VISIBLE);
|
mCallControlRow.setVisibility(View.VISIBLE);
|
||||||
mInCallControlRow.setVisibility(View.GONE);
|
mInCallControlRow.setVisibility(View.GONE);
|
||||||
mInCallAddressLayout.setVisibility(View.GONE);
|
mInCallAddressLayout.setVisibility(View.GONE);
|
||||||
|
@ -289,68 +293,18 @@ public class DialerActivity extends LinphoneManagerWaitActivity implements Linph
|
||||||
|
|
||||||
mHangup.setEnabled(false);
|
mHangup.setEnabled(false);
|
||||||
|
|
||||||
|
|
||||||
if (useVideoActivity && LinphoneManager.getLc().isVideoEnabled()) {
|
|
||||||
LinphoneActivity.instance().finishVideoActivity();
|
|
||||||
BandwidthManager.getInstance().setUserRestriction(false);
|
|
||||||
LinphoneManager.getInstance().resetCameraFromPreferences();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mWakeLock.isHeld()) mWakeLock.release();
|
if (mWakeLock.isHeld()) mWakeLock.release();
|
||||||
LinphoneActivity.instance().stopProxymitySensor();
|
LinphoneManager.stopProximitySensorForActivity(LinphoneActivity.instance());
|
||||||
|
|
||||||
setVolumeControlStream(AudioManager.USE_DEFAULT_STREAM_TYPE);
|
setVolumeControlStream(AudioManager.USE_DEFAULT_STREAM_TYPE);
|
||||||
mCall.setEnabled(true);
|
mCall.setEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void callPending(final LinphoneCall call) {
|
|
||||||
showDialog(incomingCallDialogId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPrepareDialog(int id, Dialog dialog) {
|
|
||||||
if (id == incomingCallDialogId) {
|
|
||||||
String from = LinphoneManager.getInstance().extractIncomingRemoteName();
|
|
||||||
String msg = String.format(getString(R.string.incoming_call_dialog_title), from);
|
|
||||||
((AlertDialog) dialog).setMessage(msg);
|
|
||||||
} else {
|
|
||||||
super.onPrepareDialog(id, dialog);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Dialog onCreateDialog(int id) {
|
protected Dialog onCreateDialog(int id) {
|
||||||
if (id == incomingCallDialogId) {
|
if (id == LinphoneManagerWaitHelper.DIALOG_ID) {
|
||||||
View incomingCallView = getLayoutInflater().inflate(R.layout.incoming_call, null);
|
return waitHelper.createWaitDialog();
|
||||||
|
|
||||||
final Dialog dialog = new AlertDialog.Builder(this)
|
|
||||||
.setMessage("")
|
|
||||||
.setCancelable(false)
|
|
||||||
.setView(incomingCallView).create();
|
|
||||||
|
|
||||||
|
|
||||||
((CallButton) incomingCallView.findViewById(R.id.Call)).setExternalClickListener(new OnClickListener() {
|
|
||||||
public void onClick(View v) {
|
|
||||||
dialog.dismiss();
|
|
||||||
if (Version.isVideoCapable()) {
|
|
||||||
LinphoneManager.getInstance().resetCameraFromPreferences();
|
|
||||||
|
|
||||||
// Privacy setting to not share the user camera by default
|
|
||||||
boolean prefVideoEnable = LinphoneManager.getInstance().isVideoEnabled();
|
|
||||||
int key = R.string.pref_video_automatically_share_my_video_key;
|
|
||||||
boolean prefAutoShareMyCamera = mPref.getBoolean(getString(key), false);
|
|
||||||
boolean videoMuted = !(prefVideoEnable && prefAutoShareMyCamera);
|
|
||||||
|
|
||||||
LinphoneManager.getLc().getCurrentCall().enableCamera(prefAutoShareMyCamera);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
((HangCallButton) incomingCallView.findViewById(R.id.Decline)).setExternalClickListener(new OnClickListener() {
|
|
||||||
public void onClick(View v) {dialog.dismiss();}
|
|
||||||
});
|
|
||||||
|
|
||||||
return dialog;
|
|
||||||
} else {
|
} else {
|
||||||
return super.onCreateDialog(id);
|
return super.onCreateDialog(id);
|
||||||
}
|
}
|
||||||
|
@ -405,42 +359,32 @@ public class DialerActivity extends LinphoneManagerWaitActivity implements Linph
|
||||||
|
|
||||||
|
|
||||||
public void onCallStateChanged(LinphoneCall call, State state, String message) {
|
public void onCallStateChanged(LinphoneCall call, State state, String message) {
|
||||||
Log.i("OnCallStateChanged: call=", call, ", state=", state, ", message=", message, ", currentCall=", mCurrentCall);
|
Log.i("OnCallStateChanged: call=", call, ", state=", state, ", message=", message);
|
||||||
LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
|
LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
|
||||||
if (lc==null) {
|
if (lc==null) {
|
||||||
/* we are certainly exiting, ignore then.*/
|
/* we are certainly exiting, ignore then.*/
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state==LinphoneCall.State.OutgoingInit){
|
if (state==State.OutgoingInit){
|
||||||
mCurrentCall=call;
|
enterIncallMode();
|
||||||
call.enableCamera(LinphoneManager.getInstance().shareMyCamera());
|
}else if (state==State.Connected){
|
||||||
enterIncallMode(lc);
|
|
||||||
LinphoneActivity.instance().startOrientationSensor();
|
|
||||||
}else if (state==LinphoneCall.State.IncomingReceived){
|
|
||||||
mCurrentCall=call;
|
|
||||||
callPending(call);
|
|
||||||
call.enableCamera(LinphoneManager.getInstance().shareMyCamera());
|
|
||||||
LinphoneActivity.instance().startOrientationSensor();
|
|
||||||
}else if (state==LinphoneCall.State.Connected){
|
|
||||||
if (call.getDirection() == CallDirection.Incoming) {
|
if (call.getDirection() == CallDirection.Incoming) {
|
||||||
enterIncallMode(lc);
|
enterIncallMode();
|
||||||
}
|
}
|
||||||
}else if (state==LinphoneCall.State.Error){
|
}else if (state==State.Error){
|
||||||
if (lc.getCurrentCall() == null || lc.getCurrentCall()==call){
|
showToast(R.string.call_error, message);
|
||||||
|
if (lc.getCallsNb() == 0){
|
||||||
if (mWakeLock.isHeld()) mWakeLock.release();
|
if (mWakeLock.isHeld()) mWakeLock.release();
|
||||||
showToast(R.string.call_error, message);
|
|
||||||
exitCallMode();
|
exitCallMode();
|
||||||
LinphoneActivity.instance().stopOrientationSensor();
|
|
||||||
mCurrentCall=null;
|
|
||||||
}
|
}
|
||||||
}else if (state==LinphoneCall.State.CallEnd){
|
}else if (state==State.CallEnd){
|
||||||
if (lc.getCurrentCall() == null || lc.getCurrentCall()==call){
|
if (lc.getCallsNb() == 0){
|
||||||
exitCallMode();
|
exitCallMode();
|
||||||
LinphoneActivity.instance().stopOrientationSensor();
|
|
||||||
mCurrentCall=null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateCallControlRow();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showToast(int id, String txt) {
|
private void showToast(int id, String txt) {
|
||||||
|
@ -456,7 +400,7 @@ public class DialerActivity extends LinphoneManagerWaitActivity implements Linph
|
||||||
|
|
||||||
public void onGlobalStateChangedToOn(String message) {
|
public void onGlobalStateChangedToOn(String message) {
|
||||||
mCall.setEnabled(!LinphoneManager.getLc().isIncall());
|
mCall.setEnabled(!LinphoneManager.getLc().isIncall());
|
||||||
if (!useIncallActivity) updateIncallVideoCallButton();
|
if (!useIncallActivity && !useConferenceActivity) updateIncallVideoCallButton();
|
||||||
else mHangup.setEnabled(!mCall.isEnabled());
|
else mHangup.setEnabled(!mCall.isEnabled());
|
||||||
|
|
||||||
if (getIntent().getData() != null) {
|
if (getIntent().getData() != null) {
|
||||||
|
@ -476,17 +420,65 @@ public class DialerActivity extends LinphoneManagerWaitActivity implements Linph
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onResume() {
|
public void onResumeWhenManagerReady() {
|
||||||
|
updateCallControlRow();
|
||||||
|
|
||||||
// When coming back from a video call, if the phone orientation is different
|
// When coming back from a video call, if the phone orientation is different
|
||||||
// Android will destroy the previous Dialer and create a new one.
|
// Android will destroy the previous Dialer and create a new one.
|
||||||
// Unfortunately the "call end" status event is received in the meanwhile
|
// Unfortunately the "call end" status event is received in the meanwhile
|
||||||
// and set to the to be destroyed Dialer.
|
// and set to the to be destroyed Dialer.
|
||||||
// Note1: We wait as long as possible before setting the last message.
|
// Note1: We wait as long as possible before setting the last message.
|
||||||
// Note2: Linphone service is in charge of instantiating LinphoneManager
|
// Note2: Linphone service is in charge of instantiating LinphoneManager
|
||||||
if (LinphoneService.isReady()) {
|
mStatus.setText(LinphoneManager.getInstance().getLastLcStatusMessage());
|
||||||
mStatus.setText(LinphoneManager.getInstance().getLastLcStatusMessage());
|
if (LinphoneManager.getLc().getCallsNb() > 0) {
|
||||||
|
LinphoneManager.startProximitySensorForActivity(LinphoneActivity.instance());
|
||||||
|
// removing is done directly in LinphoneActivity.onPause()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResume() {
|
||||||
|
waitHelper.doManagerDependentOnResume();
|
||||||
super.onResume();
|
super.onResume();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void updateCallControlRow() {
|
||||||
|
if (useConferenceActivity) {
|
||||||
|
if (LinphoneManager.isInstanciated()) {
|
||||||
|
LinphoneCore lc = LinphoneManager.getLc();
|
||||||
|
int calls = lc.getCallsNb();
|
||||||
|
View backToConf = mCallControlRow.findViewById(R.id.BackToConference);
|
||||||
|
View callButton = mCallControlRow.findViewById(R.id.Call);
|
||||||
|
View hangButton = mCallControlRow.findViewById(R.id.Decline);
|
||||||
|
if (calls > 0) {
|
||||||
|
backToConf.setVisibility(View.VISIBLE);
|
||||||
|
callButton.setVisibility(View.GONE);
|
||||||
|
hangButton.setEnabled(true);
|
||||||
|
} else {
|
||||||
|
backToConf.setVisibility(View.GONE);
|
||||||
|
callButton.setVisibility(View.VISIBLE);
|
||||||
|
hangButton.setEnabled(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||||
|
if (LinphoneUtils.onKeyVolumeSoftAdjust(keyCode)) return true;
|
||||||
|
return super.onKeyDown(keyCode, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
switch (v.getId()) {
|
||||||
|
case R.id.BackToConference:
|
||||||
|
LinphoneActivity.instance().startConferenceActivity();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,11 +57,12 @@ public class HistoryActivity extends ListActivity {
|
||||||
super.onListItemClick(l, v, position, id);
|
super.onListItemClick(l, v, position, id);
|
||||||
TextView lFirstLineView = (TextView) v.findViewById(R.id.history_cell_first_line);
|
TextView lFirstLineView = (TextView) v.findViewById(R.id.history_cell_first_line);
|
||||||
TextView lSecondLineView = (TextView) v.findViewById(R.id.history_cell_second_line);
|
TextView lSecondLineView = (TextView) v.findViewById(R.id.history_cell_second_line);
|
||||||
|
ContactPicked parent = (ContactPicked) getParent();
|
||||||
if (lSecondLineView.getVisibility() == View.GONE) {
|
if (lSecondLineView.getVisibility() == View.GONE) {
|
||||||
// no display name
|
// no display name
|
||||||
LinphoneActivity.setAddressAndGoToDialer(lFirstLineView.getText().toString(), null, null);
|
parent.setAddressAndGoToDialer(lFirstLineView.getText().toString(), null, null);
|
||||||
} else {
|
} else {
|
||||||
LinphoneActivity.setAddressAndGoToDialer(
|
parent.setAddressAndGoToDialer(
|
||||||
lSecondLineView.getText().toString(),
|
lSecondLineView.getText().toString(),
|
||||||
lFirstLineView.getText().toString(),
|
lFirstLineView.getText().toString(),
|
||||||
null);
|
null);
|
||||||
|
|
|
@ -23,7 +23,7 @@ import java.util.TimerTask;
|
||||||
|
|
||||||
import org.linphone.ui.HangCallButton;
|
import org.linphone.ui.HangCallButton;
|
||||||
|
|
||||||
import android.content.Intent;
|
import android.app.Activity;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
|
@ -32,7 +32,11 @@ import android.view.View;
|
||||||
import android.view.View.OnClickListener;
|
import android.view.View.OnClickListener;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
public class IncallActivity extends SoftVolumeActivity implements OnClickListener {
|
/**
|
||||||
|
* @author Guillaume Beraudo
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class IncallActivity extends Activity implements OnClickListener {
|
||||||
|
|
||||||
public static final String CONTACT_KEY = "contact";
|
public static final String CONTACT_KEY = "contact";
|
||||||
public static final String PICTURE_URI_KEY = "picture_uri";
|
public static final String PICTURE_URI_KEY = "picture_uri";
|
||||||
|
@ -98,7 +102,7 @@ public class IncallActivity extends SoftVolumeActivity implements OnClickListene
|
||||||
@Override
|
@Override
|
||||||
protected void onResume() {
|
protected void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
|
LinphoneManager.startProximitySensorForActivity(this);
|
||||||
task = new TimerTask() {
|
task = new TimerTask() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
@ -121,6 +125,7 @@ public class IncallActivity extends SoftVolumeActivity implements OnClickListene
|
||||||
@Override
|
@Override
|
||||||
protected void onPause() {
|
protected void onPause() {
|
||||||
super.onPause();
|
super.onPause();
|
||||||
|
LinphoneManager.stopProximitySensorForActivity(this);
|
||||||
|
|
||||||
if (task != null) {
|
if (task != null) {
|
||||||
task.cancel();
|
task.cancel();
|
||||||
|
@ -128,16 +133,15 @@ public class IncallActivity extends SoftVolumeActivity implements OnClickListene
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||||
|
if (LinphoneUtils.onKeyVolumeSoftAdjust(keyCode)) return true;
|
||||||
|
return super.onKeyDown(keyCode, event);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onKeyUp(int keyCode, KeyEvent event) {
|
public boolean onKeyUp(int keyCode, KeyEvent event) {
|
||||||
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
|
if (LinphoneUtils.onKeyBackGoHome(this, keyCode)) return true;
|
||||||
startActivity(new Intent()
|
return super.onKeyUp(keyCode, event);
|
||||||
.setAction(Intent.ACTION_MAIN)
|
|
||||||
.addCategory(Intent.CATEGORY_HOME));
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return super.onKeyUp(keyCode, event);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
176
src/org/linphone/IncomingCallActivity.java
Normal file
|
@ -0,0 +1,176 @@
|
||||||
|
/*
|
||||||
|
IncomingCallActivity.java
|
||||||
|
Copyright (C) 2011 Belledonne Communications, Grenoble, France
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
package org.linphone;
|
||||||
|
|
||||||
|
import org.linphone.LinphoneManagerWaitHelper.LinphoneManagerReadyListener;
|
||||||
|
import org.linphone.LinphoneSimpleListener.LinphoneOnCallStateChangedListener;
|
||||||
|
import org.linphone.core.LinphoneAddress;
|
||||||
|
import org.linphone.core.LinphoneCall;
|
||||||
|
import org.linphone.core.Log;
|
||||||
|
import org.linphone.core.LinphoneCall.State;
|
||||||
|
import org.linphone.ui.SlidingTab;
|
||||||
|
import org.linphone.ui.SlidingTab.OnTriggerListener;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.KeyEvent;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.WindowManager;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Activity displayed when a call comes in.
|
||||||
|
* It should bypass the screen lock mechanism.
|
||||||
|
*
|
||||||
|
* @author Guillaume Beraudo
|
||||||
|
*/
|
||||||
|
public class IncomingCallActivity extends Activity implements LinphoneManagerReadyListener, LinphoneOnCallStateChangedListener, OnTriggerListener {
|
||||||
|
|
||||||
|
private TextView mNameView;
|
||||||
|
private TextView mNumberView;
|
||||||
|
private ImageView mPictureView;
|
||||||
|
private LinphoneCall mCall;
|
||||||
|
private LinphoneManagerWaitHelper mHelper;
|
||||||
|
private SlidingTab mIncomingCallWidget;
|
||||||
|
|
||||||
|
private void findIncomingCall(Intent intent) {
|
||||||
|
String stringUri = intent.getStringExtra("stringUri");
|
||||||
|
mCall = LinphoneManager.getLc().findCallFromUri(stringUri);
|
||||||
|
if (mCall == null) {
|
||||||
|
Log.e("Couldn't find incoming call from ", stringUri);
|
||||||
|
Toast.makeText(this, "Error", Toast.LENGTH_SHORT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
setContentView(R.layout.incoming);
|
||||||
|
|
||||||
|
mNameView = (TextView) findViewById(R.id.incoming_caller_name);
|
||||||
|
mNumberView = (TextView) findViewById(R.id.incoming_caller_number);
|
||||||
|
mPictureView = (ImageView) findViewById(R.id.incoming_picture);
|
||||||
|
|
||||||
|
// set this flag so this activity will stay in front of the keyguard
|
||||||
|
int flags = WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
|
||||||
|
flags |= WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD;
|
||||||
|
getWindow().addFlags(flags);
|
||||||
|
|
||||||
|
|
||||||
|
// "Dial-to-answer" widget for incoming calls.
|
||||||
|
mIncomingCallWidget = (SlidingTab) findViewById(R.id.sliding_widget);
|
||||||
|
|
||||||
|
// For now, we only need to show two states: answer and decline.
|
||||||
|
// TODO: make left hint work
|
||||||
|
// mIncomingCallWidget.setLeftHintText(R.string.slide_to_answer_hint);
|
||||||
|
// mIncomingCallWidget.setRightHintText(R.string.slide_to_decline_hint);
|
||||||
|
|
||||||
|
mIncomingCallWidget.setOnTriggerListener(this);
|
||||||
|
|
||||||
|
|
||||||
|
mHelper = new LinphoneManagerWaitHelper(this, this);
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreateWhenManagerReady() {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResumeWhenManagerReady() {
|
||||||
|
LinphoneManager.addListener(this);
|
||||||
|
findIncomingCall(getIntent());
|
||||||
|
if (mCall == null) {
|
||||||
|
finish();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
LinphoneAddress address = mCall.getRemoteAddress();
|
||||||
|
// May be greatly sped up using a drawable cache
|
||||||
|
Uri uri = LinphoneUtils.findUriPictureOfContactAndSetDisplayName(address, getContentResolver());
|
||||||
|
LinphoneUtils.setImagePictureFromUri(this, mPictureView, uri, R.drawable.unknown_person);
|
||||||
|
|
||||||
|
// To be done after findUriPictureOfContactAndSetDisplayName called
|
||||||
|
mNameView.setText(address.getDisplayName());
|
||||||
|
if (getResources().getBoolean(R.bool.show_full_remote_address_on_incoming_call)) {
|
||||||
|
mNumberView.setText(address.asStringUriOnly());
|
||||||
|
} else {
|
||||||
|
mNumberView.setText(address.getUserName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
mHelper.doManagerDependentOnResume();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPause() {
|
||||||
|
super.onPause();
|
||||||
|
LinphoneManager.removeListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||||
|
if (LinphoneManager.isInstanciated() && (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_HOME)) {
|
||||||
|
LinphoneManager.getLc().terminateCall(mCall);
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
return super.onKeyDown(keyCode, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCallStateChanged(LinphoneCall call, State state, String msg) {
|
||||||
|
if (call == mCall && State.CallEnd == state) {
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void decline() {
|
||||||
|
LinphoneManager.getLc().terminateCall(mCall);
|
||||||
|
}
|
||||||
|
private void answer() {
|
||||||
|
if (!LinphoneManager.getInstance().acceptCall(mCall)) {
|
||||||
|
// the above method takes care of Samsung Galaxy S
|
||||||
|
Toast.makeText(this, R.string.couldnt_accept_call, Toast.LENGTH_LONG);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void onGrabbedStateChange(View v, int grabbedState) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTrigger(View v, int whichHandle) {
|
||||||
|
switch (whichHandle) {
|
||||||
|
case OnTriggerListener.LEFT_HANDLE:
|
||||||
|
answer();
|
||||||
|
finish();
|
||||||
|
break;
|
||||||
|
case OnTriggerListener.RIGHT_HANDLE:
|
||||||
|
decline();
|
||||||
|
finish();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
iLinphoneActivity.java
|
LinphoneActivity.java
|
||||||
Copyright (C) 2010 Belledonne Communications, Grenoble, France
|
Copyright (C) 2010 Belledonne Communications, Grenoble, France
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
This program is free software; you can redistribute it and/or
|
||||||
|
@ -21,12 +21,14 @@ package org.linphone;
|
||||||
|
|
||||||
import static android.content.Intent.ACTION_MAIN;
|
import static android.content.Intent.ACTION_MAIN;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.linphone.LinphoneManager.EcCalibrationListener;
|
import org.linphone.LinphoneManager.EcCalibrationListener;
|
||||||
|
import org.linphone.LinphoneSimpleListener.LinphoneOnCallStateChangedListener;
|
||||||
|
import org.linphone.core.LinphoneAddress;
|
||||||
|
import org.linphone.core.LinphoneCall;
|
||||||
import org.linphone.core.LinphoneCore;
|
import org.linphone.core.LinphoneCore;
|
||||||
import org.linphone.core.LinphoneCoreException;
|
import org.linphone.core.LinphoneCoreException;
|
||||||
import org.linphone.core.Log;
|
import org.linphone.core.Log;
|
||||||
|
import org.linphone.core.LinphoneCall.State;
|
||||||
import org.linphone.core.LinphoneCore.EcCalibratorStatus;
|
import org.linphone.core.LinphoneCore.EcCalibratorStatus;
|
||||||
import org.linphone.core.LinphoneCore.RegistrationState;
|
import org.linphone.core.LinphoneCore.RegistrationState;
|
||||||
import org.linphone.mediastream.Version;
|
import org.linphone.mediastream.Version;
|
||||||
|
@ -51,33 +53,28 @@ import android.text.Html;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuInflater;
|
import android.view.MenuInflater;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
|
||||||
import android.view.WindowManager;
|
|
||||||
import android.widget.FrameLayout;
|
|
||||||
import android.widget.TabWidget;
|
import android.widget.TabWidget;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
import android.widget.TabHost.TabSpec;
|
import android.widget.TabHost.TabSpec;
|
||||||
|
|
||||||
public class LinphoneActivity extends TabActivity implements SensorEventListener {
|
public class LinphoneActivity extends TabActivity implements SensorEventListener, ContactPicked, LinphoneOnCallStateChangedListener {
|
||||||
public static final String DIALER_TAB = "dialer";
|
public static final String DIALER_TAB = "dialer";
|
||||||
public static final String PREF_FIRST_LAUNCH = "pref_first_launch";
|
public static final String PREF_FIRST_LAUNCH = "pref_first_launch";
|
||||||
private static final int video_activity = 100;
|
private static final int video_activity = 100;
|
||||||
static final int FIRST_LOGIN_ACTIVITY = 101;
|
static final int FIRST_LOGIN_ACTIVITY = 101;
|
||||||
static final int INCALL_ACTIVITY = 102;
|
static final int INCALL_ACTIVITY = 102;
|
||||||
static final int INCOMING_CALL_ACTIVITY = 103;
|
static final int INCOMING_CALL_ACTIVITY = 103;
|
||||||
|
private static final int conference_activity = 104;
|
||||||
private static final String PREF_CHECK_CONFIG = "pref_check_config";
|
private static final String PREF_CHECK_CONFIG = "pref_check_config";
|
||||||
|
|
||||||
private static LinphoneActivity instance;
|
private static LinphoneActivity instance;
|
||||||
|
|
||||||
|
|
||||||
private FrameLayout mMainFrame;
|
|
||||||
private SensorManager mSensorManager;
|
private SensorManager mSensorManager;
|
||||||
private Sensor mAccelerometer;
|
private Sensor mAccelerometer;
|
||||||
private int previousRotation = -1;
|
private int previousRotation = -1;
|
||||||
private static SensorEventListener mSensorEventListener;
|
|
||||||
|
|
||||||
private static final String SCREEN_IS_HIDDEN = "screen_is_hidden";
|
|
||||||
private Handler mHandler = new Handler();
|
private Handler mHandler = new Handler();
|
||||||
|
|
||||||
|
|
||||||
|
@ -98,14 +95,9 @@ public class LinphoneActivity extends TabActivity implements SensorEventListener
|
||||||
throw new RuntimeException("LinphoneActivity not instantiated yet");
|
throw new RuntimeException("LinphoneActivity not instantiated yet");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void onSaveInstanceState (Bundle outState) {
|
|
||||||
super.onSaveInstanceState(outState);
|
|
||||||
outState.putBoolean(SCREEN_IS_HIDDEN, mMainFrame.getVisibility() == View.INVISIBLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
instance = this;
|
instance = this;
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.main);
|
setContentView(R.layout.main);
|
||||||
|
|
||||||
LinphonePreferenceManager.getInstance(this);
|
LinphonePreferenceManager.getInstance(this);
|
||||||
|
@ -118,7 +110,6 @@ public class LinphoneActivity extends TabActivity implements SensorEventListener
|
||||||
startService(new Intent(ACTION_MAIN).setClass(this, LinphoneService.class));
|
startService(new Intent(ACTION_MAIN).setClass(this, LinphoneService.class));
|
||||||
|
|
||||||
|
|
||||||
mMainFrame = (FrameLayout) findViewById(R.id.main_frame);
|
|
||||||
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
|
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
|
||||||
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);
|
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);
|
||||||
|
|
||||||
|
@ -139,17 +130,15 @@ public class LinphoneActivity extends TabActivity implements SensorEventListener
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (savedInstanceState !=null && savedInstanceState.getBoolean(SCREEN_IS_HIDDEN,false)) {
|
LinphoneManager.addListener(this);
|
||||||
hideScreen(true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
|
switch (requestCode) {
|
||||||
if (requestCode == FIRST_LOGIN_ACTIVITY) {
|
case FIRST_LOGIN_ACTIVITY:
|
||||||
if (resultCode == RESULT_OK) {
|
if (resultCode == RESULT_OK) {
|
||||||
Toast.makeText(this, getString(R.string.ec_calibration_launch_message), Toast.LENGTH_LONG).show();
|
Toast.makeText(this, getString(R.string.ec_calibration_launch_message), Toast.LENGTH_LONG).show();
|
||||||
try {
|
try {
|
||||||
|
@ -170,6 +159,11 @@ public class LinphoneActivity extends TabActivity implements SensorEventListener
|
||||||
finish();
|
finish();
|
||||||
stopService(new Intent(ACTION_MAIN).setClass(this, LinphoneService.class));
|
stopService(new Intent(ACTION_MAIN).setClass(this, LinphoneService.class));
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case conference_activity:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
super.onActivityResult(requestCode, resultCode, data);
|
super.onActivityResult(requestCode, resultCode, data);
|
||||||
|
@ -217,7 +211,10 @@ public class LinphoneActivity extends TabActivity implements SensorEventListener
|
||||||
gotToDialer();
|
gotToDialer();
|
||||||
} else {
|
} else {
|
||||||
if (getResources().getBoolean(R.bool.use_incall_activity)) {
|
if (getResources().getBoolean(R.bool.use_incall_activity)) {
|
||||||
startIncallActivity(LinphoneManager.getInstance().extractADisplayName(), null);
|
LinphoneAddress address = LinphoneManager.getLc().getRemoteAddress();
|
||||||
|
startIncallActivity(LinphoneManager.extractADisplayName(getResources(), address), null);
|
||||||
|
} if (getResources().getBoolean(R.bool.use_conference_activity)) {
|
||||||
|
startConferenceActivity();
|
||||||
} else {
|
} else {
|
||||||
// TODO
|
// TODO
|
||||||
Log.e("Not handled case: recreation while in call and not using incall activity");
|
Log.e("Not handled case: recreation while in call and not using incall activity");
|
||||||
|
@ -257,11 +254,12 @@ public class LinphoneActivity extends TabActivity implements SensorEventListener
|
||||||
@Override
|
@Override
|
||||||
protected void onPause() {
|
protected void onPause() {
|
||||||
super.onPause();
|
super.onPause();
|
||||||
|
|
||||||
if (isFinishing()) {
|
if (isFinishing()) {
|
||||||
//restore audio settings
|
//restore audio settings
|
||||||
LinphoneManager.getInstance().routeAudioToReceiver();
|
boolean isUserRequest = false;
|
||||||
stopProxymitySensor();//just in case
|
LinphoneManager.getInstance().routeAudioToReceiver(isUserRequest);
|
||||||
|
LinphoneManager.removeListener(this);
|
||||||
|
LinphoneManager.stopProximitySensorForActivity(this);
|
||||||
instance = null;
|
instance = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -318,39 +316,12 @@ public class LinphoneActivity extends TabActivity implements SensorEventListener
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public synchronized void stopOrientationSensor() {
|
||||||
void hideScreen(boolean isHidden) {
|
if (mSensorManager!=null)
|
||||||
WindowManager.LayoutParams lAttrs =getWindow().getAttributes();
|
mSensorManager.unregisterListener(this, mAccelerometer);
|
||||||
if (isHidden) {
|
|
||||||
lAttrs.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
|
|
||||||
mMainFrame.setVisibility(View.INVISIBLE);
|
|
||||||
} else {
|
|
||||||
lAttrs.flags &= (~WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
|
||||||
mMainFrame.setVisibility(View.VISIBLE);
|
|
||||||
}
|
|
||||||
getWindow().setAttributes(lAttrs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized void startProxymitySensor() {
|
|
||||||
if (mSensorEventListener != null) {
|
|
||||||
Log.i("proximity sensor already active");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
List<Sensor> lSensorList = mSensorManager.getSensorList(Sensor.TYPE_PROXIMITY);
|
|
||||||
mSensorEventListener = new SensorEventListener() {
|
|
||||||
public void onSensorChanged(SensorEvent event) {
|
|
||||||
//just ignoring for nexus 1
|
|
||||||
if (event.timestamp == 0) return;
|
|
||||||
instance().hideScreen(LinphoneManager.isProximitySensorNearby(event));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onAccuracyChanged(Sensor sensor, int accuracy) {}
|
|
||||||
};
|
|
||||||
if (lSensorList.size() >0) {
|
|
||||||
mSensorManager.registerListener(mSensorEventListener,lSensorList.get(0),SensorManager.SENSOR_DELAY_UI);
|
|
||||||
Log.i("Proximity sensor detected, registering");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void startOrientationSensor() {
|
public synchronized void startOrientationSensor() {
|
||||||
if (mSensorManager!=null) {
|
if (mSensorManager!=null) {
|
||||||
|
@ -363,20 +334,6 @@ public class LinphoneActivity extends TabActivity implements SensorEventListener
|
||||||
onSensorChanged(null);
|
onSensorChanged(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void stopOrientationSensor() {
|
|
||||||
if (mSensorManager!=null)
|
|
||||||
mSensorManager.unregisterListener(this, mAccelerometer);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected synchronized void stopProxymitySensor() {
|
|
||||||
if (mSensorManager!=null) {
|
|
||||||
mSensorManager.unregisterListener(mSensorEventListener);
|
|
||||||
mSensorEventListener=null;
|
|
||||||
}
|
|
||||||
hideScreen(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void showPreferenceErrorDialog(String message) {
|
void showPreferenceErrorDialog(String message) {
|
||||||
if (!useMenuSettings) {
|
if (!useMenuSettings) {
|
||||||
Toast.makeText(this, message, Toast.LENGTH_LONG);
|
Toast.makeText(this, message, Toast.LENGTH_LONG);
|
||||||
|
@ -471,7 +428,7 @@ public class LinphoneActivity extends TabActivity implements SensorEventListener
|
||||||
builder.create().show();
|
builder.create().show();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setAddressAndGoToDialer(String number, String name, Uri photo) {
|
public void setAddressAndGoToDialer(String number, String name, Uri photo) {
|
||||||
DialerActivity.instance().setContactAddress(number, name, photo);
|
DialerActivity.instance().setContactAddress(number, name, photo);
|
||||||
instance.gotToDialer();
|
instance.gotToDialer();
|
||||||
}
|
}
|
||||||
|
@ -500,9 +457,11 @@ public class LinphoneActivity extends TabActivity implements SensorEventListener
|
||||||
public void closeIncallActivity() {
|
public void closeIncallActivity() {
|
||||||
finishActivity(INCALL_ACTIVITY);
|
finishActivity(INCALL_ACTIVITY);
|
||||||
}
|
}
|
||||||
|
public void closeConferenceActivity() {
|
||||||
|
finishActivity(conference_activity);
|
||||||
|
}
|
||||||
|
|
||||||
public void startVideoActivity() {
|
public void startVideoActivity() {
|
||||||
|
|
||||||
mHandler.post(new Runnable() {
|
mHandler.post(new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
startActivityForResult(new Intent().setClass(
|
startActivityForResult(new Intent().setClass(
|
||||||
|
@ -511,7 +470,30 @@ public class LinphoneActivity extends TabActivity implements SensorEventListener
|
||||||
video_activity);
|
video_activity);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
LinphoneManager.getInstance().routeAudioToSpeaker();
|
boolean isUserRequest = false;
|
||||||
|
LinphoneManager.getInstance().routeAudioToSpeaker(isUserRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startConferenceActivity() {
|
||||||
|
if (ConferenceActivity.active) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mHandler.post(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
startActivityForResult(new Intent().setClass(
|
||||||
|
LinphoneActivity.this,
|
||||||
|
ConferenceActivity.class),
|
||||||
|
conference_activity);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startIncomingCallActivity(LinphoneCall pendingCall) {
|
||||||
|
Intent intent = new Intent()
|
||||||
|
.setClass(this, IncomingCallActivity.class)
|
||||||
|
.putExtra("stringUri", pendingCall.getRemoteAddress().asStringUriOnly());
|
||||||
|
startActivityForResult(intent, INCOMING_CALL_ACTIVITY);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void finishVideoActivity() {
|
public void finishVideoActivity() {
|
||||||
|
@ -521,4 +503,25 @@ public class LinphoneActivity extends TabActivity implements SensorEventListener
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCallStateChanged(LinphoneCall call, State state,
|
||||||
|
String message) {
|
||||||
|
if (state==State.IncomingReceived) {
|
||||||
|
startIncomingCallActivity(call);
|
||||||
|
}
|
||||||
|
if (state==State.OutgoingInit || state==State.IncomingReceived) {
|
||||||
|
startOrientationSensor();
|
||||||
|
} else if (state==State.Error || state==State.CallEnd){
|
||||||
|
stopOrientationSensor();
|
||||||
|
finishActivity(INCOMING_CALL_ACTIVITY);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
interface ContactPicked {
|
||||||
|
void setAddressAndGoToDialer(String number, String name, Uri photo);
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,9 +39,17 @@ import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.Timer;
|
import java.util.Timer;
|
||||||
import java.util.TimerTask;
|
import java.util.TimerTask;
|
||||||
|
|
||||||
|
import org.linphone.LinphoneSimpleListener.LinphoneOnAudioChangedListener;
|
||||||
|
import org.linphone.LinphoneSimpleListener.LinphoneServiceListener;
|
||||||
|
import org.linphone.LinphoneSimpleListener.LinphoneOnAudioChangedListener.AudioState;
|
||||||
|
import org.linphone.core.CallDirection;
|
||||||
import org.linphone.core.LinphoneAddress;
|
import org.linphone.core.LinphoneAddress;
|
||||||
import org.linphone.core.LinphoneAuthInfo;
|
import org.linphone.core.LinphoneAuthInfo;
|
||||||
import org.linphone.core.LinphoneCall;
|
import org.linphone.core.LinphoneCall;
|
||||||
|
@ -66,6 +74,7 @@ import org.linphone.mediastream.video.capture.hwconf.AndroidCameraConfiguration;
|
||||||
import org.linphone.mediastream.video.capture.hwconf.Hacks;
|
import org.linphone.mediastream.video.capture.hwconf.Hacks;
|
||||||
import org.linphone.mediastream.video.capture.hwconf.AndroidCameraConfiguration.AndroidCamera;
|
import org.linphone.mediastream.video.capture.hwconf.AndroidCameraConfiguration.AndroidCamera;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
@ -74,18 +83,25 @@ import android.content.IntentFilter;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.content.SharedPreferences.Editor;
|
import android.content.SharedPreferences.Editor;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
|
import android.hardware.Sensor;
|
||||||
import android.hardware.SensorEvent;
|
import android.hardware.SensorEvent;
|
||||||
|
import android.hardware.SensorEventListener;
|
||||||
|
import android.hardware.SensorManager;
|
||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
||||||
import android.media.MediaPlayer;
|
import android.media.MediaPlayer;
|
||||||
import android.net.ConnectivityManager;
|
import android.net.ConnectivityManager;
|
||||||
import android.net.NetworkInfo;
|
import android.net.NetworkInfo;
|
||||||
import android.os.Build;
|
|
||||||
import android.os.PowerManager;
|
import android.os.PowerManager;
|
||||||
import android.os.Vibrator;
|
import android.os.Vibrator;
|
||||||
import android.os.PowerManager.WakeLock;
|
import android.os.PowerManager.WakeLock;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.provider.Settings.SettingNotFoundException;
|
import android.provider.Settings.SettingNotFoundException;
|
||||||
|
import android.telephony.TelephonyManager;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.view.Window;
|
||||||
|
import android.view.WindowManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -116,6 +132,18 @@ public final class LinphoneManager implements LinphoneCoreListener {
|
||||||
private String basePath;
|
private String basePath;
|
||||||
private static boolean sExited;
|
private static boolean sExited;
|
||||||
|
|
||||||
|
private WakeLock mIncallWakeLock;
|
||||||
|
|
||||||
|
private static List<LinphoneSimpleListener> simpleListeners = new ArrayList<LinphoneSimpleListener>();
|
||||||
|
public static void addListener(LinphoneSimpleListener listener) {
|
||||||
|
if (!simpleListeners.contains(listener)) {
|
||||||
|
simpleListeners.add(listener);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static void removeListener(LinphoneSimpleListener listener) {
|
||||||
|
simpleListeners.remove(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private LinphoneManager(final Context c) {
|
private LinphoneManager(final Context c) {
|
||||||
sExited=false;
|
sExited=false;
|
||||||
|
@ -132,6 +160,8 @@ public final class LinphoneManager implements LinphoneCoreListener {
|
||||||
mPref = PreferenceManager.getDefaultSharedPreferences(c);
|
mPref = PreferenceManager.getDefaultSharedPreferences(c);
|
||||||
mPowerManager = (PowerManager) c.getSystemService(Context.POWER_SERVICE);
|
mPowerManager = (PowerManager) c.getSystemService(Context.POWER_SERVICE);
|
||||||
mR = c.getResources();
|
mR = c.getResources();
|
||||||
|
TelephonyManager tm = (TelephonyManager) c.getSystemService(Context.TELEPHONY_SERVICE);
|
||||||
|
gsmIdle = tm.getCallState() == TelephonyManager.CALL_STATE_IDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final int LINPHONE_VOLUME_STREAM = STREAM_VOICE_CALL;
|
private static final int LINPHONE_VOLUME_STREAM = STREAM_VOICE_CALL;
|
||||||
|
@ -153,6 +183,12 @@ public final class LinphoneManager implements LinphoneCoreListener {
|
||||||
getInstance().routeAudioToSpeakerHelperHelper(speakerOn);
|
getInstance().routeAudioToSpeakerHelperHelper(speakerOn);
|
||||||
}
|
}
|
||||||
private void routeAudioToSpeakerHelperHelper(boolean speakerOn) {
|
private void routeAudioToSpeakerHelperHelper(boolean speakerOn) {
|
||||||
|
boolean different = isSpeakerOn() ^ speakerOn;
|
||||||
|
if (!different) {
|
||||||
|
Log.d("Skipping change audio route by the same route ",
|
||||||
|
speakerOn ? "speaker" : "earpiece");
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (Hacks.needGalaxySAudioHack() || lpm.useGalaxySHack())
|
if (Hacks.needGalaxySAudioHack() || lpm.useGalaxySHack())
|
||||||
setAudioModeIncallForGalaxyS();
|
setAudioModeIncallForGalaxyS();
|
||||||
|
|
||||||
|
@ -167,6 +203,9 @@ public final class LinphoneManager implements LinphoneCoreListener {
|
||||||
} else {
|
} else {
|
||||||
mAudioManager.setSpeakerphoneOn(speakerOn);
|
mAudioManager.setSpeakerphoneOn(speakerOn);
|
||||||
}
|
}
|
||||||
|
for (LinphoneOnAudioChangedListener listener : getSimpleListeners(LinphoneOnAudioChangedListener.class)) {
|
||||||
|
listener.onAudioStateChanged(speakerOn ? AudioState.SPEAKER : AudioState.EARPIECE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
private synchronized void routeAudioToSpeakerHelper(boolean speakerOn) {
|
private synchronized void routeAudioToSpeakerHelper(boolean speakerOn) {
|
||||||
final LinphoneCall call = mLc.getCurrentCall();
|
final LinphoneCall call = mLc.getCurrentCall();
|
||||||
|
@ -178,8 +217,24 @@ public final class LinphoneManager implements LinphoneCoreListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean sUserRequestedSpeaker;
|
||||||
|
public static final boolean isUserRequestedSpeaker() {return sUserRequestedSpeaker;}
|
||||||
|
|
||||||
public void routeAudioToSpeaker() {
|
public void restoreUserRequestedSpeaker() {
|
||||||
|
if (sUserRequestedSpeaker) {
|
||||||
|
routeAudioToSpeaker(false);
|
||||||
|
} else {
|
||||||
|
routeAudioToReceiver(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param isUserRequest true if the setting is permanent, otherwise it can be lost
|
||||||
|
* eg: video activity imply speaker on, which is not a request from the user.
|
||||||
|
* when the activity stops, the sound is routed to the previously user requested route.
|
||||||
|
*/
|
||||||
|
public void routeAudioToSpeaker(boolean isUserRequest) {
|
||||||
|
if (isUserRequest) sUserRequestedSpeaker = true;
|
||||||
routeAudioToSpeakerHelper(true);
|
routeAudioToSpeakerHelper(true);
|
||||||
if (mLc.isIncall()) {
|
if (mLc.isIncall()) {
|
||||||
/*disable EC, it is not efficient enough on speaker mode due to bad quality of speakers and saturation*/
|
/*disable EC, it is not efficient enough on speaker mode due to bad quality of speakers and saturation*/
|
||||||
|
@ -190,7 +245,14 @@ public final class LinphoneManager implements LinphoneCoreListener {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void routeAudioToReceiver() {
|
/**
|
||||||
|
*
|
||||||
|
* @param isUserRequest true if the setting is permanent, otherwise it can be lost
|
||||||
|
* eg: video activity imply speaker on, which is not a request from the user.
|
||||||
|
* when the activity stops, the sound is routed to the previously user requested route.
|
||||||
|
*/
|
||||||
|
public void routeAudioToReceiver(boolean isUserRequest) {
|
||||||
|
if (isUserRequest) sUserRequestedSpeaker = false;
|
||||||
routeAudioToSpeakerHelper(false);
|
routeAudioToSpeakerHelper(false);
|
||||||
if (mLc.isIncall()) {
|
if (mLc.isIncall()) {
|
||||||
//Restore default value
|
//Restore default value
|
||||||
|
@ -210,7 +272,7 @@ public final class LinphoneManager implements LinphoneCoreListener {
|
||||||
throw new RuntimeException("Linphone Manager is already initialized");
|
throw new RuntimeException("Linphone Manager is already initialized");
|
||||||
|
|
||||||
instance = new LinphoneManager(c);
|
instance = new LinphoneManager(c);
|
||||||
instance.serviceListener = listener;
|
instance.listenerDispatcher.setServiceListener(listener);
|
||||||
instance.startLibLinphone(c);
|
instance.startLibLinphone(c);
|
||||||
|
|
||||||
if (Version.isVideoCapable())
|
if (Version.isVideoCapable())
|
||||||
|
@ -236,23 +298,26 @@ public final class LinphoneManager implements LinphoneCoreListener {
|
||||||
|
|
||||||
|
|
||||||
public boolean isSpeakerOn() {
|
public boolean isSpeakerOn() {
|
||||||
return (Integer.parseInt(Build.VERSION.SDK) <=4 && mAudioManager.getRouting(MODE_NORMAL) == ROUTE_SPEAKER)
|
if (Hacks.needRoutingAPI() || lpm.useAudioRoutingAPIHack()) {
|
||||||
|| Integer.parseInt(Build.VERSION.SDK) >4 &&mAudioManager.isSpeakerphoneOn();
|
return mAudioManager.getRouting(MODE_NORMAL) == ROUTE_SPEAKER;
|
||||||
|
} else {
|
||||||
|
return mAudioManager.isSpeakerphoneOn();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void newOutgoingCall(AddressType address) {
|
public void newOutgoingCall(AddressType address) {
|
||||||
String to = address.getText().toString();
|
String to = address.getText().toString();
|
||||||
|
|
||||||
if (mLc.isIncall()) {
|
// if (mLc.isIncall()) {
|
||||||
serviceListener.tryingNewOutgoingCallButAlreadyInCall();
|
// listenerDispatcher.tryingNewOutgoingCallButAlreadyInCall();
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
LinphoneAddress lAddress;
|
LinphoneAddress lAddress;
|
||||||
try {
|
try {
|
||||||
lAddress = mLc.interpretUrl(to);
|
lAddress = mLc.interpretUrl(to);
|
||||||
} catch (LinphoneCoreException e) {
|
} catch (LinphoneCoreException e) {
|
||||||
serviceListener.tryingNewOutgoingCallButWrongDestinationAddress();
|
listenerDispatcher.tryingNewOutgoingCallButWrongDestinationAddress();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
lAddress.setDisplayName(address.getDisplayedName());
|
lAddress.setDisplayName(address.getDisplayedName());
|
||||||
|
@ -269,7 +334,7 @@ public final class LinphoneManager implements LinphoneCoreListener {
|
||||||
|
|
||||||
|
|
||||||
} catch (LinphoneCoreException e) {
|
} catch (LinphoneCoreException e) {
|
||||||
serviceListener.tryingNewOutgoingCallButCannotGetCallParameters();
|
listenerDispatcher.tryingNewOutgoingCallButCannotGetCallParameters();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -646,25 +711,11 @@ public final class LinphoneManager implements LinphoneCoreListener {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public interface LinphoneServiceListener {
|
|
||||||
void onGlobalStateChanged(GlobalState state, String message);
|
|
||||||
void tryingNewOutgoingCallButCannotGetCallParameters();
|
|
||||||
void tryingNewOutgoingCallButWrongDestinationAddress();
|
|
||||||
void tryingNewOutgoingCallButAlreadyInCall();
|
|
||||||
void onRegistrationStateChanged(RegistrationState state, String message);
|
|
||||||
void onCallStateChanged(LinphoneCall call, State state, String message);
|
|
||||||
void onRingerPlayerCreated(MediaPlayer mRingerPlayer);
|
|
||||||
void onDisplayStatus(String message);
|
|
||||||
void onAlreadyInVideoCall();
|
|
||||||
void onCallEncryptionChanged(LinphoneCall call, boolean encrypted,
|
|
||||||
String authenticationToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface EcCalibrationListener {
|
public interface EcCalibrationListener {
|
||||||
void onEcCalibrationStatus(EcCalibratorStatus status, int delayMs);
|
void onEcCalibrationStatus(EcCalibratorStatus status, int delayMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
private LinphoneServiceListener serviceListener;
|
private ListenerDispatcher listenerDispatcher = new ListenerDispatcher();
|
||||||
private LinphoneCall ringingCall;
|
private LinphoneCall ringingCall;
|
||||||
|
|
||||||
private MediaPlayer mRingerPlayer;
|
private MediaPlayer mRingerPlayer;
|
||||||
|
@ -689,35 +740,37 @@ public final class LinphoneManager implements LinphoneCoreListener {
|
||||||
public void displayStatus(final LinphoneCore lc, final String message) {
|
public void displayStatus(final LinphoneCore lc, final String message) {
|
||||||
Log.i(message);
|
Log.i(message);
|
||||||
lastLcStatusMessage=message;
|
lastLcStatusMessage=message;
|
||||||
serviceListener.onDisplayStatus(message);
|
listenerDispatcher.onDisplayStatus(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void globalState(final LinphoneCore lc, final LinphoneCore.GlobalState state, final String message) {
|
public void globalState(final LinphoneCore lc, final LinphoneCore.GlobalState state, final String message) {
|
||||||
Log.i("new state [",state,"]");
|
Log.i("new state [",state,"]");
|
||||||
serviceListener.onGlobalStateChanged(state, message);
|
listenerDispatcher.onGlobalStateChanged(state, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void registrationState(final LinphoneCore lc, final LinphoneProxyConfig cfg,final LinphoneCore.RegistrationState state,final String message) {
|
public void registrationState(final LinphoneCore lc, final LinphoneProxyConfig cfg,final LinphoneCore.RegistrationState state,final String message) {
|
||||||
Log.i("new state ["+state+"]");
|
Log.i("new state ["+state+"]");
|
||||||
serviceListener.onRegistrationStateChanged(state, message);
|
listenerDispatcher.onRegistrationStateChanged(state, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean gsmIdle;
|
||||||
public void callState(final LinphoneCore lc,final LinphoneCall call, final State state, final String message) {
|
public void callState(final LinphoneCore lc,final LinphoneCall call, final State state, final String message) {
|
||||||
Log.i("new state [",state,"]");
|
Log.i("new state [",state,"]");
|
||||||
if (state == IncomingReceived && !call.equals(lc.getCurrentCall())) {
|
if (state == IncomingReceived && !call.equals(lc.getCurrentCall())) {
|
||||||
if (call.getReplacedCall()==null){
|
if (call.getReplacedCall()!=null){
|
||||||
//no multicall support, just decline
|
// attended transfer
|
||||||
lc.terminateCall(call);
|
// it will be accepted automatically.
|
||||||
}//otherwise it will be accepted automatically.
|
return;
|
||||||
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state == IncomingReceived) {
|
if (state == IncomingReceived) {
|
||||||
|
if (!gsmIdle) {
|
||||||
|
mLc.terminateCall(call);
|
||||||
|
}
|
||||||
// Brighten screen for at least 10 seconds
|
// Brighten screen for at least 10 seconds
|
||||||
WakeLock wl = mPowerManager.newWakeLock(
|
WakeLock wl = mPowerManager.newWakeLock(
|
||||||
PowerManager.ACQUIRE_CAUSES_WAKEUP
|
PowerManager.ACQUIRE_CAUSES_WAKEUP
|
||||||
|
@ -726,13 +779,14 @@ public final class LinphoneManager implements LinphoneCoreListener {
|
||||||
"incoming_call");
|
"incoming_call");
|
||||||
wl.acquire(10000);
|
wl.acquire(10000);
|
||||||
|
|
||||||
startRinging();
|
if (mLc.getCallsNb() == 1) {
|
||||||
ringingCall = call;
|
ringingCall = call;
|
||||||
} else if (call == ringingCall) {
|
startRinging();
|
||||||
|
// otherwise there is the beep
|
||||||
|
}
|
||||||
|
} else if (call == ringingCall && isRinging) {
|
||||||
//previous state was ringing, so stop ringing
|
//previous state was ringing, so stop ringing
|
||||||
stopRinging();
|
stopRinging();
|
||||||
ringingCall = null;
|
|
||||||
routeAudioToReceiver();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state == CallEnd || state == Error) {
|
if (state == CallEnd || state == Error) {
|
||||||
|
@ -745,12 +799,33 @@ public final class LinphoneManager implements LinphoneCoreListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
serviceListener.onCallStateChanged(call, state, message);
|
if (state == CallEnd) {
|
||||||
|
if (mLc.getCallsNb() == 0) {
|
||||||
|
if (mIncallWakeLock != null && mIncallWakeLock.isHeld()) {
|
||||||
|
mIncallWakeLock.release();
|
||||||
|
Log.i("Last call ended: releasing incall (CPU only) wake lock");
|
||||||
|
} else {
|
||||||
|
Log.i("Last call ended: no incall (CPU only) wake lock were held");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (state == State.StreamsRunning) {
|
||||||
|
if (mIncallWakeLock == null) {
|
||||||
|
mIncallWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "incall");
|
||||||
|
}
|
||||||
|
if (!mIncallWakeLock.isHeld()) {
|
||||||
|
Log.i("New call active : acquiring incall (CPU only) wake lock");
|
||||||
|
mIncallWakeLock.acquire();
|
||||||
|
} else {
|
||||||
|
Log.i("New call active while incall (CPU only) wake lock already active");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
listenerDispatcher.onCallStateChanged(call, state, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void callEncryptionChanged(LinphoneCore lc, LinphoneCall call,
|
public void callEncryptionChanged(LinphoneCore lc, LinphoneCall call,
|
||||||
boolean encrypted, String authenticationToken) {
|
boolean encrypted, String authenticationToken) {
|
||||||
serviceListener.onCallEncryptionChanged(call, encrypted, authenticationToken);
|
listenerDispatcher.onCallEncryptionChanged(call, encrypted, authenticationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ecCalibrationStatus(final LinphoneCore lc,final EcCalibratorStatus status, final int delayMs,
|
public void ecCalibrationStatus(final LinphoneCore lc,final EcCalibratorStatus status, final int delayMs,
|
||||||
|
@ -779,6 +854,7 @@ public final class LinphoneManager implements LinphoneCoreListener {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private boolean isRinging;
|
||||||
private synchronized void startRinging() {
|
private synchronized void startRinging() {
|
||||||
if (Hacks.needGalaxySAudioHack()) {
|
if (Hacks.needGalaxySAudioHack()) {
|
||||||
mAudioManager.setMode(MODE_RINGTONE);
|
mAudioManager.setMode(MODE_RINGTONE);
|
||||||
|
@ -792,7 +868,7 @@ public final class LinphoneManager implements LinphoneCoreListener {
|
||||||
if (mRingerPlayer == null) {
|
if (mRingerPlayer == null) {
|
||||||
mRingerPlayer = new MediaPlayer();
|
mRingerPlayer = new MediaPlayer();
|
||||||
mRingerPlayer.setAudioStreamType(STREAM_RING);
|
mRingerPlayer.setAudioStreamType(STREAM_RING);
|
||||||
serviceListener.onRingerPlayerCreated(mRingerPlayer);
|
listenerDispatcher.onRingerPlayerCreated(mRingerPlayer);
|
||||||
mRingerPlayer.prepare();
|
mRingerPlayer.prepare();
|
||||||
mRingerPlayer.setLooping(true);
|
mRingerPlayer.setLooping(true);
|
||||||
mRingerPlayer.start();
|
mRingerPlayer.start();
|
||||||
|
@ -802,7 +878,7 @@ public final class LinphoneManager implements LinphoneCoreListener {
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.e(e,"cannot handle incoming call");
|
Log.e(e,"cannot handle incoming call");
|
||||||
}
|
}
|
||||||
|
isRinging = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void stopRinging() {
|
private synchronized void stopRinging() {
|
||||||
|
@ -815,25 +891,27 @@ public final class LinphoneManager implements LinphoneCoreListener {
|
||||||
mVibrator.cancel();
|
mVibrator.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isRinging = false;
|
||||||
// You may need to call galaxys audio hack after this method
|
// You may need to call galaxys audio hack after this method
|
||||||
|
boolean isUserRequest = false;
|
||||||
|
routeAudioToReceiver(isUserRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public String extractADisplayName() {
|
public static String extractADisplayName(Resources r, LinphoneAddress address) {
|
||||||
final LinphoneAddress remote = mLc.getRemoteAddress();
|
if (address == null) return r.getString(R.string.unknown_incoming_call_name);
|
||||||
if (remote == null) return mR.getString(R.string.unknown_incoming_call_name);
|
|
||||||
|
|
||||||
final String displayName = remote.getDisplayName();
|
final String displayName = address.getDisplayName();
|
||||||
if (displayName!=null) {
|
if (displayName!=null) {
|
||||||
return displayName;
|
return displayName;
|
||||||
} else if (remote.getUserName() != null){
|
} else if (address.getUserName() != null){
|
||||||
return remote.getUserName();
|
return address.getUserName();
|
||||||
} else {
|
} else {
|
||||||
String rms = remote.toString();
|
String rms = address.toString();
|
||||||
if (rms != null && rms.length() > 1)
|
if (rms != null && rms.length() > 1)
|
||||||
return rms;
|
return rms;
|
||||||
|
|
||||||
return mR.getString(R.string.unknown_incoming_call_name);
|
return r.getString(R.string.unknown_incoming_call_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -846,13 +924,11 @@ public final class LinphoneManager implements LinphoneCoreListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean shareMyCamera() {
|
public boolean shareMyCamera() {
|
||||||
return mPref.getBoolean(getString(R.string.pref_video_automatically_share_my_video_key), false);
|
return isVideoEnabled() && mPref.getBoolean(getString(R.string.pref_video_automatically_share_my_video_key), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAudioModeIncallForGalaxyS() {
|
public void setAudioModeIncallForGalaxyS() {
|
||||||
stopRinging();
|
|
||||||
mAudioManager.setMode(MODE_IN_CALL);
|
mAudioManager.setMode(MODE_IN_CALL);
|
||||||
ringingCall = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called on first launch only
|
// Called on first launch only
|
||||||
|
@ -884,11 +960,15 @@ public final class LinphoneManager implements LinphoneCoreListener {
|
||||||
e.commit();
|
e.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addVideo() {
|
private LinphoneCall requestedVideoCall;
|
||||||
if (!LinphoneManager.getLc().isIncall()) return;
|
public boolean addVideo() {
|
||||||
|
requestedVideoCall = mLc.getCurrentCall();
|
||||||
|
if (requestedVideoCall == null) return false;
|
||||||
|
|
||||||
if (!reinviteWithVideo()) {
|
if (!reinviteWithVideo()) {
|
||||||
serviceListener.onAlreadyInVideoCall();
|
listenerDispatcher.onAlreadyInVideoCall();
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean acceptCallIfIncomingPending() throws LinphoneCoreException {
|
public boolean acceptCallIfIncomingPending() throws LinphoneCoreException {
|
||||||
|
@ -902,15 +982,27 @@ public final class LinphoneManager implements LinphoneCoreListener {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String extractIncomingRemoteName() {
|
public boolean acceptCall(LinphoneCall call) {
|
||||||
if (!mR.getBoolean(R.bool.show_full_remote_address_on_incoming_call))
|
if (Hacks.needGalaxySAudioHack() || lpm.useGalaxySHack())
|
||||||
return extractADisplayName();
|
setAudioModeIncallForGalaxyS();
|
||||||
|
|
||||||
LinphoneAddress remote = mLc.getRemoteAddress();
|
try {
|
||||||
if (remote != null)
|
mLc.acceptCall(call);
|
||||||
return remote.toString();
|
return true;
|
||||||
|
} catch (LinphoneCoreException e) {
|
||||||
|
Log.i(e, "Accept call failed");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return mR.getString(R.string.unknown_incoming_call_name);
|
public static String extractIncomingRemoteName(Resources r, LinphoneAddress linphoneAddress) {
|
||||||
|
if (!r.getBoolean(R.bool.show_full_remote_address_on_incoming_call))
|
||||||
|
return extractADisplayName(r, linphoneAddress);
|
||||||
|
|
||||||
|
if (linphoneAddress != null)
|
||||||
|
return linphoneAddress.asStringUriOnly();
|
||||||
|
|
||||||
|
return r.getString(R.string.unknown_incoming_call_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void adjustSoftwareVolume(int i) {
|
public void adjustSoftwareVolume(int i) {
|
||||||
|
@ -938,6 +1030,79 @@ public final class LinphoneManager implements LinphoneCoreListener {
|
||||||
|
|
||||||
return distanceInCm < threshold;
|
return distanceInCm < threshold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static boolean sLastProximitySensorValueNearby;
|
||||||
|
private static Set<Activity> sProximityDependentActivities = new HashSet<Activity>();
|
||||||
|
private static SensorEventListener sProximitySensorListener = new SensorEventListener() {
|
||||||
|
@Override
|
||||||
|
public void onSensorChanged(SensorEvent event) {
|
||||||
|
if (event.timestamp == 0) return; //just ignoring for nexus 1
|
||||||
|
sLastProximitySensorValueNearby = isProximitySensorNearby(event);
|
||||||
|
proximityNearbyChanged();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void onAccuracyChanged(Sensor sensor, int accuracy) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
private static void hideActivityViewAsIfProximitySensorNearby(Activity activity) {
|
||||||
|
final Window window = activity.getWindow();
|
||||||
|
View view = ((ViewGroup) window.getDecorView().findViewById(android.R.id.content)).getChildAt(0);
|
||||||
|
WindowManager.LayoutParams lAttrs = activity.getWindow().getAttributes();
|
||||||
|
lAttrs.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
|
||||||
|
view.setVisibility(View.INVISIBLE);
|
||||||
|
window.setAttributes(lAttrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void proximityNearbyChanged() {
|
||||||
|
boolean nearby = sLastProximitySensorValueNearby;
|
||||||
|
for (Activity activity : sProximityDependentActivities) {
|
||||||
|
final Window window = activity.getWindow();
|
||||||
|
WindowManager.LayoutParams lAttrs = activity.getWindow().getAttributes();
|
||||||
|
View view = ((ViewGroup) window.getDecorView().findViewById(android.R.id.content)).getChildAt(0);
|
||||||
|
if (nearby) {
|
||||||
|
lAttrs.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
|
||||||
|
view.setVisibility(View.INVISIBLE);
|
||||||
|
} else {
|
||||||
|
lAttrs.flags &= (~WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||||
|
view.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
window.setAttributes(lAttrs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static synchronized void startProximitySensorForActivity(Activity activity) {
|
||||||
|
if (sProximityDependentActivities.contains(activity)) {
|
||||||
|
Log.i("proximity sensor already active for " + activity.getLocalClassName());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sProximityDependentActivities.isEmpty()) {
|
||||||
|
SensorManager sm = (SensorManager) activity.getSystemService(Context.SENSOR_SERVICE);
|
||||||
|
Sensor s = sm.getDefaultSensor(Sensor.TYPE_PROXIMITY);
|
||||||
|
if (s != null) {
|
||||||
|
sm.registerListener(sProximitySensorListener,s,SensorManager.SENSOR_DELAY_UI);
|
||||||
|
Log.i("Proximity sensor detected, registering");
|
||||||
|
}
|
||||||
|
} else if (sLastProximitySensorValueNearby){
|
||||||
|
hideActivityViewAsIfProximitySensorNearby(activity);
|
||||||
|
}
|
||||||
|
|
||||||
|
sProximityDependentActivities.add(activity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static synchronized void stopProximitySensorForActivity(Activity activity) {
|
||||||
|
sProximityDependentActivities.remove(activity);
|
||||||
|
if (sProximityDependentActivities.isEmpty()) {
|
||||||
|
SensorManager sm = (SensorManager) activity.getSystemService(Context.SENSOR_SERVICE);
|
||||||
|
sm.unregisterListener(sProximitySensorListener);
|
||||||
|
sLastProximitySensorValueNearby = false;
|
||||||
|
proximityNearbyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static synchronized LinphoneCore getLcIfManagerNotDestroyedOrNull() {
|
public static synchronized LinphoneCore getLcIfManagerNotDestroyedOrNull() {
|
||||||
if (sExited) {
|
if (sExited) {
|
||||||
// Can occur if the UI thread play a posted event but in the meantime the LinphoneManager was destroyed
|
// Can occur if the UI thread play a posted event but in the meantime the LinphoneManager was destroyed
|
||||||
|
@ -948,4 +1113,98 @@ public final class LinphoneManager implements LinphoneCoreListener {
|
||||||
return getLc();
|
return getLc();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private <T> List<T> getSimpleListeners(Class<T> clazz) {
|
||||||
|
List<T> list = new ArrayList<T>();
|
||||||
|
for (LinphoneSimpleListener l : simpleListeners) {
|
||||||
|
if (clazz.isInstance(l)) list.add((T) l);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ListenerDispatcher implements LinphoneServiceListener {
|
||||||
|
private LinphoneServiceListener serviceListener;
|
||||||
|
|
||||||
|
public void setServiceListener(LinphoneServiceListener s) {
|
||||||
|
this.serviceListener = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onAlreadyInVideoCall() {
|
||||||
|
if (serviceListener != null) serviceListener.onAlreadyInVideoCall();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onCallEncryptionChanged(LinphoneCall call,
|
||||||
|
boolean encrypted, String authenticationToken) {
|
||||||
|
if (serviceListener != null) serviceListener.onCallEncryptionChanged(call, encrypted, authenticationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onCallStateChanged(LinphoneCall call, State state,
|
||||||
|
String message) {
|
||||||
|
if (state==State.OutgoingInit || state==State.IncomingReceived) {
|
||||||
|
boolean sendCamera = shareMyCamera() && mLc.getConferenceSize() == 0;
|
||||||
|
call.enableCamera(sendCamera);
|
||||||
|
}
|
||||||
|
if (state == State.CallEnd && call == requestedVideoCall) {
|
||||||
|
requestedVideoCall = null; // drop reference
|
||||||
|
}
|
||||||
|
if (state == State.CallEnd && mLc.getCallsNb() == 0) {
|
||||||
|
routeAudioToReceiver(true);
|
||||||
|
}
|
||||||
|
if (state == State.StreamsRunning && call == requestedVideoCall && call.getCurrentParamsCopy().getVideoEnabled()) {
|
||||||
|
for (LinphoneOnVideoCallReadyListener l : getSimpleListeners(LinphoneOnVideoCallReadyListener.class)) {
|
||||||
|
l.onRequestedVideoCallReady(call);
|
||||||
|
}
|
||||||
|
requestedVideoCall = null;
|
||||||
|
}
|
||||||
|
if (serviceListener != null) serviceListener.onCallStateChanged(call, state, message);
|
||||||
|
for (LinphoneOnCallStateChangedListener l : getSimpleListeners(LinphoneOnCallStateChangedListener.class)) {
|
||||||
|
l.onCallStateChanged(call, state, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onDisplayStatus(String message) {
|
||||||
|
if (serviceListener != null) serviceListener.onDisplayStatus(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onGlobalStateChanged(GlobalState state, String message) {
|
||||||
|
if (serviceListener != null) serviceListener.onGlobalStateChanged( state, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onRegistrationStateChanged(RegistrationState state,
|
||||||
|
String message) {
|
||||||
|
if (serviceListener != null) serviceListener.onRegistrationStateChanged(state, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onRingerPlayerCreated(MediaPlayer mRingerPlayer) {
|
||||||
|
if (serviceListener != null) serviceListener.onRingerPlayerCreated(mRingerPlayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void tryingNewOutgoingCallButAlreadyInCall() {
|
||||||
|
if (serviceListener != null) serviceListener.tryingNewOutgoingCallButAlreadyInCall();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void tryingNewOutgoingCallButCannotGetCallParameters() {
|
||||||
|
if (serviceListener != null) serviceListener.tryingNewOutgoingCallButCannotGetCallParameters();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void tryingNewOutgoingCallButWrongDestinationAddress() {
|
||||||
|
if (serviceListener != null) serviceListener.tryingNewOutgoingCallButWrongDestinationAddress();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final boolean isInstanciated() {
|
||||||
|
return instance != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized LinphoneCall getPendingIncomingCall() {
|
||||||
|
LinphoneCall currentCall = mLc.getCurrentCall();
|
||||||
|
if (currentCall == null) return null;
|
||||||
|
|
||||||
|
LinphoneCall.State state = currentCall.getState();
|
||||||
|
boolean incomingPending = currentCall.getDirection() == CallDirection.Incoming
|
||||||
|
&& (state == State.IncomingReceived || state == State.CallIncomingEarlyMedia);
|
||||||
|
|
||||||
|
return incomingPending ? currentCall : null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,103 +0,0 @@
|
||||||
/*
|
|
||||||
LinphoneManagerWaitActivity.java
|
|
||||||
Copyright (C) 2011 Belledonne Communications, Grenoble, France
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU General Public License
|
|
||||||
as published by the Free Software Foundation; either version 2
|
|
||||||
of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
*/
|
|
||||||
package org.linphone;
|
|
||||||
|
|
||||||
import org.linphone.core.Log;
|
|
||||||
|
|
||||||
import android.app.AlertDialog;
|
|
||||||
import android.app.Dialog;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.os.Handler;
|
|
||||||
import android.view.View;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Activity requiring access to LinphoneManager should inherit from this class.
|
|
||||||
*
|
|
||||||
* @author Guillaume Beraudo
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public abstract class LinphoneManagerWaitActivity extends SoftVolumeActivity {
|
|
||||||
|
|
||||||
private final int waitServiceDialogId = 314159265;
|
|
||||||
private Handler mHandler = new Handler();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
|
|
||||||
if (LinphoneService.isReady()) {
|
|
||||||
onLinphoneManagerAvailable(LinphoneManager.getInstance());
|
|
||||||
} else {
|
|
||||||
showDialog(waitServiceDialogId);
|
|
||||||
thread = new ServiceWaitThread();
|
|
||||||
thread.start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private ServiceWaitThread thread;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onDestroy() {
|
|
||||||
if (thread != null) thread.interrupt();
|
|
||||||
super.onDestroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Dialog onCreateDialog(int id) {
|
|
||||||
if (id == waitServiceDialogId) {
|
|
||||||
View v = getLayoutInflater().inflate((R.layout.wait_service_dialog), null);
|
|
||||||
return new AlertDialog.Builder(this).setView(v).setCancelable(false).create();
|
|
||||||
}
|
|
||||||
return super.onCreateDialog(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract void onLinphoneManagerAvailable(LinphoneManager m);
|
|
||||||
|
|
||||||
private void dismissDialogFromThread(final int id) {
|
|
||||||
mHandler.post(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
dismissDialog(id);
|
|
||||||
} catch (Throwable e) {
|
|
||||||
// Discarding exception which may be thrown if the dialog wasn't showing.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private class ServiceWaitThread extends Thread {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
while (!LinphoneService.isReady()) {
|
|
||||||
try {
|
|
||||||
sleep(30);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
Log.e("waiting thread sleep() has been interrupted, exiting as requested");
|
|
||||||
dismissDialogFromThread(waitServiceDialogId); // FIXME, may not be the best thing to do
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onLinphoneManagerAvailable(LinphoneManager.getInstance());
|
|
||||||
dismissDialogFromThread(waitServiceDialogId);
|
|
||||||
super.run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -19,9 +19,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
package org.linphone;
|
package org.linphone;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
import org.linphone.LinphoneManager.LinphoneServiceListener;
|
|
||||||
import org.linphone.LinphoneManager.NewOutgoingCallUiListener;
|
import org.linphone.LinphoneManager.NewOutgoingCallUiListener;
|
||||||
|
import org.linphone.LinphoneSimpleListener.LinphoneServiceListener;
|
||||||
import org.linphone.core.LinphoneCall;
|
import org.linphone.core.LinphoneCall;
|
||||||
import org.linphone.core.LinphoneCoreFactoryImpl;
|
import org.linphone.core.LinphoneCoreFactoryImpl;
|
||||||
import org.linphone.core.Log;
|
import org.linphone.core.Log;
|
||||||
|
@ -35,7 +37,6 @@ import android.app.Notification;
|
||||||
import android.app.NotificationManager;
|
import android.app.NotificationManager;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.app.Service;
|
import android.app.Service;
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.PackageInfo;
|
import android.content.pm.PackageInfo;
|
||||||
import android.content.pm.PackageManager.NameNotFoundException;
|
import android.content.pm.PackageManager.NameNotFoundException;
|
||||||
|
@ -69,7 +70,7 @@ public final class LinphoneService extends Service implements LinphoneServiceLis
|
||||||
private Handler mHandler = new Handler();
|
private Handler mHandler = new Handler();
|
||||||
private static LinphoneService instance;
|
private static LinphoneService instance;
|
||||||
|
|
||||||
static boolean isReady() { return (instance!=null); }
|
public static boolean isReady() { return (instance!=null); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws RuntimeException service not instantiated
|
* @throws RuntimeException service not instantiated
|
||||||
|
@ -81,7 +82,6 @@ public final class LinphoneService extends Service implements LinphoneServiceLis
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private NotificationManager mNotificationMgr;
|
|
||||||
private final static int NOTIF_ID=1;
|
private final static int NOTIF_ID=1;
|
||||||
|
|
||||||
private Notification mNotif;
|
private Notification mNotif;
|
||||||
|
@ -116,7 +116,7 @@ public final class LinphoneService extends Service implements LinphoneServiceLis
|
||||||
dumpDeviceInformation();
|
dumpDeviceInformation();
|
||||||
dumpInstalledLinphoneInformation();
|
dumpInstalledLinphoneInformation();
|
||||||
|
|
||||||
mNotificationMgr = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
|
mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
|
||||||
mNotif = new Notification(R.drawable.status_level, "", System.currentTimeMillis());
|
mNotif = new Notification(R.drawable.status_level, "", System.currentTimeMillis());
|
||||||
mNotif.iconLevel=IC_LEVEL_ORANGE;
|
mNotif.iconLevel=IC_LEVEL_ORANGE;
|
||||||
mNotif.flags |= Notification.FLAG_ONGOING_EVENT;
|
mNotif.flags |= Notification.FLAG_ONGOING_EVENT;
|
||||||
|
@ -124,16 +124,106 @@ public final class LinphoneService extends Service implements LinphoneServiceLis
|
||||||
Intent notifIntent = new Intent(this, LinphoneActivity.class);
|
Intent notifIntent = new Intent(this, LinphoneActivity.class);
|
||||||
mNotifContentIntent = PendingIntent.getActivity(this, 0, notifIntent, 0);
|
mNotifContentIntent = PendingIntent.getActivity(this, 0, notifIntent, 0);
|
||||||
mNotif.setLatestEventInfo(this, notificationTitle,"", mNotifContentIntent);
|
mNotif.setLatestEventInfo(this, notificationTitle,"", mNotifContentIntent);
|
||||||
mNotificationMgr.notify(NOTIF_ID, mNotif);
|
|
||||||
|
|
||||||
|
|
||||||
LinphoneManager.createAndStart(this, this);
|
LinphoneManager.createAndStart(this, this);
|
||||||
LinphoneManager.getLc().setPresenceInfo(0, null, OnlineStatus.Online);
|
LinphoneManager.getLc().setPresenceInfo(0, null, OnlineStatus.Online);
|
||||||
instance = this; // instance is ready once linphone manager has been created
|
instance = this; // instance is ready once linphone manager has been created
|
||||||
|
|
||||||
|
|
||||||
|
// Retrieve methods to publish notification and keep Android
|
||||||
|
// from killing us and keep the audio quality high.
|
||||||
|
if (Version.sdkStrictlyBelow(Version.API05_ECLAIR_20)) {
|
||||||
|
try {
|
||||||
|
mSetForeground = getClass().getMethod("setForeground", mSetFgSign);
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
Log.e(e, "Couldn't find foreground method");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
mStartForeground = getClass().getMethod("startForeground", mStartFgSign);
|
||||||
|
mStopForeground = getClass().getMethod("stopForeground", mStopFgSign);
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
Log.e(e, "Couldn't find startGoreground or stopForeground");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
startForegroundCompat(NOTIF_ID, mNotif);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private static final Class<?>[] mSetFgSign = new Class[] {boolean.class};
|
||||||
|
private static final Class<?>[] mStartFgSign = new Class[] {
|
||||||
|
int.class, Notification.class};
|
||||||
|
private static final Class<?>[] mStopFgSign = new Class[] {boolean.class};
|
||||||
|
|
||||||
|
private NotificationManager mNM;
|
||||||
|
private Method mSetForeground;
|
||||||
|
private Method mStartForeground;
|
||||||
|
private Method mStopForeground;
|
||||||
|
private Object[] mSetForegroundArgs = new Object[1];
|
||||||
|
private Object[] mStartForegroundArgs = new Object[2];
|
||||||
|
private Object[] mStopForegroundArgs = new Object[1];
|
||||||
|
|
||||||
|
void invokeMethod(Method method, Object[] args) {
|
||||||
|
try {
|
||||||
|
method.invoke(this, args);
|
||||||
|
} catch (InvocationTargetException e) {
|
||||||
|
// Should not happen.
|
||||||
|
Log.w(e, "Unable to invoke method");
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
// Should not happen.
|
||||||
|
Log.w(e, "Unable to invoke method");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a wrapper around the new startForeground method, using the older
|
||||||
|
* APIs if it is not available.
|
||||||
|
*/
|
||||||
|
void startForegroundCompat(int id, Notification notification) {
|
||||||
|
// If we have the new startForeground API, then use it.
|
||||||
|
if (mStartForeground != null) {
|
||||||
|
mStartForegroundArgs[0] = Integer.valueOf(id);
|
||||||
|
mStartForegroundArgs[1] = notification;
|
||||||
|
invokeMethod(mStartForeground, mStartForegroundArgs);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fall back on the old API.
|
||||||
|
if (mSetForeground != null) {
|
||||||
|
mSetForegroundArgs[0] = Boolean.TRUE;
|
||||||
|
invokeMethod(mSetForeground, mSetForegroundArgs);
|
||||||
|
// continue
|
||||||
|
}
|
||||||
|
|
||||||
|
mNM.notify(id, notification);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a wrapper around the new stopForeground method, using the older
|
||||||
|
* APIs if it is not available.
|
||||||
|
*/
|
||||||
|
void stopForegroundCompat(int id) {
|
||||||
|
// If we have the new stopForeground API, then use it.
|
||||||
|
if (mStopForeground != null) {
|
||||||
|
mStopForegroundArgs[0] = Boolean.TRUE;
|
||||||
|
invokeMethod(mStopForeground, mStopForegroundArgs);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fall back on the old API. Note to cancel BEFORE changing the
|
||||||
|
// foreground state, since we could be killed at that point.
|
||||||
|
mNM.cancel(id);
|
||||||
|
if (mSetForeground != null) {
|
||||||
|
mSetForegroundArgs[0] = Boolean.FALSE;
|
||||||
|
invokeMethod(mSetForeground, mSetForegroundArgs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static final String START_LINPHONE_LOGS = " ==== Phone information dump ====";
|
public static final String START_LINPHONE_LOGS = " ==== Phone information dump ====";
|
||||||
private void dumpDeviceInformation() {
|
private void dumpDeviceInformation() {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
|
@ -170,7 +260,7 @@ public final class LinphoneService extends Service implements LinphoneServiceLis
|
||||||
}
|
}
|
||||||
|
|
||||||
mNotif.setLatestEventInfo(this, notificationTitle, text, mNotifContentIntent);
|
mNotif.setLatestEventInfo(this, notificationTitle, text, mNotifContentIntent);
|
||||||
mNotificationMgr.notify(NOTIF_ID, mNotif);
|
mNM.notify(NOTIF_ID, mNotif);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -184,10 +274,11 @@ public final class LinphoneService extends Service implements LinphoneServiceLis
|
||||||
@Override
|
@Override
|
||||||
public void onDestroy() {
|
public void onDestroy() {
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
|
// Make sure our notification is gone.
|
||||||
|
stopForegroundCompat(NOTIF_ID);
|
||||||
|
|
||||||
LinphoneManager.getLcIfManagerNotDestroyedOrNull().setPresenceInfo(0, null, OnlineStatus.Offline);
|
LinphoneManager.getLcIfManagerNotDestroyedOrNull().setPresenceInfo(0, null, OnlineStatus.Offline);
|
||||||
LinphoneManager.destroy(this);
|
LinphoneManager.destroy(this);
|
||||||
|
|
||||||
mNotificationMgr.cancel(NOTIF_ID);
|
|
||||||
instance=null;
|
instance=null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -252,6 +343,7 @@ public final class LinphoneService extends Service implements LinphoneServiceLis
|
||||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
|
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
|
||||||
} else if (state == LinphoneCall.State.StreamsRunning) {
|
} else if (state == LinphoneCall.State.StreamsRunning) {
|
||||||
if (Version.isVideoCapable()
|
if (Version.isVideoCapable()
|
||||||
|
&& getResources().getBoolean(R.bool.autostart_video_activity)
|
||||||
&& getResources().getBoolean(R.bool.use_video_activity)
|
&& getResources().getBoolean(R.bool.use_video_activity)
|
||||||
&& !VideoCallActivity.launched && LinphoneActivity.isInstanciated()
|
&& !VideoCallActivity.launched && LinphoneActivity.isInstanciated()
|
||||||
&& call.getCurrentParamsCopy().getVideoEnabled()) {
|
&& call.getCurrentParamsCopy().getVideoEnabled()) {
|
||||||
|
|
59
src/org/linphone/LinphoneSimpleListener.java
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
/*
|
||||||
|
LinphoneServiceListener.java
|
||||||
|
Copyright (C) 2011 Belledonne Communications, Grenoble, France
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
package org.linphone;
|
||||||
|
|
||||||
|
import org.linphone.core.LinphoneCall;
|
||||||
|
import org.linphone.core.LinphoneCall.State;
|
||||||
|
import org.linphone.core.LinphoneCore.GlobalState;
|
||||||
|
import org.linphone.core.LinphoneCore.RegistrationState;
|
||||||
|
|
||||||
|
import android.media.MediaPlayer;
|
||||||
|
|
||||||
|
public interface LinphoneSimpleListener {
|
||||||
|
|
||||||
|
public static interface LinphoneServiceListener
|
||||||
|
extends LinphoneOnGlobalStateChangedListener, LinphoneOnCallStateChangedListener {
|
||||||
|
void tryingNewOutgoingCallButCannotGetCallParameters();
|
||||||
|
void tryingNewOutgoingCallButWrongDestinationAddress();
|
||||||
|
void tryingNewOutgoingCallButAlreadyInCall();
|
||||||
|
void onRegistrationStateChanged(RegistrationState state, String message);
|
||||||
|
void onRingerPlayerCreated(MediaPlayer mRingerPlayer);
|
||||||
|
void onDisplayStatus(String message);
|
||||||
|
void onCallEncryptionChanged(LinphoneCall call, boolean encrypted, String authenticationToken);
|
||||||
|
void onAlreadyInVideoCall();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static interface LinphoneOnGlobalStateChangedListener extends LinphoneSimpleListener {
|
||||||
|
void onGlobalStateChanged(GlobalState state, String message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static interface LinphoneOnCallStateChangedListener extends LinphoneSimpleListener {
|
||||||
|
void onCallStateChanged(LinphoneCall call, State state, String message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static interface LinphoneOnAudioChangedListener extends LinphoneSimpleListener {
|
||||||
|
public enum AudioState {EARPIECE, SPEAKER}
|
||||||
|
void onAudioStateChanged(AudioState state);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static interface LinphoneOnVideoCallReadyListener extends LinphoneSimpleListener {
|
||||||
|
void onRequestedVideoCallReady(LinphoneCall call);
|
||||||
|
}
|
||||||
|
}
|