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="gen"/>
|
||||
<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="output" path="bin"/>
|
||||
</classpath>
|
||||
|
|
|
@ -36,13 +36,39 @@
|
|||
</intent-filter>
|
||||
</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">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
</intent-filter>
|
||||
</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"
|
||||
android:launchMode="singleTop"
|
||||
android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
|
||||
|
@ -99,10 +125,21 @@
|
|||
<receiver android:name="org.linphone.BootReceiver">
|
||||
<intent-filter><action android:name="android.intent.action.BOOT_COMPLETED"></action></intent-filter>
|
||||
</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"
|
||||
android:label="Video test"
|
||||
android:theme="@android:style/Theme.NoTitleBar"
|
||||
|
@ -168,6 +205,7 @@
|
|||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
<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"/>
|
||||
</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">
|
||||
<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"
|
||||
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"
|
||||
|
@ -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"/>
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
|
||||
<EditText android:id="@+id/status_label" android:layout_width="fill_parent"
|
||||
android:clickable="false" android:focusable="false"
|
||||
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: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"/>
|
||||
<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"/>
|
||||
<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" 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 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.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.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="1" android:background="@drawable/clavier_bg"/>
|
||||
</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" />
|
||||
|
|
|
@ -24,9 +24,7 @@
|
|||
</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>
|
||||
</TableLayout>
|
||||
|
||||
|
@ -34,8 +32,21 @@
|
|||
</FrameLayout>
|
||||
|
||||
<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">
|
||||
<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" />
|
||||
|
|
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="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>
|
||||
<bool name="allow_edit_in_dialer">true</bool>
|
||||
<string name="notification_registered">Registered 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_bugreport_email">linphone-android@belledonne-communications.com</string>
|
||||
</resources>
|
||||
|
|
@ -9,4 +9,13 @@
|
|||
<item name="android:textSize">20sp</item>
|
||||
<item name="android:layout_weight">1</item>
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
<declare-styleable name="Numpad">
|
||||
<attr name="play_dtmf">
|
||||
<enum name="dont" value="0" />
|
||||
<enum name="play" value="1" />
|
||||
</attr>
|
||||
</declare-styleable>
|
||||
</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"?>
|
||||
<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_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>
|
||||
|
@ -54,9 +108,9 @@
|
|||
<string name="menu_videocall_terminate_call_title">Terminate call</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">Automatically send my camera on incoming calls</string>
|
||||
<string name="pref_video_initiate_call_with_video_title">Initiate video calls</string>
|
||||
<string name="pref_video_initiate_call_with_video">Always send my camera on outgoing 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 capable 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_escape_plus">Replace + by 00</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">
|
||||
<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"
|
||||
android:key="@string/pref_passwd_key" android:password="true"></EditTextPreference>
|
||||
|
||||
<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"
|
||||
android:key="@string/pref_proxy_key"></EditTextPreference>
|
||||
android:key="@string/pref_proxy_key" android:inputType="text|textEmailAddress"></EditTextPreference>
|
||||
|
||||
<CheckBoxPreference android:enabled="true"
|
||||
android:selectable="true" android:key="@string/pref_enable_outbound_proxy_key"
|
||||
|
|
|
@ -73,26 +73,32 @@ public class AboutActivity extends Activity implements OnClickListener {
|
|||
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) {
|
||||
File tempFile;
|
||||
if (logs == null) {
|
||||
Toast.makeText(this, getString(R.string.about_logs_not_found), Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
|
||||
try {
|
||||
tempFile = File.createTempFile("bugreport", ".txt");
|
||||
tempFile.deleteOnExit();
|
||||
FileWriter writer = new FileWriter(tempFile);
|
||||
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;
|
||||
File tempFile = writeLogs(logs, null);
|
||||
if (tempFile == null) {
|
||||
// If writing to temporary file to default location failed
|
||||
// Write one to our storage place
|
||||
tempFile = writeLogs(logs, getFilesDir());
|
||||
}
|
||||
|
||||
|
||||
Intent intent = new Intent(Intent.ACTION_SEND);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
intent.setType("plain/text");
|
||||
|
@ -114,6 +120,7 @@ public class AboutActivity extends Activity implements OnClickListener {
|
|||
@Override
|
||||
public void run() {
|
||||
onLogsRead(logs);
|
||||
thread=null;
|
||||
}
|
||||
});
|
||||
super.run();
|
||||
|
|
|
@ -21,6 +21,8 @@ package org.linphone;
|
|||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.linphone.mediastream.Version;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.DialogInterface;
|
||||
|
@ -155,7 +157,7 @@ public abstract class AbstractContactPickerActivity extends Activity implements
|
|||
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 android.content.ContentResolver;
|
||||
import android.content.ContentUris;
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
|
@ -52,35 +53,28 @@ public class ContactPickerActivityNew extends AbstractContactPickerActivity {
|
|||
|
||||
@Override
|
||||
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);
|
||||
if (photoUri == null) {
|
||||
return null;
|
||||
}
|
||||
Cursor cursor = getContentResolver().query(photoUri,
|
||||
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;
|
||||
}
|
||||
if (ContactHelper.testPhotoUri(resolver, photoUri, ContactsContract.CommonDataKinds.Photo.PHOTO)) {
|
||||
return photoUri;
|
||||
} finally {
|
||||
if (cursor != null) {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected List<String> extractPhones(String id) {
|
||||
List<String> list = new ArrayList<String>();
|
||||
Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
|
||||
String[] projection = {ContactsContract.CommonDataKinds.Phone.NUMBER};
|
||||
String selection = ContactsContract.CommonDataKinds.Phone.CONTACT_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);
|
||||
|
||||
|
@ -96,35 +90,41 @@ public class ContactPickerActivityNew extends AbstractContactPickerActivity {
|
|||
protected List<String> extractSipNumbers(String id) {
|
||||
List<String> list = new ArrayList<String>();
|
||||
Uri uri = ContactsContract.Data.CONTENT_URI;
|
||||
String[] projection = {ContactsContract.CommonDataKinds.Im.DATA};
|
||||
String selection = new StringBuilder()
|
||||
.append(ContactsContract.Data.CONTACT_ID).append(" = ? AND ")
|
||||
.append(ContactsContract.Data.MIMETYPE).append(" = ? ")
|
||||
.append(" AND lower(")
|
||||
.append(ContactsContract.CommonDataKinds.Im.CUSTOM_PROTOCOL)
|
||||
.append(") = 'sip'").toString();
|
||||
String[] selArgs = new String[] {id, ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE};
|
||||
Cursor c = this.getContentResolver().query(uri, null, selection, selArgs, null);
|
||||
.append(ContactsContract.Data.CONTACT_ID).append(" = ? AND ")
|
||||
.append(ContactsContract.Data.MIMETYPE).append(" = '")
|
||||
.append(ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE)
|
||||
.append("' AND lower(")
|
||||
.append(ContactsContract.CommonDataKinds.Im.CUSTOM_PROTOCOL)
|
||||
.append(") = 'sip'")
|
||||
.toString();
|
||||
Cursor c = getContentResolver().query(uri, projection, selection, new String[]{id}, null);
|
||||
|
||||
int nbId = c.getColumnIndex(ContactsContract.CommonDataKinds.Im.DATA);
|
||||
|
||||
while (c.moveToNext()) {
|
||||
list.add("sip:" + c.getString(nbId));
|
||||
}
|
||||
|
||||
c.close();
|
||||
|
||||
|
||||
// Using the SIP contact field added in SDK 9
|
||||
if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) {
|
||||
selection = ContactsContract.Data.CONTACT_ID + " = ? AND " + ContactsContract.Data.MIMETYPE + " = ?";
|
||||
String projection[] = new String[] {ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS};
|
||||
selArgs = new String[] {id, ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE};
|
||||
c = this.getContentResolver().query(uri, projection, selection, selArgs, null);
|
||||
selection = new StringBuilder()
|
||||
.append(ContactsContract.Data.CONTACT_ID)
|
||||
.append(" = ? AND ")
|
||||
.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);
|
||||
while (c.moveToNext()) {
|
||||
list.add("sip:" + c.getString(nbId));
|
||||
}
|
||||
|
||||
c.close();
|
||||
}
|
||||
|
||||
|
@ -162,13 +162,14 @@ public class ContactPickerActivityNew extends AbstractContactPickerActivity {
|
|||
private String retrieveContactName(String id) {
|
||||
//Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
|
||||
Uri uri = ContactsContract.Contacts.CONTENT_URI;
|
||||
String[] projection = new String[] {ContactsContract.Contacts.DISPLAY_NAME};
|
||||
String selection = ContactsContract.Contacts._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 = "";
|
||||
if (c.moveToFirst()) {
|
||||
name = c.getString(c.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
|
||||
name = c.getString(c.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
|
||||
}
|
||||
c.close();
|
||||
|
||||
|
|
|
@ -26,7 +26,6 @@ import android.net.Uri;
|
|||
import android.os.Bundle;
|
||||
import android.provider.Contacts;
|
||||
import android.provider.Contacts.People;
|
||||
import android.provider.Contacts.Photos;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
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,
|
||||
Intent data) {
|
||||
|
@ -81,8 +65,10 @@ public class ContactPickerActivityOld extends Activity {
|
|||
String lPhoneNo = lCur.getString(lCur.getColumnIndex(People.NUMBER));
|
||||
long id = lCur.getLong(lCur.getColumnIndex(People._ID));
|
||||
Uri personUri = ContentUris.withAppendedId(People.CONTENT_URI, id);
|
||||
Uri potentialPictureUri = Uri.withAppendedPath(personUri, Contacts.Photos.CONTENT_DIRECTORY);
|
||||
Uri pictureUri = getPhotoUri(potentialPictureUri);
|
||||
Uri pictureUri = Uri.withAppendedPath(personUri, Contacts.Photos.CONTENT_DIRECTORY);
|
||||
if (!ContactHelper.testPhotoUri(getContentResolver(), pictureUri, Contacts.Photos.CONTENT_DIRECTORY)) {
|
||||
pictureUri = null;
|
||||
}
|
||||
// FIXME surprisingly all this picture stuff doesn't seem to work
|
||||
DialerActivity.instance().setContactAddress(lPhoneNo, lName, pictureUri);
|
||||
}
|
||||
|
@ -91,4 +77,5 @@ public class ContactPickerActivityOld extends Activity {
|
|||
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;
|
||||
|
||||
import org.linphone.LinphoneManager.NewOutgoingCallUiListener;
|
||||
import org.linphone.LinphoneManagerWaitHelper.LinphoneManagerReadyListener;
|
||||
import org.linphone.LinphoneService.LinphoneGuiListener;
|
||||
import org.linphone.core.CallDirection;
|
||||
import org.linphone.core.LinphoneAddress;
|
||||
import org.linphone.core.LinphoneCall;
|
||||
import org.linphone.core.LinphoneCore;
|
||||
import org.linphone.core.Log;
|
||||
import org.linphone.core.LinphoneCall.State;
|
||||
import org.linphone.mediastream.Version;
|
||||
import org.linphone.ui.AddVideoButton;
|
||||
import org.linphone.ui.AddressAware;
|
||||
import org.linphone.ui.AddressText;
|
||||
|
@ -35,16 +36,15 @@ import org.linphone.ui.HangCallButton;
|
|||
import org.linphone.ui.MuteMicButton;
|
||||
import org.linphone.ui.SpeakerButton;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Activity;
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.media.AudioManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.PowerManager;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.TextView;
|
||||
|
@ -62,7 +62,7 @@ import android.widget.Toast;
|
|||
* </ul>
|
||||
*
|
||||
*/
|
||||
public class DialerActivity extends LinphoneManagerWaitActivity implements LinphoneGuiListener, NewOutgoingCallUiListener {
|
||||
public class DialerActivity extends Activity implements LinphoneGuiListener, LinphoneManagerReadyListener, NewOutgoingCallUiListener, OnClickListener {
|
||||
|
||||
private TextView mStatus;
|
||||
private View mHangup;
|
||||
|
@ -81,16 +81,12 @@ public class DialerActivity extends LinphoneManagerWaitActivity implements Linph
|
|||
private static DialerActivity instance;
|
||||
|
||||
private PowerManager.WakeLock mWakeLock;
|
||||
private SharedPreferences mPref;
|
||||
private LinphoneCall mCurrentCall;
|
||||
private boolean useIncallActivity;
|
||||
private boolean useVideoActivity;
|
||||
private boolean useConferenceActivity;
|
||||
|
||||
private static final String CURRENT_ADDRESS = "org.linphone.current-address";
|
||||
private static final String CURRENT_DISPLAYNAME = "org.linphone.current-displayname";
|
||||
|
||||
private static final int incomingCallDialogId = 1;
|
||||
|
||||
/**
|
||||
* @return null if not ready yet
|
||||
*/
|
||||
|
@ -98,22 +94,21 @@ public class DialerActivity extends LinphoneManagerWaitActivity implements Linph
|
|||
return instance;
|
||||
}
|
||||
|
||||
|
||||
private LinphoneManagerWaitHelper waitHelper;
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
setContentView(R.layout.dialer);
|
||||
|
||||
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.
|
||||
|
||||
mPref = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE);
|
||||
mWakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK|PowerManager.ON_AFTER_RELEASE,Log.TAG);
|
||||
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
|
||||
mWakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK|PowerManager.ON_AFTER_RELEASE,Log.TAG+"#"+getClass().getName());
|
||||
|
||||
|
||||
mAddress = (AddressText) findViewById(R.id.SipUri);
|
||||
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);
|
||||
|
@ -121,6 +116,7 @@ public class DialerActivity extends LinphoneManagerWaitActivity implements Linph
|
|||
|
||||
|
||||
mCallControlRow = findViewById(R.id.CallControlRow);
|
||||
mCallControlRow.findViewById(R.id.BackToConference).setOnClickListener(this);
|
||||
mAddressLayout = findViewById(R.id.Addresslayout);
|
||||
|
||||
mInCallControlRow = findViewById(R.id.IncallControlRow);
|
||||
|
@ -128,15 +124,19 @@ public class DialerActivity extends LinphoneManagerWaitActivity implements Linph
|
|||
mInCallAddressLayout = findViewById(R.id.IncallAddressLayout);
|
||||
mInCallAddressLayout.setVisibility(View.GONE);
|
||||
|
||||
if (useIncallActivity) {
|
||||
mHangup = findViewById(R.id.HangUp);
|
||||
HangCallButton hang = (HangCallButton) findViewById(R.id.HangUp);
|
||||
HangCallButton decline = (HangCallButton) findViewById(R.id.Decline);
|
||||
hang.setTerminateAllCalls(true);
|
||||
decline.setTerminateAllCalls(true);
|
||||
|
||||
if (useConferenceActivity || useIncallActivity) {
|
||||
mHangup = hang;
|
||||
} else {
|
||||
mMute = (MuteMicButton) findViewById(R.id.mic_mute_button);
|
||||
mSpeaker = (SpeakerButton) findViewById(R.id.speaker_button);
|
||||
mHangup = findViewById(R.id.Decline);
|
||||
mHangup = decline;
|
||||
}
|
||||
|
||||
|
||||
mStatus = (TextView) findViewById(R.id.status_label);
|
||||
|
||||
AddressAware numpad = (AddressAware) findViewById(R.id.Dialer);
|
||||
|
@ -149,18 +149,19 @@ public class DialerActivity extends LinphoneManagerWaitActivity implements Linph
|
|||
|
||||
checkIfOutgoingCallIntentReceived();
|
||||
|
||||
waitHelper = new LinphoneManagerWaitHelper(this, this);
|
||||
waitHelper.doManagerDependentOnCreate();
|
||||
instance = this;
|
||||
super.onCreate(savedInstanceState);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLinphoneManagerAvailable(LinphoneManager m) {
|
||||
LinphoneCore lc = LinphoneManager.getLc();
|
||||
if (lc.isIncall()) {
|
||||
if(lc.isInComingInvitePending()) {
|
||||
callPending(lc.getCurrentCall());
|
||||
} else {
|
||||
enterIncallMode(lc);
|
||||
}
|
||||
public void onCreateWhenManagerReady() {
|
||||
LinphoneCall pendingCall = LinphoneManager.getInstance().getPendingIncomingCall();
|
||||
if (pendingCall != null) {
|
||||
LinphoneActivity.instance().startIncomingCallActivity(pendingCall);
|
||||
} else if (LinphoneManager.getLc().isIncall()) {
|
||||
enterIncallMode();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -221,17 +222,21 @@ public class DialerActivity extends LinphoneManagerWaitActivity implements Linph
|
|||
|
||||
|
||||
|
||||
private void enterIncallMode(LinphoneCore lc) {
|
||||
mDisplayNameView.setText(LinphoneManager.getInstance().extractADisplayName());
|
||||
private void enterIncallMode() {
|
||||
LinphoneCore lc = LinphoneManager.getLc();
|
||||
LinphoneAddress address = lc.getRemoteAddress();
|
||||
mDisplayNameView.setText(LinphoneManager.extractADisplayName(getResources(), address));
|
||||
|
||||
// setVolumeControlStream(AudioManager.STREAM_VOICE_CALL);
|
||||
|
||||
LinphoneActivity.instance().startProxymitySensor();
|
||||
LinphoneManager.startProximitySensorForActivity(LinphoneActivity.instance());
|
||||
if (!mWakeLock.isHeld()) mWakeLock.acquire();
|
||||
|
||||
if (useIncallActivity) {
|
||||
LinphoneActivity.instance().startIncallActivity(
|
||||
mDisplayNameView.getText(), mAddress.getPictureUri());
|
||||
} else if (useConferenceActivity) {
|
||||
LinphoneActivity.instance().startConferenceActivity();
|
||||
} else {
|
||||
loadMicAndSpeakerUiStateFromManager();
|
||||
mCallControlRow.setVisibility(View.GONE);
|
||||
|
@ -247,7 +252,8 @@ public class DialerActivity extends LinphoneManagerWaitActivity implements Linph
|
|||
|
||||
|
||||
private void updateIncallVideoCallButton() {
|
||||
if (useIncallActivity) throw new RuntimeException("Internal error");
|
||||
if (useIncallActivity || useConferenceActivity)
|
||||
throw new RuntimeException("Internal error");
|
||||
|
||||
boolean prefVideoEnabled = LinphoneManager.getInstance().isVideoEnabled();
|
||||
AddVideoButton mAddVideo = (AddVideoButton) findViewById(R.id.AddVideo);
|
||||
|
@ -262,7 +268,8 @@ public class DialerActivity extends LinphoneManagerWaitActivity implements Linph
|
|||
|
||||
|
||||
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());
|
||||
mSpeaker.setSpeakerOn(LinphoneManager.getInstance().isSpeakerOn());
|
||||
|
@ -270,14 +277,11 @@ public class DialerActivity extends LinphoneManagerWaitActivity implements Linph
|
|||
|
||||
|
||||
private void exitCallMode() {
|
||||
// Remove dialog if existing
|
||||
try {
|
||||
dismissDialog(incomingCallDialogId);
|
||||
} catch (Throwable e) {/* Exception if never created */}
|
||||
|
||||
if (useIncallActivity) {
|
||||
LinphoneActivity.instance().closeIncallActivity();
|
||||
} else {
|
||||
} else if(useConferenceActivity) {
|
||||
LinphoneActivity.instance().closeConferenceActivity();
|
||||
}else {
|
||||
mCallControlRow.setVisibility(View.VISIBLE);
|
||||
mInCallControlRow.setVisibility(View.GONE);
|
||||
mInCallAddressLayout.setVisibility(View.GONE);
|
||||
|
@ -289,68 +293,18 @@ public class DialerActivity extends LinphoneManagerWaitActivity implements Linph
|
|||
|
||||
mHangup.setEnabled(false);
|
||||
|
||||
|
||||
if (useVideoActivity && LinphoneManager.getLc().isVideoEnabled()) {
|
||||
LinphoneActivity.instance().finishVideoActivity();
|
||||
BandwidthManager.getInstance().setUserRestriction(false);
|
||||
LinphoneManager.getInstance().resetCameraFromPreferences();
|
||||
}
|
||||
|
||||
if (mWakeLock.isHeld()) mWakeLock.release();
|
||||
LinphoneActivity.instance().stopProxymitySensor();
|
||||
LinphoneManager.stopProximitySensorForActivity(LinphoneActivity.instance());
|
||||
|
||||
setVolumeControlStream(AudioManager.USE_DEFAULT_STREAM_TYPE);
|
||||
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
|
||||
protected Dialog onCreateDialog(int id) {
|
||||
if (id == incomingCallDialogId) {
|
||||
View incomingCallView = getLayoutInflater().inflate(R.layout.incoming_call, null);
|
||||
|
||||
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;
|
||||
if (id == LinphoneManagerWaitHelper.DIALOG_ID) {
|
||||
return waitHelper.createWaitDialog();
|
||||
} else {
|
||||
return super.onCreateDialog(id);
|
||||
}
|
||||
|
@ -405,42 +359,32 @@ public class DialerActivity extends LinphoneManagerWaitActivity implements Linph
|
|||
|
||||
|
||||
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();
|
||||
if (lc==null) {
|
||||
/* we are certainly exiting, ignore then.*/
|
||||
return;
|
||||
}
|
||||
|
||||
if (state==LinphoneCall.State.OutgoingInit){
|
||||
mCurrentCall=call;
|
||||
call.enableCamera(LinphoneManager.getInstance().shareMyCamera());
|
||||
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 (state==State.OutgoingInit){
|
||||
enterIncallMode();
|
||||
}else if (state==State.Connected){
|
||||
if (call.getDirection() == CallDirection.Incoming) {
|
||||
enterIncallMode(lc);
|
||||
enterIncallMode();
|
||||
}
|
||||
}else if (state==LinphoneCall.State.Error){
|
||||
if (lc.getCurrentCall() == null || lc.getCurrentCall()==call){
|
||||
}else if (state==State.Error){
|
||||
showToast(R.string.call_error, message);
|
||||
if (lc.getCallsNb() == 0){
|
||||
if (mWakeLock.isHeld()) mWakeLock.release();
|
||||
showToast(R.string.call_error, message);
|
||||
exitCallMode();
|
||||
LinphoneActivity.instance().stopOrientationSensor();
|
||||
mCurrentCall=null;
|
||||
}
|
||||
}else if (state==LinphoneCall.State.CallEnd){
|
||||
if (lc.getCurrentCall() == null || lc.getCurrentCall()==call){
|
||||
}else if (state==State.CallEnd){
|
||||
if (lc.getCallsNb() == 0){
|
||||
exitCallMode();
|
||||
LinphoneActivity.instance().stopOrientationSensor();
|
||||
mCurrentCall=null;
|
||||
}
|
||||
}
|
||||
|
||||
updateCallControlRow();
|
||||
}
|
||||
|
||||
private void showToast(int id, String txt) {
|
||||
|
@ -456,7 +400,7 @@ public class DialerActivity extends LinphoneManagerWaitActivity implements Linph
|
|||
|
||||
public void onGlobalStateChangedToOn(String message) {
|
||||
mCall.setEnabled(!LinphoneManager.getLc().isIncall());
|
||||
if (!useIncallActivity) updateIncallVideoCallButton();
|
||||
if (!useIncallActivity && !useConferenceActivity) updateIncallVideoCallButton();
|
||||
else mHangup.setEnabled(!mCall.isEnabled());
|
||||
|
||||
if (getIntent().getData() != null) {
|
||||
|
@ -476,17 +420,65 @@ public class DialerActivity extends LinphoneManagerWaitActivity implements Linph
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
public void onResumeWhenManagerReady() {
|
||||
updateCallControlRow();
|
||||
|
||||
// When coming back from a video call, if the phone orientation is different
|
||||
// Android will destroy the previous Dialer and create a new one.
|
||||
// Unfortunately the "call end" status event is received in the meanwhile
|
||||
// and set to the to be destroyed Dialer.
|
||||
// Note1: We wait as long as possible before setting the last message.
|
||||
// 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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
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);
|
||||
TextView lFirstLineView = (TextView) v.findViewById(R.id.history_cell_first_line);
|
||||
TextView lSecondLineView = (TextView) v.findViewById(R.id.history_cell_second_line);
|
||||
ContactPicked parent = (ContactPicked) getParent();
|
||||
if (lSecondLineView.getVisibility() == View.GONE) {
|
||||
// no display name
|
||||
LinphoneActivity.setAddressAndGoToDialer(lFirstLineView.getText().toString(), null, null);
|
||||
parent.setAddressAndGoToDialer(lFirstLineView.getText().toString(), null, null);
|
||||
} else {
|
||||
LinphoneActivity.setAddressAndGoToDialer(
|
||||
parent.setAddressAndGoToDialer(
|
||||
lSecondLineView.getText().toString(),
|
||||
lFirstLineView.getText().toString(),
|
||||
null);
|
||||
|
|
|
@ -23,7 +23,7 @@ import java.util.TimerTask;
|
|||
|
||||
import org.linphone.ui.HangCallButton;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.preference.PreferenceManager;
|
||||
|
@ -32,7 +32,11 @@ import android.view.View;
|
|||
import android.view.View.OnClickListener;
|
||||
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 PICTURE_URI_KEY = "picture_uri";
|
||||
|
@ -98,7 +102,7 @@ public class IncallActivity extends SoftVolumeActivity implements OnClickListene
|
|||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
|
||||
LinphoneManager.startProximitySensorForActivity(this);
|
||||
task = new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
@ -121,6 +125,7 @@ public class IncallActivity extends SoftVolumeActivity implements OnClickListene
|
|||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
LinphoneManager.stopProximitySensorForActivity(this);
|
||||
|
||||
if (task != null) {
|
||||
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
|
||||
public boolean onKeyUp(int keyCode, KeyEvent event) {
|
||||
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
|
||||
startActivity(new Intent()
|
||||
.setAction(Intent.ACTION_MAIN)
|
||||
.addCategory(Intent.CATEGORY_HOME));
|
||||
return true;
|
||||
} else {
|
||||
return super.onKeyUp(keyCode, event);
|
||||
}
|
||||
if (LinphoneUtils.onKeyBackGoHome(this, keyCode)) return true;
|
||||
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
|
||||
|
||||
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 java.util.List;
|
||||
|
||||
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.LinphoneCoreException;
|
||||
import org.linphone.core.Log;
|
||||
import org.linphone.core.LinphoneCall.State;
|
||||
import org.linphone.core.LinphoneCore.EcCalibratorStatus;
|
||||
import org.linphone.core.LinphoneCore.RegistrationState;
|
||||
import org.linphone.mediastream.Version;
|
||||
|
@ -51,33 +53,28 @@ import android.text.Html;
|
|||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.TabWidget;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
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 PREF_FIRST_LAUNCH = "pref_first_launch";
|
||||
private static final int video_activity = 100;
|
||||
static final int FIRST_LOGIN_ACTIVITY = 101;
|
||||
static final int INCALL_ACTIVITY = 102;
|
||||
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 LinphoneActivity instance;
|
||||
|
||||
|
||||
private FrameLayout mMainFrame;
|
||||
private SensorManager mSensorManager;
|
||||
private Sensor mAccelerometer;
|
||||
private int previousRotation = -1;
|
||||
private static SensorEventListener mSensorEventListener;
|
||||
|
||||
private static final String SCREEN_IS_HIDDEN = "screen_is_hidden";
|
||||
private Handler mHandler = new Handler();
|
||||
|
||||
|
||||
|
@ -98,14 +95,9 @@ public class LinphoneActivity extends TabActivity implements SensorEventListener
|
|||
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) {
|
||||
super.onCreate(savedInstanceState);
|
||||
instance = this;
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.main);
|
||||
|
||||
LinphonePreferenceManager.getInstance(this);
|
||||
|
@ -118,7 +110,6 @@ public class LinphoneActivity extends TabActivity implements SensorEventListener
|
|||
startService(new Intent(ACTION_MAIN).setClass(this, LinphoneService.class));
|
||||
|
||||
|
||||
mMainFrame = (FrameLayout) findViewById(R.id.main_frame);
|
||||
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
|
||||
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
|
||||
|
@ -138,18 +129,16 @@ public class LinphoneActivity extends TabActivity implements SensorEventListener
|
|||
checkAccount = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (savedInstanceState !=null && savedInstanceState.getBoolean(SCREEN_IS_HIDDEN,false)) {
|
||||
hideScreen(true);
|
||||
}
|
||||
|
||||
LinphoneManager.addListener(this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
|
||||
if (requestCode == FIRST_LOGIN_ACTIVITY) {
|
||||
switch (requestCode) {
|
||||
case FIRST_LOGIN_ACTIVITY:
|
||||
if (resultCode == RESULT_OK) {
|
||||
Toast.makeText(this, getString(R.string.ec_calibration_launch_message), Toast.LENGTH_LONG).show();
|
||||
try {
|
||||
|
@ -170,6 +159,11 @@ public class LinphoneActivity extends TabActivity implements SensorEventListener
|
|||
finish();
|
||||
stopService(new Intent(ACTION_MAIN).setClass(this, LinphoneService.class));
|
||||
}
|
||||
break;
|
||||
case conference_activity:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
|
@ -217,7 +211,10 @@ public class LinphoneActivity extends TabActivity implements SensorEventListener
|
|||
gotToDialer();
|
||||
} else {
|
||||
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 {
|
||||
// TODO
|
||||
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
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
|
||||
if (isFinishing()) {
|
||||
//restore audio settings
|
||||
LinphoneManager.getInstance().routeAudioToReceiver();
|
||||
stopProxymitySensor();//just in case
|
||||
//restore audio settings
|
||||
boolean isUserRequest = false;
|
||||
LinphoneManager.getInstance().routeAudioToReceiver(isUserRequest);
|
||||
LinphoneManager.removeListener(this);
|
||||
LinphoneManager.stopProximitySensorForActivity(this);
|
||||
instance = null;
|
||||
}
|
||||
}
|
||||
|
@ -318,39 +316,12 @@ public class LinphoneActivity extends TabActivity implements SensorEventListener
|
|||
}
|
||||
|
||||
|
||||
|
||||
void hideScreen(boolean isHidden) {
|
||||
WindowManager.LayoutParams lAttrs =getWindow().getAttributes();
|
||||
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);
|
||||
public synchronized void stopOrientationSensor() {
|
||||
if (mSensorManager!=null)
|
||||
mSensorManager.unregisterListener(this, mAccelerometer);
|
||||
}
|
||||
|
||||
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() {
|
||||
if (mSensorManager!=null) {
|
||||
|
@ -362,20 +333,6 @@ public class LinphoneActivity extends TabActivity implements SensorEventListener
|
|||
previousRotation = -1;
|
||||
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) {
|
||||
if (!useMenuSettings) {
|
||||
|
@ -471,7 +428,7 @@ public class LinphoneActivity extends TabActivity implements SensorEventListener
|
|||
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);
|
||||
instance.gotToDialer();
|
||||
}
|
||||
|
@ -500,9 +457,11 @@ public class LinphoneActivity extends TabActivity implements SensorEventListener
|
|||
public void closeIncallActivity() {
|
||||
finishActivity(INCALL_ACTIVITY);
|
||||
}
|
||||
public void closeConferenceActivity() {
|
||||
finishActivity(conference_activity);
|
||||
}
|
||||
|
||||
public void startVideoActivity() {
|
||||
|
||||
mHandler.post(new Runnable() {
|
||||
public void run() {
|
||||
startActivityForResult(new Intent().setClass(
|
||||
|
@ -511,9 +470,32 @@ public class LinphoneActivity extends TabActivity implements SensorEventListener
|
|||
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() {
|
||||
mHandler.post(new Runnable() {
|
||||
public void run() {
|
||||
|
@ -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.IOException;
|
||||
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.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.LinphoneAuthInfo;
|
||||
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.AndroidCameraConfiguration.AndroidCamera;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
|
@ -74,18 +83,25 @@ import android.content.IntentFilter;
|
|||
import android.content.SharedPreferences;
|
||||
import android.content.SharedPreferences.Editor;
|
||||
import android.content.res.Resources;
|
||||
import android.hardware.Sensor;
|
||||
import android.hardware.SensorEvent;
|
||||
import android.hardware.SensorEventListener;
|
||||
import android.hardware.SensorManager;
|
||||
import android.media.AudioManager;
|
||||
import android.media.MediaPlayer;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.NetworkInfo;
|
||||
import android.os.Build;
|
||||
import android.os.PowerManager;
|
||||
import android.os.Vibrator;
|
||||
import android.os.PowerManager.WakeLock;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.provider.Settings;
|
||||
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,7 +132,19 @@ public final class LinphoneManager implements LinphoneCoreListener {
|
|||
private String basePath;
|
||||
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) {
|
||||
sExited=false;
|
||||
basePath = c.getFilesDir().getAbsolutePath();
|
||||
|
@ -132,6 +160,8 @@ public final class LinphoneManager implements LinphoneCoreListener {
|
|||
mPref = PreferenceManager.getDefaultSharedPreferences(c);
|
||||
mPowerManager = (PowerManager) c.getSystemService(Context.POWER_SERVICE);
|
||||
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;
|
||||
|
@ -153,6 +183,12 @@ public final class LinphoneManager implements LinphoneCoreListener {
|
|||
getInstance().routeAudioToSpeakerHelperHelper(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())
|
||||
setAudioModeIncallForGalaxyS();
|
||||
|
||||
|
@ -167,6 +203,9 @@ public final class LinphoneManager implements LinphoneCoreListener {
|
|||
} else {
|
||||
mAudioManager.setSpeakerphoneOn(speakerOn);
|
||||
}
|
||||
for (LinphoneOnAudioChangedListener listener : getSimpleListeners(LinphoneOnAudioChangedListener.class)) {
|
||||
listener.onAudioStateChanged(speakerOn ? AudioState.SPEAKER : AudioState.EARPIECE);
|
||||
}
|
||||
}
|
||||
private synchronized void routeAudioToSpeakerHelper(boolean speakerOn) {
|
||||
final LinphoneCall call = mLc.getCurrentCall();
|
||||
|
@ -178,8 +217,24 @@ public final class LinphoneManager implements LinphoneCoreListener {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public void routeAudioToSpeaker() {
|
||||
private static boolean sUserRequestedSpeaker;
|
||||
public static final boolean isUserRequestedSpeaker() {return sUserRequestedSpeaker;}
|
||||
|
||||
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);
|
||||
if (mLc.isIncall()) {
|
||||
/*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);
|
||||
if (mLc.isIncall()) {
|
||||
//Restore default value
|
||||
|
@ -203,21 +265,21 @@ public final class LinphoneManager implements LinphoneCoreListener {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public synchronized static final LinphoneManager createAndStart(
|
||||
Context c, LinphoneServiceListener listener) {
|
||||
if (instance != null)
|
||||
throw new RuntimeException("Linphone Manager is already initialized");
|
||||
|
||||
instance = new LinphoneManager(c);
|
||||
instance.serviceListener = listener;
|
||||
instance.listenerDispatcher.setServiceListener(listener);
|
||||
instance.startLibLinphone(c);
|
||||
|
||||
if (Version.isVideoCapable())
|
||||
AndroidVideoApi5JniWrapper.setAndroidSdkVersion(Version.sdk());
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
||||
public static synchronized final LinphoneManager getInstance() {
|
||||
if (instance != null) return instance;
|
||||
|
||||
|
@ -236,23 +298,26 @@ public final class LinphoneManager implements LinphoneCoreListener {
|
|||
|
||||
|
||||
public boolean isSpeakerOn() {
|
||||
return (Integer.parseInt(Build.VERSION.SDK) <=4 && mAudioManager.getRouting(MODE_NORMAL) == ROUTE_SPEAKER)
|
||||
|| Integer.parseInt(Build.VERSION.SDK) >4 &&mAudioManager.isSpeakerphoneOn();
|
||||
if (Hacks.needRoutingAPI() || lpm.useAudioRoutingAPIHack()) {
|
||||
return mAudioManager.getRouting(MODE_NORMAL) == ROUTE_SPEAKER;
|
||||
} else {
|
||||
return mAudioManager.isSpeakerphoneOn();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void newOutgoingCall(AddressType address) {
|
||||
String to = address.getText().toString();
|
||||
|
||||
if (mLc.isIncall()) {
|
||||
serviceListener.tryingNewOutgoingCallButAlreadyInCall();
|
||||
return;
|
||||
}
|
||||
// if (mLc.isIncall()) {
|
||||
// listenerDispatcher.tryingNewOutgoingCallButAlreadyInCall();
|
||||
// return;
|
||||
// }
|
||||
LinphoneAddress lAddress;
|
||||
try {
|
||||
lAddress = mLc.interpretUrl(to);
|
||||
} catch (LinphoneCoreException e) {
|
||||
serviceListener.tryingNewOutgoingCallButWrongDestinationAddress();
|
||||
listenerDispatcher.tryingNewOutgoingCallButWrongDestinationAddress();
|
||||
return;
|
||||
}
|
||||
lAddress.setDisplayName(address.getDisplayedName());
|
||||
|
@ -269,7 +334,7 @@ public final class LinphoneManager implements LinphoneCoreListener {
|
|||
|
||||
|
||||
} catch (LinphoneCoreException e) {
|
||||
serviceListener.tryingNewOutgoingCallButCannotGetCallParameters();
|
||||
listenerDispatcher.tryingNewOutgoingCallButCannotGetCallParameters();
|
||||
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 {
|
||||
void onEcCalibrationStatus(EcCalibratorStatus status, int delayMs);
|
||||
}
|
||||
|
||||
private LinphoneServiceListener serviceListener;
|
||||
private ListenerDispatcher listenerDispatcher = new ListenerDispatcher();
|
||||
private LinphoneCall ringingCall;
|
||||
|
||||
private MediaPlayer mRingerPlayer;
|
||||
|
@ -689,35 +740,37 @@ public final class LinphoneManager implements LinphoneCoreListener {
|
|||
public void displayStatus(final LinphoneCore lc, final String message) {
|
||||
Log.i(message);
|
||||
lastLcStatusMessage=message;
|
||||
serviceListener.onDisplayStatus(message);
|
||||
listenerDispatcher.onDisplayStatus(message);
|
||||
}
|
||||
|
||||
|
||||
public void globalState(final LinphoneCore lc, final LinphoneCore.GlobalState state, final String message) {
|
||||
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) {
|
||||
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) {
|
||||
Log.i("new state [",state,"]");
|
||||
if (state == IncomingReceived && !call.equals(lc.getCurrentCall())) {
|
||||
if (call.getReplacedCall()==null){
|
||||
//no multicall support, just decline
|
||||
lc.terminateCall(call);
|
||||
}//otherwise it will be accepted automatically.
|
||||
|
||||
return;
|
||||
if (call.getReplacedCall()!=null){
|
||||
// attended transfer
|
||||
// it will be accepted automatically.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (state == IncomingReceived) {
|
||||
if (!gsmIdle) {
|
||||
mLc.terminateCall(call);
|
||||
}
|
||||
// Brighten screen for at least 10 seconds
|
||||
WakeLock wl = mPowerManager.newWakeLock(
|
||||
PowerManager.ACQUIRE_CAUSES_WAKEUP
|
||||
|
@ -726,15 +779,16 @@ public final class LinphoneManager implements LinphoneCoreListener {
|
|||
"incoming_call");
|
||||
wl.acquire(10000);
|
||||
|
||||
startRinging();
|
||||
ringingCall = call;
|
||||
} else if (call == ringingCall) {
|
||||
if (mLc.getCallsNb() == 1) {
|
||||
ringingCall = call;
|
||||
startRinging();
|
||||
// otherwise there is the beep
|
||||
}
|
||||
} else if (call == ringingCall && isRinging) {
|
||||
//previous state was ringing, so stop ringing
|
||||
stopRinging();
|
||||
ringingCall = null;
|
||||
routeAudioToReceiver();
|
||||
}
|
||||
|
||||
|
||||
if (state == CallEnd || state == Error) {
|
||||
mAudioManager.setMode(MODE_NORMAL);
|
||||
}
|
||||
|
@ -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,
|
||||
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,
|
||||
|
@ -779,6 +854,7 @@ public final class LinphoneManager implements LinphoneCoreListener {
|
|||
|
||||
|
||||
|
||||
private boolean isRinging;
|
||||
private synchronized void startRinging() {
|
||||
if (Hacks.needGalaxySAudioHack()) {
|
||||
mAudioManager.setMode(MODE_RINGTONE);
|
||||
|
@ -792,7 +868,7 @@ public final class LinphoneManager implements LinphoneCoreListener {
|
|||
if (mRingerPlayer == null) {
|
||||
mRingerPlayer = new MediaPlayer();
|
||||
mRingerPlayer.setAudioStreamType(STREAM_RING);
|
||||
serviceListener.onRingerPlayerCreated(mRingerPlayer);
|
||||
listenerDispatcher.onRingerPlayerCreated(mRingerPlayer);
|
||||
mRingerPlayer.prepare();
|
||||
mRingerPlayer.setLooping(true);
|
||||
mRingerPlayer.start();
|
||||
|
@ -802,7 +878,7 @@ public final class LinphoneManager implements LinphoneCoreListener {
|
|||
} catch (Exception e) {
|
||||
Log.e(e,"cannot handle incoming call");
|
||||
}
|
||||
|
||||
isRinging = true;
|
||||
}
|
||||
|
||||
private synchronized void stopRinging() {
|
||||
|
@ -815,25 +891,27 @@ public final class LinphoneManager implements LinphoneCoreListener {
|
|||
mVibrator.cancel();
|
||||
}
|
||||
|
||||
isRinging = false;
|
||||
// You may need to call galaxys audio hack after this method
|
||||
boolean isUserRequest = false;
|
||||
routeAudioToReceiver(isUserRequest);
|
||||
}
|
||||
|
||||
|
||||
public String extractADisplayName() {
|
||||
final LinphoneAddress remote = mLc.getRemoteAddress();
|
||||
if (remote == null) return mR.getString(R.string.unknown_incoming_call_name);
|
||||
public static String extractADisplayName(Resources r, LinphoneAddress address) {
|
||||
if (address == null) return r.getString(R.string.unknown_incoming_call_name);
|
||||
|
||||
final String displayName = remote.getDisplayName();
|
||||
final String displayName = address.getDisplayName();
|
||||
if (displayName!=null) {
|
||||
return displayName;
|
||||
} else if (remote.getUserName() != null){
|
||||
return remote.getUserName();
|
||||
} else if (address.getUserName() != null){
|
||||
return address.getUserName();
|
||||
} else {
|
||||
String rms = remote.toString();
|
||||
String rms = address.toString();
|
||||
if (rms != null && rms.length() > 1)
|
||||
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() {
|
||||
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() {
|
||||
stopRinging();
|
||||
mAudioManager.setMode(MODE_IN_CALL);
|
||||
ringingCall = null;
|
||||
}
|
||||
|
||||
// Called on first launch only
|
||||
|
@ -884,13 +960,17 @@ public final class LinphoneManager implements LinphoneCoreListener {
|
|||
e.commit();
|
||||
}
|
||||
|
||||
public void addVideo() {
|
||||
if (!LinphoneManager.getLc().isIncall()) return;
|
||||
if (!reinviteWithVideo()) {
|
||||
serviceListener.onAlreadyInVideoCall();
|
||||
}
|
||||
}
|
||||
private LinphoneCall requestedVideoCall;
|
||||
public boolean addVideo() {
|
||||
requestedVideoCall = mLc.getCurrentCall();
|
||||
if (requestedVideoCall == null) return false;
|
||||
|
||||
if (!reinviteWithVideo()) {
|
||||
listenerDispatcher.onAlreadyInVideoCall();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean acceptCallIfIncomingPending() throws LinphoneCoreException {
|
||||
if (Hacks.needGalaxySAudioHack() || lpm.useGalaxySHack())
|
||||
setAudioModeIncallForGalaxyS();
|
||||
|
@ -902,15 +982,27 @@ public final class LinphoneManager implements LinphoneCoreListener {
|
|||
return false;
|
||||
}
|
||||
|
||||
public String extractIncomingRemoteName() {
|
||||
if (!mR.getBoolean(R.bool.show_full_remote_address_on_incoming_call))
|
||||
return extractADisplayName();
|
||||
public boolean acceptCall(LinphoneCall call) {
|
||||
if (Hacks.needGalaxySAudioHack() || lpm.useGalaxySHack())
|
||||
setAudioModeIncallForGalaxyS();
|
||||
|
||||
LinphoneAddress remote = mLc.getRemoteAddress();
|
||||
if (remote != null)
|
||||
return remote.toString();
|
||||
try {
|
||||
mLc.acceptCall(call);
|
||||
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) {
|
||||
|
@ -938,6 +1030,79 @@ public final class LinphoneManager implements LinphoneCoreListener {
|
|||
|
||||
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() {
|
||||
if (sExited) {
|
||||
// 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();
|
||||
}
|
||||
|
||||
@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;
|
||||
|
||||
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.LinphoneSimpleListener.LinphoneServiceListener;
|
||||
import org.linphone.core.LinphoneCall;
|
||||
import org.linphone.core.LinphoneCoreFactoryImpl;
|
||||
import org.linphone.core.Log;
|
||||
|
@ -35,7 +37,6 @@ import android.app.Notification;
|
|||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.Service;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
|
@ -69,7 +70,7 @@ public final class LinphoneService extends Service implements LinphoneServiceLis
|
|||
private Handler mHandler = new Handler();
|
||||
private static LinphoneService instance;
|
||||
|
||||
static boolean isReady() { return (instance!=null); }
|
||||
public static boolean isReady() { return (instance!=null); }
|
||||
|
||||
/**
|
||||
* @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 Notification mNotif;
|
||||
|
@ -101,7 +101,7 @@ public final class LinphoneService extends Service implements LinphoneServiceLis
|
|||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
|
||||
|
||||
// In case restart after a crash. Main in LinphoneActivity
|
||||
LinphonePreferenceManager.getInstance(this);
|
||||
|
||||
|
@ -116,7 +116,7 @@ public final class LinphoneService extends Service implements LinphoneServiceLis
|
|||
dumpDeviceInformation();
|
||||
dumpInstalledLinphoneInformation();
|
||||
|
||||
mNotificationMgr = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
|
||||
mNotif = new Notification(R.drawable.status_level, "", System.currentTimeMillis());
|
||||
mNotif.iconLevel=IC_LEVEL_ORANGE;
|
||||
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);
|
||||
mNotifContentIntent = PendingIntent.getActivity(this, 0, notifIntent, 0);
|
||||
mNotif.setLatestEventInfo(this, notificationTitle,"", mNotifContentIntent);
|
||||
mNotificationMgr.notify(NOTIF_ID, mNotif);
|
||||
|
||||
|
||||
|
||||
LinphoneManager.createAndStart(this, this);
|
||||
LinphoneManager.getLc().setPresenceInfo(0, null, OnlineStatus.Online);
|
||||
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 ====";
|
||||
private void dumpDeviceInformation() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
@ -170,7 +260,7 @@ public final class LinphoneService extends Service implements LinphoneServiceLis
|
|||
}
|
||||
|
||||
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
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
// Make sure our notification is gone.
|
||||
stopForegroundCompat(NOTIF_ID);
|
||||
|
||||
LinphoneManager.getLcIfManagerNotDestroyedOrNull().setPresenceInfo(0, null, OnlineStatus.Offline);
|
||||
LinphoneManager.destroy(this);
|
||||
|
||||
mNotificationMgr.cancel(NOTIF_ID);
|
||||
instance=null;
|
||||
}
|
||||
|
||||
|
@ -252,6 +343,7 @@ public final class LinphoneService extends Service implements LinphoneServiceLis
|
|||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
|
||||
} else if (state == LinphoneCall.State.StreamsRunning) {
|
||||
if (Version.isVideoCapable()
|
||||
&& getResources().getBoolean(R.bool.autostart_video_activity)
|
||||
&& getResources().getBoolean(R.bool.use_video_activity)
|
||||
&& !VideoCallActivity.launched && LinphoneActivity.isInstanciated()
|
||||
&& 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);
|
||||
}
|
||||
}
|