diff options
author | Hung-ying Tyan <tyanh@google.com> | 2010-06-23 17:58:46 -0700 |
---|---|---|
committer | Hung-ying Tyan <tyanh@google.com> | 2010-06-23 18:01:22 -0700 |
commit | 9ea67392771810ff8baa55d7343b8ebcc4dfc4c2 (patch) | |
tree | ab32cb771c8c35686d35f40b10dbc4ba2fe118f2 | |
parent | ff0fe66a80c78ffbeefb418f67022ac6a0b914d8 (diff) | |
download | android_external_nist-sip-9ea67392771810ff8baa55d7343b8ebcc4dfc4c2.tar.gz android_external_nist-sip-9ea67392771810ff8baa55d7343b8ebcc4dfc4c2.tar.bz2 android_external_nist-sip-9ea67392771810ff8baa55d7343b8ebcc4dfc4c2.zip |
SIP: duplicate PhoneApp for telephony integration development
Change-Id: I62b01c9f7f93ca3d788222aeb483c3a2dd499117
75 files changed, 1306 insertions, 1232 deletions
diff --git a/phone/Android.mk b/phone/Android.mk.sample index c21e7e2..653f77b 100644 --- a/phone/Android.mk +++ b/phone/Android.mk.sample @@ -27,13 +27,10 @@ LOCAL_SRC_FILES += \ src/com/android/phone2/INetworkQueryService.aidl \ src/com/android/phone2/INetworkQueryServiceCallback.aidl -LOCAL_SRC_FILES += $(call all-java-files-under, src2) - LOCAL_PACKAGE_NAME := Phone2 -LOCAL_CERTIFICATE := platform -LOCAL_STATIC_JAVA_LIBRARIES := android.sip +#LOCAL_CERTIFICATE := platform include $(BUILD_PACKAGE) -## Build the test package -#include $(call all-makefiles-under,$(LOCAL_PATH)) +# Build the test package +include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/phone/AndroidManifest.xml b/phone/AndroidManifest.xml index e1679f8..17d1162 100644 --- a/phone/AndroidManifest.xml +++ b/phone/AndroidManifest.xml @@ -20,6 +20,7 @@ android:sharedUserLabel="@string/dialerIconLabel" > + <original-package android:name="com.android.phone2" /> <protected-broadcast android:name="android.intent.action.SERVICE_STATE" /> <protected-broadcast android:name="android.intent.action.RADIO_TECHNOLOGY" /> @@ -82,7 +83,7 @@ android:label="@string/dialerIconLabel" android:icon="@drawable/ic_launcher_phone"> <provider android:name="IccProvider" - android:authorities="icc2" + android:authorities="icc" android:multiprocess="true" android:readPermission="android.permission.READ_CONTACTS" android:writePermission="android.permission.WRITE_CONTACTS" /> diff --git a/phone/MODULE_LICENSE_APACHE2 b/phone/MODULE_LICENSE_APACHE2 deleted file mode 100644 index e69de29..0000000 --- a/phone/MODULE_LICENSE_APACHE2 +++ /dev/null diff --git a/phone/NOTICE b/phone/NOTICE deleted file mode 100644 index c5b1efa..0000000 --- a/phone/NOTICE +++ /dev/null @@ -1,190 +0,0 @@ - - Copyright (c) 2005-2008, 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. - - 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. - - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - diff --git a/phone/res/color-finger/end_call_button_text.xml b/phone/res/color-finger/end_call_button_text.xml new file mode 100644 index 0000000..a570c2b --- /dev/null +++ b/phone/res/color-finger/end_call_button_text.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2010 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. +--> + +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:state_enabled="false" android:color="#80000000"/> + <item android:state_focused="true" android:color="#FF000000"/> + <item android:state_pressed="true" android:color="#FF000000"/> + <item android:state_selected="true" android:color="#FF000000"/> + <item android:color="@color/incall_endButtonLabel"/> <!-- not selected --> +</selector> + diff --git a/phone/res/color-finger/in_call_button_text.xml b/phone/res/color-finger/in_call_button_text.xml new file mode 100644 index 0000000..4a5a4a4 --- /dev/null +++ b/phone/res/color-finger/in_call_button_text.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2010 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. +--> + +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:state_enabled="false" android:color="#ff808080"/> + <item android:state_focused="true" android:color="#FF000000"/> + <item android:state_pressed="true" android:color="#FF000000"/> + <item android:state_selected="true" android:color="#FF000000"/> + <item android:color="#FFFFFFFF"/> <!-- not selected --> +</selector> + diff --git a/phone/res/drawable-hdpi/ic_btn_back.png b/phone/res/drawable-hdpi/ic_btn_back.png Binary files differnew file mode 100755 index 0000000..9051cb1 --- /dev/null +++ b/phone/res/drawable-hdpi/ic_btn_back.png diff --git a/phone/res/drawable-hdpi/ic_btn_next.png b/phone/res/drawable-hdpi/ic_btn_next.png Binary files differnew file mode 100755 index 0000000..ad00a95 --- /dev/null +++ b/phone/res/drawable-hdpi/ic_btn_next.png diff --git a/phone/res/drawable-mdpi/ic_btn_back.png b/phone/res/drawable-mdpi/ic_btn_back.png Binary files differnew file mode 100644 index 0000000..c9bff4c --- /dev/null +++ b/phone/res/drawable-mdpi/ic_btn_back.png diff --git a/phone/res/layout-finger/dialpad.xml b/phone/res/layout-finger/dialpad.xml index 135f0fb..98f8418 100644 --- a/phone/res/layout-finger/dialpad.xml +++ b/phone/res/layout-finger/dialpad.xml @@ -14,7 +14,7 @@ limitations under the License. --> -<com.android.phone2.ButtonGridLayout xmlns:android="http://schemas.android.com/apk/res/android" +<com.android.phone.ButtonGridLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/dialpad" android:paddingLeft="7dp" android:paddingRight="7dp" @@ -108,5 +108,5 @@ android:src="@drawable/dial_num_pound" android:background="@drawable/btn_dial" /> -</com.android.phone2.ButtonGridLayout> +</com.android.phone.ButtonGridLayout> diff --git a/phone/res/layout-finger/dtmf_twelve_key_dialer.xml b/phone/res/layout-finger/dtmf_twelve_key_dialer.xml index b0202e2..e8f971b 100644 --- a/phone/res/layout-finger/dtmf_twelve_key_dialer.xml +++ b/phone/res/layout-finger/dtmf_twelve_key_dialer.xml @@ -77,7 +77,7 @@ </LinearLayout> <!-- drawer content dialer view --> - <com.android.phone2.DTMFTwelveKeyDialerView + <com.android.phone.DTMFTwelveKeyDialerView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/dtmf_dialer" android:layout_width="match_parent" @@ -113,6 +113,6 @@ android:layout_width="match_parent" android:layout_weight="1"/> - </com.android.phone2.DTMFTwelveKeyDialerView> + </com.android.phone.DTMFTwelveKeyDialerView> </SlidingDrawer> diff --git a/phone/res/layout-finger/non_drawer_dialpad.xml b/phone/res/layout-finger/non_drawer_dialpad.xml index b90480d..fe804e8 100644 --- a/phone/res/layout-finger/non_drawer_dialpad.xml +++ b/phone/res/layout-finger/non_drawer_dialpad.xml @@ -22,7 +22,7 @@ dtmf_twelve_key_dialer.xml and dialpad.xml, but in a more compact layout, and without the SlidingDrawer container. --> -<com.android.phone2.DTMFTwelveKeyDialerView +<com.android.phone.DTMFTwelveKeyDialerView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/non_drawer_dtmf_dialer" android:layout_width="match_parent" @@ -54,7 +54,7 @@ android:clickable="false"/> <!-- The dialpad itself --> - <com.android.phone2.ButtonGridLayout + <com.android.phone.ButtonGridLayout android:id="@+id/dialpad" android:paddingLeft="7dp" android:paddingRight="7dp" @@ -147,6 +147,6 @@ android:src="@drawable/dial_num_pound" android:background="@drawable/btn_dial_green" /> - </com.android.phone2.ButtonGridLayout> + </com.android.phone.ButtonGridLayout> -</com.android.phone2.DTMFTwelveKeyDialerView> +</com.android.phone.DTMFTwelveKeyDialerView> diff --git a/phone/res/layout-long-finger/dialpad.xml b/phone/res/layout-long-finger/dialpad.xml index 510b0b6..43311ba 100644 --- a/phone/res/layout-long-finger/dialpad.xml +++ b/phone/res/layout-long-finger/dialpad.xml @@ -18,7 +18,7 @@ Tall screen version with taller buttons. --> -<com.android.phone2.ButtonGridLayout xmlns:android="http://schemas.android.com/apk/res/android" +<com.android.phone.ButtonGridLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/dialpad" android:paddingLeft="7dp" android:paddingRight="7dp" @@ -112,5 +112,5 @@ android:src="@drawable/dial_num_pound" android:background="@drawable/btn_dial" /> -</com.android.phone2.ButtonGridLayout> +</com.android.phone.ButtonGridLayout> diff --git a/phone/res/layout-long-finger/non_drawer_dialpad.xml b/phone/res/layout-long-finger/non_drawer_dialpad.xml index 34a5b93..ac21ed0 100644 --- a/phone/res/layout-long-finger/non_drawer_dialpad.xml +++ b/phone/res/layout-long-finger/non_drawer_dialpad.xml @@ -22,7 +22,7 @@ dtmf_twelve_key_dialer.xml and dialpad.xml, but in a more compact layout, and without the SlidingDrawer container. --> -<com.android.phone2.DTMFTwelveKeyDialerView +<com.android.phone.DTMFTwelveKeyDialerView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/non_drawer_dtmf_dialer" android:layout_width="match_parent" @@ -54,7 +54,7 @@ android:clickable="false"/> <!-- The dialpad itself --> - <com.android.phone2.ButtonGridLayout + <com.android.phone.ButtonGridLayout android:id="@+id/dialpad" android:paddingLeft="7dp" android:paddingRight="7dp" @@ -147,6 +147,6 @@ android:src="@drawable/dial_num_pound" android:background="@drawable/btn_dial_green" /> - </com.android.phone2.ButtonGridLayout> + </com.android.phone.ButtonGridLayout> -</com.android.phone2.DTMFTwelveKeyDialerView> +</com.android.phone.DTMFTwelveKeyDialerView> diff --git a/phone/res/layout/call_card.xml b/phone/res/layout/call_card.xml index f32edb5..663f114 100644 --- a/phone/res/layout/call_card.xml +++ b/phone/res/layout/call_card.xml @@ -63,6 +63,7 @@ android:layout_height="101dp" android:layout_marginTop="-6dip" android:background="@drawable/incall_photo_border_med" + android:contentDescription="@string/onHold" /> </LinearLayout> diff --git a/phone/res/layout/call_card_person_info.xml b/phone/res/layout/call_card_person_info.xml index e2c9489..b5a6901 100644 --- a/phone/res/layout/call_card_person_info.xml +++ b/phone/res/layout/call_card_person_info.xml @@ -41,6 +41,7 @@ android:layout_height="166dp" android:layout_centerHorizontal="true" android:background="@drawable/incall_photo_border_lg" + android:contentDescription="@string/contactPhoto" /> <!-- The big "Manage conference" button that we show in place of diff --git a/phone/res/layout/caller_in_conference.xml b/phone/res/layout/caller_in_conference.xml index 630b44b..93406ec 100644 --- a/phone/res/layout/caller_in_conference.xml +++ b/phone/res/layout/caller_in_conference.xml @@ -36,7 +36,8 @@ android:layout_height="46dp" android:layout_marginTop="2dp" android:layout_marginLeft="6dp" - android:scaleType="center"/> + android:scaleType="center" + android:contentDescription="@string/onscreenEndCallText" /> <!-- Caller information --> <LinearLayout @@ -97,7 +98,8 @@ android:layout_height="46dp" android:layout_marginTop="2dp" android:layout_marginRight="6dp" - android:scaleType="center"/> + android:scaleType="center" + android:contentDescription="@string/goPrivate"/> </LinearLayout> <!-- End of single list element --> diff --git a/phone/res/layout/incall_screen.xml b/phone/res/layout/incall_screen.xml index e291ac1..aa313e3 100644 --- a/phone/res/layout/incall_screen.xml +++ b/phone/res/layout/incall_screen.xml @@ -38,7 +38,7 @@ > <!-- The "Call Card", which displays info about the currently active phone call(s) on the device. See call_card.xml. --> - <com.android.phone2.CallCard android:id="@+id/callCard" + <com.android.phone.CallCard android:id="@+id/callCard" android:layout_width="match_parent" android:layout_height="match_parent" /> @@ -68,9 +68,11 @@ widget needs to be be a direct child of a FrameLayout anyway.) This is used only on devices that do *not* have an onscreen InCallTouchUi widget.--> - <!-- TODO: this should be a ViewStub, and should only get inflated - on platforms that need it. --> - <include layout="@layout/dtmf_twelve_key_dialer"/> + <ViewStub android:id="@+id/dtmf_dialer_stub" + android:layout="@layout/dtmf_twelve_key_dialer" + android:layout_width="match_parent" + android:layout_height="match_parent" + /> <!-- Finally, the "touch lock" overlay, drawn on top of the DTMF dialpad (after some delay) to prevent false touches from @@ -103,34 +105,43 @@ <!-- In-call onscreen touch controls, used on some platforms. --> <!-- TODO: if this widget ends up being totally unused on some platforms, then this should probably be a ViewStub. --> - <com.android.phone2.InCallTouchUi + <com.android.phone.InCallTouchUi android:id="@+id/inCallTouchUi" android:layout_width="match_parent" android:layout_height="match_parent" /> - <!-- Frame where the provider's badge will be + <!-- Layout where the provider's badge will be inflated. The badge must fit in the available height. The badge is displayed for 5s on top of the contact's picture. --> - <FrameLayout android:id="@+id/inCallProviderOverlay" + <LinearLayout android:id="@+id/inCallProviderOverlay" android:background="@drawable/dialog_bg_calling_via" android:layout_width="match_parent" - android:layout_height="wrap_content" - android:minHeight="88dip" + android:layout_height="88dip" android:layout_marginTop="8dip" android:layout_gravity="top" - android:visibility="gone"> + android:gravity="center" + android:visibility="gone" + android:orientation="horizontal"> + + <ImageView android:id="@+id/callingViaIcon" + android:layout_width="40dip" + android:layout_height="40dip" + /> <TextView android:id="@+id/callingVia" android:text="@string/calling_via_template" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="center" + android:layout_weight="1" + android:layout_width="0dip" + android:layout_height="match_parent" + android:textAppearance="?android:attr/textAppearanceSmallInverse" android:gravity="center" - android:textAppearance="?android:attr/textAppearanceMediumInverse" - android:textSize="16sp" /> - </FrameLayout> + <View + android:layout_width="40dip" + android:layout_height="40dip" + /> + </LinearLayout> </FrameLayout> diff --git a/phone/res/layout/incall_touch_ui.xml b/phone/res/layout/incall_touch_ui.xml index a85f8cc..0217d02 100644 --- a/phone/res/layout/incall_touch_ui.xml +++ b/phone/res/layout/incall_touch_ui.xml @@ -64,7 +64,8 @@ android:visibility="gone"> <ImageButton android:id="@+id/holdButton" style="@style/InCallRoundTouchButton" - android:src="@drawable/ic_in_call_touch_round_hold" /> + android:src="@drawable/ic_in_call_touch_round_hold" + android:contentDescription="@string/onscreenHoldText" /> <TextView android:id="@+id/holdButtonLabel" style="@style/InCallRoundButtonLabel" /> </LinearLayout> @@ -78,7 +79,8 @@ android:visibility="gone"> <ImageButton android:id="@+id/swapButton" style="@style/InCallRoundTouchButton" - android:src="@drawable/ic_in_call_touch_round_swap" /> + android:src="@drawable/ic_in_call_touch_round_swap" + android:contentDescription="@string/onscreenSwapCallsText"/> <TextView android:id="@+id/swapButtonLabel" style="@style/InCallRoundButtonLabel" /> </LinearLayout> @@ -94,7 +96,8 @@ android:visibility="gone"> <ImageButton android:id="@+id/cdmaMergeButton" style="@style/InCallRoundTouchButton" - android:src="@drawable/ic_in_call_touch_round_merge_call" /> + android:src="@drawable/ic_in_call_touch_round_merge_call" + android:contentDescription="@string/onscreenMergeCallsText" /> <TextView style="@style/InCallRoundButtonLabel" android:text="@string/onscreenMergeCallsText" /> @@ -102,9 +105,11 @@ <!-- DTMF dialpad shown in the upper part of the screen (above the main cluster of buttons.) --> - <!-- TODO: this should be a ViewStub, and should only get inflated - when first needed. --> - <include layout="@layout/non_drawer_dialpad"/> + <ViewStub android:id="@+id/non_drawer_dialpad_stub" + android:layout="@layout/non_drawer_dialpad" + android:layout_width="match_parent" + android:layout_height="match_parent" + /> <!-- Main cluster of onscreen buttons on the lower part of the screen. --> <LinearLayout android:id="@+id/bottomButtons" @@ -177,7 +182,7 @@ android:layout_height="wrap_content" android:text="@string/onscreenEndCallText" android:drawableTop="@drawable/ic_in_call_touch_end" - android:textColor="@color/incall_endButtonLabel" + android:textColor="@color/end_call_button_text" /> <!-- "Dialpad" --> diff --git a/phone/res/layout/ongoing_call_notification.xml b/phone/res/layout/ongoing_call_notification.xml index a7302d3..e08d1cb 100644 --- a/phone/res/layout/ongoing_call_notification.xml +++ b/phone/res/layout/ongoing_call_notification.xml @@ -15,45 +15,53 @@ --> <!-- Layout file for the custom "expanded view" used by the ongoing call - Notification; see NotificationMgr.updateInCallNotification(). --> + Notification; see NotificationMgr.updateInCallNotification(). + This is largely copied from status_bar_latest_event_content, + but with some customizations --> + <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:orientation="horizontal" - android:baselineAligned="false" - android:gravity="center_vertical" - android:layout_width="match_parent" - android:layout_height="65sp" - android:background="@android:drawable/status_bar_item_background" - > + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical" + android:paddingTop="7dp" + android:paddingLeft="5dp" + > - <ImageView android:id="@+id/icon" - android:layout_width="wrap_content" + <LinearLayout + android:layout_width="match_parent" android:layout_height="wrap_content" - android:paddingLeft="4dip" - android:layout_marginRight="6dip" /> - - <LinearLayout - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:orientation="vertical" - > - <!-- The appearance of these 2 lines of text matches the other - kinds of notifications (see status_bar_latest_event.xml). - TODO: There should probably be common styles for these, though. --> - <Chronometer android:id="@+id/text1" - android:textStyle="bold" - android:textSize="18sp" - android:textColor="#ff000000" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:singleLine="true" - /> - <TextView android:id="@+id/text2" - android:textSize="14sp" - android:textColor="#ff000000" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:singleLine="true" - /> - </LinearLayout> - + android:orientation="horizontal" + android:paddingTop="3dp" + > + <ImageView android:id="@+id/icon" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:paddingLeft="4dip" + android:layout_marginRight="6dip" /> + <Chronometer android:id="@+id/text1" + android:textStyle="bold" + android:textSize="18sp" + android:textColor="#ff000000" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:singleLine="true" + /> + </LinearLayout> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + > + <TextView android:id="@+id/text2" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_weight="1" + android:textColor="#ff000000" + android:singleLine="true" + android:ellipsize="marquee" + android:fadingEdge="horizontal" + android:textSize="14sp" + android:paddingLeft="4dp" + /> + </LinearLayout> </LinearLayout> diff --git a/phone/res/layout/otacall_card.xml b/phone/res/layout/otacall_card.xml index 246c042..23db2fc 100644 --- a/phone/res/layout/otacall_card.xml +++ b/phone/res/layout/otacall_card.xml @@ -76,7 +76,7 @@ /> <!-- DTMF Dialer section --> - <com.android.phone2.DTMFTwelveKeyDialerView + <com.android.phone.DTMFTwelveKeyDialerView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/otaDtmfDialer" android:layout_width="match_parent" @@ -92,7 +92,7 @@ <!-- Keypad section --> <include layout="@layout/dialpad" /> - </com.android.phone2.DTMFTwelveKeyDialerView> + </com.android.phone.DTMFTwelveKeyDialerView> </LinearLayout> @@ -136,6 +136,8 @@ <!-- "End" button --> <Button android:id="@+id/otaEndButton" android:text="@string/ota_call_end" + android:drawableLeft="@drawable/ic_btn_back" + android:drawablePadding="3dip" style="@style/ccOtaSkipButton" /> </RelativeLayout> @@ -147,6 +149,8 @@ <!-- "Next" button --> <Button android:id="@+id/otaNextButton" android:text="@string/ota_next" + android:drawableRight="@drawable/ic_btn_next" + android:drawablePadding="10dip" style="@style/ccOtaNextButton" /> <!-- "Try Again" button --> diff --git a/phone/res/layout/pref_dialog_editphonenumber.xml b/phone/res/layout/pref_dialog_editphonenumber.xml index fc25d8c..8031c70 100644 --- a/phone/res/layout/pref_dialog_editphonenumber.xml +++ b/phone/res/layout/pref_dialog_editphonenumber.xml @@ -52,7 +52,8 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="10dip" - android:src="@drawable/ic_button_contacts" /> + android:src="@drawable/ic_button_contacts" + android:contentDescription="@string/selectContact" /> </LinearLayout> </LinearLayout> diff --git a/phone/res/values/config.xml b/phone/res/values/config.xml index 5c84336..3e9dee0 100644 --- a/phone/res/values/config.xml +++ b/phone/res/values/config.xml @@ -119,4 +119,8 @@ <!-- Determines if device implements a noise suppression device for in call audio--> <bool name="has_in_call_noise_suppression">false</bool> + <!-- Determines if the current device should allow emergency numbers + to be logged in the Call Log. --> + <bool name="allow_emergency_numbers_in_call_log">true</bool> + </resources> diff --git a/phone/res/values/strings.xml b/phone/res/values/strings.xml index f6d4839..1ff406c 100755 --- a/phone/res/values/strings.xml +++ b/phone/res/values/strings.xml @@ -85,6 +85,8 @@ <string name="callFailed_cdma_preempted">CDMA: Preempted.</string> <!-- In-call screen: call failure reason (Only Emergency calls are possible)--> <string name="callFailed_cdma_notEmergency">Only Emergency calls are possible.</string> + <!-- In-call screen: call failure reason (Dialed number doesn't exist) --> + <string name="callFailed_unobtainable_number">Invalid Number</string> <!-- In-call screen: status label for a conference call --> <string name="confCall">Conference call</string> <!-- In-call screen: call lost dialog text --> @@ -323,6 +325,8 @@ <string name="response_error">Unexpected response from network.</string> <!-- Status message displayed in the "Call settings error" dialog --> <string name="exception_error">Network or SIM card error.</string> + <!-- Status message displayed in the "Call settings error" dialog when operation fails due to FDN --> + <string name="fdn_only_error">Operations are only allowed on fixed dialing numbers.</string> <!-- Status message displayed in the "Call settings error" dialog --> <string name="radio_off_error">Please turn on the radio before viewing these settings.</string> <!-- Button label used to dismiss the "Call settings error" dialog --> @@ -655,14 +659,14 @@ <item>"1"</item> <item>"2"</item> </string-array> - <string name="subscription_title">CDMA Subscription TEST</string> - <string name="subscription_summary">Change between RUIM/SIM and NV</string> - <string name="subscription_dialogtitle">subscription</string> - <string-array name="subscription_choices"> + <string name="cdma_subscription_title">CDMA Subscription</string> + <string name="cdma_subscription_summary">Change between RUIM/SIM and NV</string> + <string name="cdma_subscription_dialogtitle">subscription</string> + <string-array name="cdma_subscription_choices"> <item>RUIM/SIM</item> <item>NV</item> </string-array> - <string-array name="subscription_values"> + <string-array name="cdma_subscription_values"> <item>"0"</item> <item>"1"</item> </string-array> @@ -1189,4 +1193,10 @@ <!-- Incoming call hint shown on tab (must be kept very short): decline incoming call --> <string name="slide_to_decline_hint">Decline</string> + <!-- Use this as a default to describe the contact photo; currently for screen readers through accessibility. --> + <string name="contactPhoto">contact photo</string> + <!-- Use this to describe the separate conference call button; currently for screen readers through accessibility. --> + <string name="goPrivate">go private</string> + <!-- Use this to describe the select contact button in EditPhoneNumberPreference; currently for screen readers through accessibility. --> + <string name="selectContact">select contact</string> </resources> diff --git a/phone/res/values/styles.xml b/phone/res/values/styles.xml index fdc1766..0850ade 100644 --- a/phone/res/values/styles.xml +++ b/phone/res/values/styles.xml @@ -176,7 +176,7 @@ <item name="android:layout_marginLeft">8dip</item> <item name="android:layout_marginRight">8dip</item> <item name="android:textAppearance">?android:attr/textAppearanceSmall</item> - <item name="android:textColor">?android:attr/textColorPrimary</item> + <item name="android:textColor">@color/in_call_button_text</item> <item name="android:singleLine">true</item> <item name="android:ellipsize">marquee</item> </style> @@ -190,7 +190,7 @@ <item name="android:layout_marginLeft">8dip</item> <item name="android:layout_marginRight">8dip</item> <item name="android:textAppearance">?android:attr/textAppearanceSmall</item> - <item name="android:textColor">?android:attr/textColorPrimary</item> + <item name="android:textColor">@color/in_call_button_text</item> <item name="android:singleLine">true</item> <item name="android:ellipsize">marquee</item> </style> diff --git a/phone/res/xml/cdma_options.xml b/phone/res/xml/cdma_options.xml index e2ff8df..3ca8c2f 100644 --- a/phone/res/xml/cdma_options.xml +++ b/phone/res/xml/cdma_options.xml @@ -17,11 +17,20 @@ <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" xmlns:settings="http://schemas.android.com/apk/res/com.android.phone2"> - <com.android.phone2.CdmaRoamingListPreference - android:key="cdma_roaming_mode_key" + <com.android.phone2.CdmaSystemSelectListPreference + android:key="cdma_system_select_key" android:title="@string/cdma_system_select_title" android:summary="@string/cdma_system_select_summary" android:entries="@array/cdma_system_select_choices" android:entryValues="@array/cdma_system_select_values" android:dialogTitle="@string/cdma_system_select_dialogtitle" /> + + <com.android.phone2.CdmaSubscriptionListPreference + android:key="cdma_subscription_key" + android:title="@string/cdma_subscription_title" + android:summary="@string/cdma_subscription_summary" + android:entries="@array/cdma_subscription_choices" + android:entryValues="@array/cdma_subscription_values" + android:dialogTitle="@string/cdma_subscription_dialogtitle" /> + </PreferenceScreen> diff --git a/phone/res/xml/network_setting.xml b/phone/res/xml/network_setting.xml index 0c579a3..43b688a 100644 --- a/phone/res/xml/network_setting.xml +++ b/phone/res/xml/network_setting.xml @@ -48,26 +48,4 @@ android:entryValues="@array/preferred_network_mode_values" android:dialogTitle="@string/preferred_network_mode_dialogtitle" /> - <PreferenceScreen - android:key="gsm_umts_options_key" - android:title="@string/gsm_umts_options" - android:persistent="false"> - - <intent android:action="android.intent.action.MAIN" - android:targetPackage="com.android.phone2" - android:targetClass="com.android.phone2.GsmUmtsOptions" /> - - </PreferenceScreen> - - <PreferenceScreen - android:key="cdma_options_key" - android:title="@string/cdma_options" - android:persistent="false"> - - <intent android:action="android.intent.action.MAIN" - android:targetPackage="com.android.phone2" - android:targetClass="com.android.phone2.CdmaOptions" /> - - </PreferenceScreen> - </PreferenceScreen> diff --git a/phone/src/com/android/phone2/BluetoothHandsfree.java b/phone/src/com/android/phone2/BluetoothHandsfree.java index 63ad4f3..29a6c8b 100644 --- a/phone/src/com/android/phone2/BluetoothHandsfree.java +++ b/phone/src/com/android/phone2/BluetoothHandsfree.java @@ -241,7 +241,7 @@ public class BluetoothHandsfree { return mHeadset.isConnected(); } - /* package */ void connectHeadset(HeadsetBase headset, int headsetType) { + /* package */ synchronized void connectHeadset(HeadsetBase headset, int headsetType) { mHeadset = headset; mHeadsetType = headsetType; if (mHeadsetType == TYPE_HEADSET) { @@ -277,7 +277,7 @@ public class BluetoothHandsfree { resetAtState(); } - private void resetAtState() { + /* package */ synchronized void resetAtState() { mClip = false; mIndicatorsEnabled = false; mServiceConnectionEstablished = false; diff --git a/phone/src/com/android/phone2/BluetoothHeadsetService.java b/phone/src/com/android/phone2/BluetoothHeadsetService.java index 1d78cdb..f36309e 100644 --- a/phone/src/com/android/phone2/BluetoothHeadsetService.java +++ b/phone/src/com/android/phone2/BluetoothHeadsetService.java @@ -437,6 +437,7 @@ public class BluetoothHeadsetService extends Service { public void handleMessage(Message msg) { switch (msg.what) { case HeadsetBase.RFCOMM_DISCONNECTED: + mBtHandsfree.resetAtState(); setState(BluetoothHeadset.STATE_DISCONNECTED, BluetoothHeadset.RESULT_FAILURE, BluetoothHeadset.REMOTE_DISCONNECT); break; @@ -490,7 +491,8 @@ public class BluetoothHeadsetService extends Service { } } - private void getSdpRecordsAndConnect() { + private synchronized void getSdpRecordsAndConnect() { + if (mRemoteDevice == null) return; ParcelUuid[] uuids = mRemoteDevice.getUuids(); if (uuids != null) { if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.Handsfree)) { diff --git a/phone/src/com/android/phone2/CLIRListPreference.java b/phone/src/com/android/phone2/CLIRListPreference.java index 0e81513..1b6dca7 100644 --- a/phone/src/com/android/phone2/CLIRListPreference.java +++ b/phone/src/com/android/phone2/CLIRListPreference.java @@ -1,11 +1,9 @@ package com.android.phone2; -import static com.android.phone2.TimeConsumingPreferenceActivity.EXCEPTION_ERROR; import static com.android.phone2.TimeConsumingPreferenceActivity.RESPONSE_ERROR; - +import com.android.internal.telephony.CommandException; import com.android.internal.telephony.CommandsInterface; import com.android.internal.telephony.Phone; -import com.android.internal.telephony.PhoneFactory; import android.content.Context; import android.os.AsyncResult; @@ -29,7 +27,7 @@ public class CLIRListPreference extends ListPreference { public CLIRListPreference(Context context, AttributeSet attrs) { super(context, attrs); - phone = PhoneFactory.getDefaultPhone(); + phone = PhoneApp.getPhone(); } public CLIRListPreference(Context context) { @@ -133,8 +131,7 @@ public class CLIRListPreference extends ListPreference { clirArray = null; if (ar.exception != null) { if (DBG) Log.d(LOG_TAG, "handleGetCLIRResponse: ar.exception="+ar.exception); - setEnabled(false); - tcpListener.onError(CLIRListPreference.this, EXCEPTION_ERROR); + tcpListener.onException(CLIRListPreference.this, (CommandException) ar.exception); } else if (ar.userObj instanceof Throwable) { tcpListener.onError(CLIRListPreference.this, RESPONSE_ERROR); } else { diff --git a/phone/src/com/android/phone2/CallCard.java b/phone/src/com/android/phone2/CallCard.java index 47d640c..5c39c5d 100755 --- a/phone/src/com/android/phone2/CallCard.java +++ b/phone/src/com/android/phone2/CallCard.java @@ -984,6 +984,10 @@ public class CallCard extends FrameLayout resID = R.string.callFailed_outOfService; break; + case UNOBTAINABLE_NUMBER: + resID = R.string.callFailed_unobtainable_number; + break; + default: resID = R.string.card_title_call_ended; break; diff --git a/phone/src/com/android/phone2/CallFeaturesSetting.java b/phone/src/com/android/phone2/CallFeaturesSetting.java index f0f8e31..9f9f2d8 100644 --- a/phone/src/com/android/phone2/CallFeaturesSetting.java +++ b/phone/src/com/android/phone2/CallFeaturesSetting.java @@ -49,7 +49,6 @@ import android.widget.ListAdapter; import com.android.internal.telephony.CallForwardInfo; import com.android.internal.telephony.CommandsInterface; import com.android.internal.telephony.Phone; -import com.android.internal.telephony.PhoneFactory; import com.android.internal.telephony.cdma.TtyIntent; import java.util.Collection; @@ -1304,7 +1303,7 @@ public class CallFeaturesSetting extends PreferenceActivity protected void onCreate(Bundle icicle) { super.onCreate(icicle); if (DBG) log("Creating activity"); - mPhone = PhoneFactory.getDefaultPhone(); + mPhone = PhoneApp.getPhone(); addPreferencesFromResource(R.xml.call_feature_setting); diff --git a/phone/src/com/android/phone2/CallForwardEditPreference.java b/phone/src/com/android/phone2/CallForwardEditPreference.java index a30b3f9..41688bf 100644 --- a/phone/src/com/android/phone2/CallForwardEditPreference.java +++ b/phone/src/com/android/phone2/CallForwardEditPreference.java @@ -1,9 +1,9 @@ package com.android.phone2; import com.android.internal.telephony.CallForwardInfo; +import com.android.internal.telephony.CommandException; import com.android.internal.telephony.CommandsInterface; import com.android.internal.telephony.Phone; -import com.android.internal.telephony.PhoneFactory; import android.app.AlertDialog; import android.content.Context; @@ -16,7 +16,6 @@ import android.text.TextUtils; import android.util.AttributeSet; import android.util.Log; -import static com.android.phone2.TimeConsumingPreferenceActivity.EXCEPTION_ERROR; import static com.android.phone2.TimeConsumingPreferenceActivity.RESPONSE_ERROR; public class CallForwardEditPreference extends EditPhoneNumberPreference { @@ -36,7 +35,7 @@ public class CallForwardEditPreference extends EditPhoneNumberPreference { public CallForwardEditPreference(Context context, AttributeSet attrs) { super(context, attrs); - phone = PhoneFactory.getDefaultPhone(); + phone = PhoneApp.getPhone(); mSummaryOnTemplate = this.getSummaryOn(); TypedArray a = context.obtainStyledAttributes(attrs, @@ -178,8 +177,8 @@ public class CallForwardEditPreference extends EditPhoneNumberPreference { callForwardInfo = null; if (ar.exception != null) { if (DBG) Log.d(LOG_TAG, "handleGetCFResponse: ar.exception=" + ar.exception); - setEnabled(false); - tcpListener.onError(CallForwardEditPreference.this, EXCEPTION_ERROR); + tcpListener.onException(CallForwardEditPreference.this, + (CommandException) ar.exception); } else { if (ar.userObj instanceof Throwable) { tcpListener.onError(CallForwardEditPreference.this, RESPONSE_ERROR); diff --git a/phone/src/com/android/phone2/CallNotifier.java b/phone/src/com/android/phone2/CallNotifier.java index 9df72ab..5d20895 100755 --- a/phone/src/com/android/phone2/CallNotifier.java +++ b/phone/src/com/android/phone2/CallNotifier.java @@ -155,7 +155,7 @@ public class CallNotifier extends Handler private static final int TONE_RELATIVE_VOLUME_SIGNALINFO = 80; private Call.State mPreviousCdmaCallState; - private boolean mCdmaVoicePrivacyState = false; + private boolean mVoicePrivacyState = false; private boolean mIsCdmaRedialCall = false; // Emergency call tone and vibrate: @@ -180,39 +180,19 @@ public class CallNotifier extends Handler mAudioManager = (AudioManager) mPhone.getContext().getSystemService(Context.AUDIO_SERVICE); - mPhone.registerForNewRingingConnection(this, PHONE_NEW_RINGING_CONNECTION, null); - mPhone.registerForPreciseCallStateChanged(this, PHONE_STATE_CHANGED, null); - mPhone.registerForDisconnect(this, PHONE_DISCONNECT, null); - mPhone.registerForUnknownConnection(this, PHONE_UNKNOWN_CONNECTION_APPEARED, null); - mPhone.registerForIncomingRing(this, PHONE_INCOMING_RING, null); - - if (mPhone.getPhoneType() == Phone.PHONE_TYPE_CDMA) { - mPhone.registerForCdmaOtaStatusChange(this, EVENT_OTA_PROVISION_CHANGE, null); - - if (DBG) log("Registering for Call Waiting, Signal and Display Info."); - mPhone.registerForCallWaiting(this, PHONE_CDMA_CALL_WAITING, null); - mPhone.registerForDisplayInfo(this, PHONE_STATE_DISPLAYINFO, null); - mPhone.registerForSignalInfo(this, PHONE_STATE_SIGNALINFO, null); - mPhone.registerForInCallVoicePrivacyOn(this, PHONE_ENHANCED_VP_ON, null); - mPhone.registerForInCallVoicePrivacyOff(this, PHONE_ENHANCED_VP_OFF, null); - - // Instantiate the ToneGenerator for SignalInfo and CallWaiting - // TODO: We probably don't need the mSignalInfoToneGenerator instance - // around forever. Need to change it so as to create a ToneGenerator instance only - // when a tone is being played and releases it after its done playing. - try { - mSignalInfoToneGenerator = new ToneGenerator(AudioManager.STREAM_VOICE_CALL, - TONE_RELATIVE_VOLUME_SIGNALINFO); - } catch (RuntimeException e) { - Log.w(LOG_TAG, "CallNotifier: Exception caught while creating " + - "mSignalInfoToneGenerator: " + e); - mSignalInfoToneGenerator = null; - } - } - - if (mPhone.getPhoneType() == Phone.PHONE_TYPE_GSM) { - mPhone.registerForRingbackTone(this, PHONE_RINGBACK_TONE, null); - mPhone.registerForResendIncallMute(this, PHONE_RESEND_MUTE, null); + registerForNotifications(); + + // Instantiate the ToneGenerator for SignalInfo and CallWaiting + // TODO: We probably don't need the mSignalInfoToneGenerator instance + // around forever. Need to change it so as to create a ToneGenerator instance only + // when a tone is being played and releases it after its done playing. + try { + mSignalInfoToneGenerator = new ToneGenerator(AudioManager.STREAM_VOICE_CALL, + TONE_RELATIVE_VOLUME_SIGNALINFO); + } catch (RuntimeException e) { + Log.w(LOG_TAG, "CallNotifier: Exception caught while creating " + + "mSignalInfoToneGenerator: " + e); + mSignalInfoToneGenerator = null; } mRinger = ringer; @@ -328,10 +308,10 @@ public class CallNotifier extends Handler case PHONE_ENHANCED_VP_ON: if (DBG) log("PHONE_ENHANCED_VP_ON..."); - if (!mCdmaVoicePrivacyState) { + if (!mVoicePrivacyState) { int toneToPlay = InCallTonePlayer.TONE_VOICE_PRIVACY; new InCallTonePlayer(toneToPlay).start(); - mCdmaVoicePrivacyState = true; + mVoicePrivacyState = true; // Update the VP icon: NotificationMgr.getDefault().updateInCallNotification(); } @@ -339,10 +319,10 @@ public class CallNotifier extends Handler case PHONE_ENHANCED_VP_OFF: if (DBG) log("PHONE_ENHANCED_VP_OFF..."); - if (mCdmaVoicePrivacyState) { + if (mVoicePrivacyState) { int toneToPlay = InCallTonePlayer.TONE_VOICE_PRIVACY; new InCallTonePlayer(toneToPlay).start(); - mCdmaVoicePrivacyState = false; + mVoicePrivacyState = false; // Update the VP icon: NotificationMgr.getDefault().updateInCallNotification(); } @@ -389,7 +369,7 @@ public class CallNotifier extends Handler } // Incoming calls are totally ignored if OTA call is active - if (mPhone.getPhoneType() == Phone.PHONE_TYPE_CDMA) { + if (TelephonyCapabilities.supportsOtasp(mPhone)) { boolean activateState = (mApplication.cdmaOtaScreenState.otaScreenState == OtaUtils.CdmaOtaScreenState.OtaScreenState.OTA_STATUS_ACTIVATION); boolean dialogState = (mApplication.cdmaOtaScreenState.otaScreenState @@ -409,9 +389,7 @@ public class CallNotifier extends Handler if (c != null && c.isRinging()) { // Stop any signalInfo tone being played on receiving a Call - if (mPhone.getPhoneType() == Phone.PHONE_TYPE_CDMA) { - stopSignalInfoTone(); - } + stopSignalInfoTone(); Call.State state = c.getState(); // State will be either INCOMING or WAITING. @@ -741,36 +719,26 @@ public class CallNotifier extends Handler mPhone.unregisterForInCallVoicePrivacyOff(this); // Register all events new to the new active phone + registerForNotifications(); + } + + private void registerForNotifications() { mPhone.registerForNewRingingConnection(this, PHONE_NEW_RINGING_CONNECTION, null); mPhone.registerForPreciseCallStateChanged(this, PHONE_STATE_CHANGED, null); mPhone.registerForDisconnect(this, PHONE_DISCONNECT, null); mPhone.registerForUnknownConnection(this, PHONE_UNKNOWN_CONNECTION_APPEARED, null); mPhone.registerForIncomingRing(this, PHONE_INCOMING_RING, null); - if (mPhone.getPhoneType() == Phone.PHONE_TYPE_CDMA) { - if (DBG) log("Registering for Call Waiting, Signal and Display Info."); - mPhone.registerForCallWaiting(this, PHONE_CDMA_CALL_WAITING, null); - mPhone.registerForDisplayInfo(this, PHONE_STATE_DISPLAYINFO, null); - mPhone.registerForSignalInfo(this, PHONE_STATE_SIGNALINFO, null); - mPhone.registerForCdmaOtaStatusChange(this, EVENT_OTA_PROVISION_CHANGE, null); - - // Instantiate the ToneGenerator for SignalInfo - try { - mSignalInfoToneGenerator = new ToneGenerator(AudioManager.STREAM_VOICE_CALL, - TONE_RELATIVE_VOLUME_SIGNALINFO); - } catch (RuntimeException e) { - Log.w(LOG_TAG, "CallNotifier: Exception caught while creating " + - "mSignalInfoToneGenerator: " + e); - mSignalInfoToneGenerator = null; - } - - mPhone.registerForInCallVoicePrivacyOn(this, PHONE_ENHANCED_VP_ON, null); - mPhone.registerForInCallVoicePrivacyOff(this, PHONE_ENHANCED_VP_OFF, null); - } - if (mPhone.getPhoneType() == Phone.PHONE_TYPE_GSM) { - mPhone.registerForRingbackTone(this, PHONE_RINGBACK_TONE, null); - mPhone.registerForResendIncallMute(this, PHONE_RESEND_MUTE, null); + if (TelephonyCapabilities.supportsOtasp(mPhone)) { + mPhone.registerForCdmaOtaStatusChange(this, EVENT_OTA_PROVISION_CHANGE, null); } + mPhone.registerForCallWaiting(this, PHONE_CDMA_CALL_WAITING, null); + mPhone.registerForDisplayInfo(this, PHONE_STATE_DISPLAYINFO, null); + mPhone.registerForSignalInfo(this, PHONE_STATE_SIGNALINFO, null); + mPhone.registerForInCallVoicePrivacyOn(this, PHONE_ENHANCED_VP_ON, null); + mPhone.registerForInCallVoicePrivacyOff(this, PHONE_ENHANCED_VP_OFF, null); + mPhone.registerForRingbackTone(this, PHONE_RINGBACK_TONE, null); + mPhone.registerForResendIncallMute(this, PHONE_RESEND_MUTE, null); } /** @@ -823,7 +791,7 @@ public class CallNotifier extends Handler private void onDisconnect(AsyncResult r) { if (VDBG) log("onDisconnect()... phone state: " + mPhone.getState()); - mCdmaVoicePrivacyState = false; + mVoicePrivacyState = false; int autoretrySetting = 0; if (mPhone.getPhoneType() == Phone.PHONE_TYPE_CDMA) { autoretrySetting = android.provider.Settings.System.getInt(mPhone.getContext(). @@ -834,10 +802,10 @@ public class CallNotifier extends Handler PhoneUtils.setAudioControlState(PhoneUtils.AUDIO_IDLE); } - if (mPhone.getPhoneType() == Phone.PHONE_TYPE_CDMA) { - // Stop any signalInfo tone being played when a call gets ended - stopSignalInfoTone(); + // Stop any signalInfo tone being played when a call gets ended + stopSignalInfoTone(); + if (mPhone.getPhoneType() == Phone.PHONE_TYPE_CDMA) { // Resetting the CdmaPhoneCallState members mApplication.cdmaPhoneCallState.resetCdmaPhoneCallState(); @@ -917,6 +885,9 @@ public class CallNotifier extends Handler } else if (cause == Connection.DisconnectCause.OUT_OF_SERVICE) { if (DBG) log("- need to play OUT OF SERVICE tone!"); toneToPlay = InCallTonePlayer.TONE_OUT_OF_SERVICE; + } else if (cause == Connection.DisconnectCause.UNOBTAINABLE_NUMBER) { + if (DBG) log("- need to play TONE_UNOBTAINABLE_NUMBER tone!"); + toneToPlay = InCallTonePlayer.TONE_UNOBTAINABLE_NUMBER; } else if (cause == Connection.DisconnectCause.ERROR_UNSPECIFIED) { if (DBG) log("- DisconnectCause is ERROR_UNSPECIFIED: play TONE_CALL_ENDED!"); toneToPlay = InCallTonePlayer.TONE_CALL_ENDED; @@ -1001,26 +972,30 @@ public class CallNotifier extends Handler } } - // To prevent accidental redial of emergency numbers - // (carrier requirement) the quickest solution is to - // not log the emergency number. We gate on CDMA - // (ugly) when we actually mean carrier X. - // TODO: Clean this up and come up with a unified strategy. - final boolean shouldNotlogEmergencyNumber = - (mPhone.getPhoneType() == Phone.PHONE_TYPE_CDMA); + // On some devices, to avoid accidental redialing of + // emergency numbers, we *never* log emergency calls to + // the Call Log. (This behavior is set on a per-product + // basis, based on carrier requirements.) + final boolean okToLogEmergencyNumber = + mApplication.getResources().getBoolean( + R.bool.allow_emergency_numbers_in_call_log); - // Don't call isOtaSpNumber on GSM phones. - final boolean isOtaNumber = (mPhone.getPhoneType() == Phone.PHONE_TYPE_CDMA) + // Don't call isOtaSpNumber() on phones that don't support OTASP. + final boolean isOtaspNumber = TelephonyCapabilities.supportsOtasp(mPhone) && mPhone.isOtaSpNumber(number); final boolean isEmergencyNumber = PhoneNumberUtils.isEmergencyNumber(number); - // Don't put OTA or CDMA Emergency calls into call log - if (!(isOtaNumber || isEmergencyNumber && shouldNotlogEmergencyNumber)) { + // Don't log emergency numbers if the device doesn't allow it, + // and never log OTASP calls. + final boolean okToLogThisCall = + (!isEmergencyNumber || okToLogEmergencyNumber) + && !isOtaspNumber; + + if (okToLogThisCall) { CallLogAsync.AddCallArgs args = new CallLogAsync.AddCallArgs( mPhone.getContext(), ci, logNumber, presentation, callLogType, date, duration); - mCallLog.addCall(args); } } @@ -1077,7 +1052,7 @@ public class CallNotifier extends Handler if (autoretrySetting == InCallScreen.AUTO_RETRY_ON) { // TODO: (Moto): The contact reference data may need to be stored and use // here when redialing a call. For now, pass in NULL as the URI parameter. - PhoneUtils.placeCall(mPhone, number, null); + PhoneUtils.placeCall(mPhone.getContext(), mPhone, number, null, false, null); mIsCdmaRedialCall = true; } else { mIsCdmaRedialCall = false; @@ -1194,6 +1169,7 @@ public class CallNotifier extends Handler public static final int TONE_REDIAL = 11; public static final int TONE_OTA_CALL_END = 12; public static final int TONE_RING_BACK = 13; + public static final int TONE_UNOBTAINABLE_NUMBER = 14; // The tone volume relative to other sounds in the stream private static final int TONE_RELATIVE_VOLUME_HIPRI = 80; @@ -1307,6 +1283,11 @@ public class CallNotifier extends Handler // Call ring back tone is stopped by stopTone() method toneLengthMillis = Integer.MAX_VALUE - TONE_TIMEOUT_BUFFER; break; + case TONE_UNOBTAINABLE_NUMBER: + toneType = ToneGenerator.TONE_SUP_ERROR; + toneVolume = TONE_RELATIVE_VOLUME_HIPRI; + toneLengthMillis = 4000; + break; default: throw new IllegalArgumentException("Bad toneId: " + mToneId); } @@ -1653,10 +1634,10 @@ public class CallNotifier extends Handler } /** - * Return the private variable mCdmaVoicePrivacyState. + * Return the private variable mVoicePrivacyState. */ - /* package */ boolean getCdmaVoicePrivacyState() { - return mCdmaVoicePrivacyState; + /* package */ boolean getVoicePrivacyState() { + return mVoicePrivacyState; } /** diff --git a/phone/src/com/android/phone2/CallTime.java b/phone/src/com/android/phone2/CallTime.java index a4c56eb..7798332 100644 --- a/phone/src/com/android/phone2/CallTime.java +++ b/phone/src/com/android/phone2/CallTime.java @@ -194,7 +194,7 @@ public class CallTime extends Handler { if (PROFILE & sProfileState == PROFILE_STATE_READY) { // For now, we move away from temp directory in favor of // the application's data directory to store the trace - // information (/data/data/com.android.phone). + // information (/data/data/com.android.phone2). File file = PhoneApp.getInstance().getDir ("phoneTrace", Context.MODE_PRIVATE); if (file.exists() == false) { file.mkdirs(); diff --git a/phone/src/com/android/phone2/CallWaitingCheckBoxPreference.java b/phone/src/com/android/phone2/CallWaitingCheckBoxPreference.java index 1d59e8c..f03d01e 100644 --- a/phone/src/com/android/phone2/CallWaitingCheckBoxPreference.java +++ b/phone/src/com/android/phone2/CallWaitingCheckBoxPreference.java @@ -1,7 +1,10 @@ package com.android.phone2; -import static com.android.phone2.TimeConsumingPreferenceActivity.EXCEPTION_ERROR; +import com.android.internal.telephony.CommandException; +import com.android.internal.telephony.Phone; + import static com.android.phone2.TimeConsumingPreferenceActivity.RESPONSE_ERROR; + import android.content.Context; import android.os.AsyncResult; import android.os.Handler; @@ -11,7 +14,6 @@ import android.util.AttributeSet; import android.util.Log; import com.android.internal.telephony.Phone; -import com.android.internal.telephony.PhoneFactory; public class CallWaitingCheckBoxPreference extends CheckBoxPreference { private static final String LOG_TAG = "CallWaitingCheckBoxPreference"; @@ -24,7 +26,7 @@ public class CallWaitingCheckBoxPreference extends CheckBoxPreference { public CallWaitingCheckBoxPreference(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); - phone = PhoneFactory.getDefaultPhone(); + phone = PhoneApp.getPhone(); } public CallWaitingCheckBoxPreference(Context context, AttributeSet attrs) { @@ -86,9 +88,13 @@ public class CallWaitingCheckBoxPreference extends CheckBoxPreference { } if (ar.exception != null) { - if (DBG) Log.d(LOG_TAG, "handleGetCallWaitingResponse: ar.exception=" + ar.exception); - setEnabled(false); - if (tcpListener != null) tcpListener.onError(CallWaitingCheckBoxPreference.this, EXCEPTION_ERROR); + if (DBG) { + Log.d(LOG_TAG, "handleGetCallWaitingResponse: ar.exception=" + ar.exception); + } + if (tcpListener != null) { + tcpListener.onException(CallWaitingCheckBoxPreference.this, + (CommandException)ar.exception); + } } else if (ar.userObj instanceof Throwable) { if (tcpListener != null) tcpListener.onError(CallWaitingCheckBoxPreference.this, RESPONSE_ERROR); } else { diff --git a/phone/src/com/android/phone2/CdmaCallOptions.java b/phone/src/com/android/phone2/CdmaCallOptions.java index 3022962..3cdf86b 100644 --- a/phone/src/com/android/phone2/CdmaCallOptions.java +++ b/phone/src/com/android/phone2/CdmaCallOptions.java @@ -1,7 +1,6 @@ package com.android.phone2; import com.android.internal.telephony.Phone; -import com.android.internal.telephony.PhoneFactory; import android.content.DialogInterface; import android.os.AsyncResult; @@ -28,7 +27,7 @@ public class CdmaCallOptions extends PreferenceActivity { addPreferencesFromResource(R.xml.cdma_call_options); mButtonVoicePrivacy = (CheckBoxPreference) findPreference(BUTTON_VP_KEY); - if (PhoneFactory.getDefaultPhone().getPhoneType() != Phone.PHONE_TYPE_CDMA) { + if (PhoneApp.getPhone().getPhoneType() != Phone.PHONE_TYPE_CDMA) { //disable the entire screen getPreferenceScreen().setEnabled(false); } diff --git a/phone/src/com/android/phone2/CdmaOptions.java b/phone/src/com/android/phone2/CdmaOptions.java index 1081668..ec09133 100644 --- a/phone/src/com/android/phone2/CdmaOptions.java +++ b/phone/src/com/android/phone2/CdmaOptions.java @@ -16,42 +16,100 @@ package com.android.phone2; -import android.os.Bundle; +import android.os.SystemProperties; import android.preference.Preference; import android.preference.PreferenceActivity; import android.preference.PreferenceScreen; - -import com.android.internal.telephony.Phone; -import com.android.internal.telephony.PhoneFactory; +import android.text.TextUtils; /** * List of Phone-specific settings screens. */ -public class CdmaOptions extends PreferenceActivity { +public class CdmaOptions { + private static final String LOG_TAG = "CdmaOptions"; + + private CdmaSystemSelectListPreference mButtonCdmaSystemSelect; + private CdmaSubscriptionListPreference mButtonCdmaSubscription; + + private static final String BUTTON_CDMA_SYSTEM_SELECT_KEY = "cdma_system_select_key"; + private static final String BUTTON_CDMA_SUBSCRIPTION_KEY = "cdma_subscription_key"; - private CdmaRoamingListPreference mButtonCdmaRoam; + private PreferenceActivity mPrefActivity; + private PreferenceScreen mPrefScreen; + + public CdmaOptions(PreferenceActivity prefActivity, PreferenceScreen prefScreen) { + mPrefActivity = prefActivity; + mPrefScreen = prefScreen; + create(); + } - private static final String BUTTON_CDMA_ROAMING_KEY = "cdma_roaming_mode_key"; + protected void create() { + mPrefActivity.addPreferencesFromResource(R.xml.cdma_options); - @Override - protected void onCreate(Bundle icicle) { - super.onCreate(icicle); + mButtonCdmaSystemSelect = (CdmaSystemSelectListPreference)mPrefScreen + .findPreference(BUTTON_CDMA_SYSTEM_SELECT_KEY); - addPreferencesFromResource(R.xml.cdma_options); + mButtonCdmaSubscription = (CdmaSubscriptionListPreference)mPrefScreen + .findPreference(BUTTON_CDMA_SUBSCRIPTION_KEY); - PreferenceScreen prefSet = getPreferenceScreen(); - mButtonCdmaRoam = - (CdmaRoamingListPreference) prefSet.findPreference(BUTTON_CDMA_ROAMING_KEY); - if (PhoneFactory.getDefaultPhone().getPhoneType() != Phone.PHONE_TYPE_CDMA) { - mButtonCdmaRoam.setEnabled(false); + mButtonCdmaSystemSelect.setEnabled(true); + if(deviceSupportsNvAndRuim()) { + log("Both NV and Ruim supported, ENABLE subscription type selection"); + mButtonCdmaSubscription.setEnabled(true); + } else { + log("Both NV and Ruim NOT supported, REMOVE subscription type selection"); + mPrefScreen.removePreference(mPrefScreen + .findPreference(BUTTON_CDMA_SUBSCRIPTION_KEY)); } } - @Override - public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) { - if (preference.getKey().equals(BUTTON_CDMA_ROAMING_KEY)) { + private boolean deviceSupportsNvAndRuim() { + // retrieve the list of subscription types supported by device. + String subscriptionsSupported = SystemProperties.get("ril.subscription.types"); + boolean nvSupported = false; + boolean ruimSupported = false; + + log("deviceSupportsnvAnRum: prop=" + subscriptionsSupported); + if (!TextUtils.isEmpty(subscriptionsSupported)) { + // Searches through the comma-separated list for a match for "NV" + // and "RUIM" to update nvSupported and ruimSupported. + for (String subscriptionType : subscriptionsSupported.split(",")) { + subscriptionType = subscriptionType.trim(); + if (subscriptionType.equalsIgnoreCase("NV")) { + nvSupported = true; + } + if (subscriptionType.equalsIgnoreCase("RUIM")) { + ruimSupported = true; + } + } + } + + log("deviceSupportsnvAnRum: nvSupported=" + nvSupported + + " ruimSupported=" + ruimSupported); + return (nvSupported && ruimSupported); + } + + public boolean preferenceTreeClick(Preference preference) { + if (preference.getKey().equals(BUTTON_CDMA_SYSTEM_SELECT_KEY)) { + log("preferenceTreeClick: return BUTTON_CDMA_ROAMING_KEY true"); + return true; + } + if (preference.getKey().equals(BUTTON_CDMA_SUBSCRIPTION_KEY)) { + log("preferenceTreeClick: return CDMA_SUBSCRIPTION_KEY true"); return true; } return false; } + + public void showDialog(Preference preference) { + if (preference.getKey().equals(BUTTON_CDMA_SYSTEM_SELECT_KEY)) { + mButtonCdmaSystemSelect.showDialog(null); + } else if (preference.getKey().equals(BUTTON_CDMA_SUBSCRIPTION_KEY)) { + mButtonCdmaSubscription.showDialog(null); + } + } + + protected void log(String s) { + android.util.Log.d(LOG_TAG, s); + } } diff --git a/phone/src/com/android/phone2/CdmaSubscriptionListPreference.java b/phone/src/com/android/phone2/CdmaSubscriptionListPreference.java new file mode 100644 index 0000000..c2ba664 --- /dev/null +++ b/phone/src/com/android/phone2/CdmaSubscriptionListPreference.java @@ -0,0 +1,131 @@ +/* + * 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. + */ + +package com.android.phone2; + +import android.content.Context; +import android.os.AsyncResult; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.preference.ListPreference; +import android.provider.Settings.Secure; +import android.util.AttributeSet; +import android.util.Log; + +import com.android.internal.telephony.Phone; +import com.android.internal.telephony.PhoneFactory; + +public class CdmaSubscriptionListPreference extends ListPreference { + + private static final String LOG_TAG = "CdmaSubscriptionListPreference"; + + // Used for CDMA subscription mode + private static final int CDMA_SUBSCRIPTION_RUIM_SIM = 0; + private static final int CDMA_SUBSCRIPTION_NV = 1; + + //preferredSubscriptionMode 0 - RUIM/SIM, preferred + // 1 - NV + static final int preferredSubscriptionMode = CDMA_SUBSCRIPTION_NV; + + private Phone mPhone; + private CdmaSubscriptionButtonHandler mHandler; + + public CdmaSubscriptionListPreference(Context context, AttributeSet attrs) { + super(context, attrs); + + mPhone = PhoneFactory.getDefaultPhone(); + mHandler = new CdmaSubscriptionButtonHandler(); + setCurrentCdmaSubscriptionModeValue(); + } + + private void setCurrentCdmaSubscriptionModeValue() { + int cdmaSubscriptionMode = Secure.getInt(mPhone.getContext().getContentResolver(), + android.provider.Settings.Secure.CDMA_SUBSCRIPTION_MODE, preferredSubscriptionMode); + setValue(Integer.toString(cdmaSubscriptionMode)); + } + + public CdmaSubscriptionListPreference(Context context) { + this(context, null); + } + + @Override + protected void showDialog(Bundle state) { + setCurrentCdmaSubscriptionModeValue(); + + super.showDialog(state); + } + + @Override + protected void onDialogClosed(boolean positiveResult) { + super.onDialogClosed(positiveResult); + + if (!positiveResult) { + //The button was dismissed - no need to set new value + return; + } + + int buttonCdmaSubscriptionMode = Integer.valueOf(getValue()).intValue(); + Log.d(LOG_TAG, "Setting new value " + buttonCdmaSubscriptionMode); + int statusCdmaSubscriptionMode; + switch(buttonCdmaSubscriptionMode) { + case CDMA_SUBSCRIPTION_NV: + statusCdmaSubscriptionMode = Phone.CDMA_SUBSCRIPTION_NV; + break; + case CDMA_SUBSCRIPTION_RUIM_SIM: + statusCdmaSubscriptionMode = Phone.CDMA_SUBSCRIPTION_RUIM_SIM; + break; + default: + statusCdmaSubscriptionMode = Phone.PREFERRED_CDMA_SUBSCRIPTION; + } + + // Set the CDMA subscription mode, when mode has been successfully changed + // handleSetCdmaSubscriptionMode will be invoked and the value saved. + mPhone.setCdmaSubscription(statusCdmaSubscriptionMode, mHandler + .obtainMessage(CdmaSubscriptionButtonHandler.MESSAGE_SET_CDMA_SUBSCRIPTION, + getValue())); + + } + + private class CdmaSubscriptionButtonHandler extends Handler { + + private static final int MESSAGE_SET_CDMA_SUBSCRIPTION = 0; + + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case MESSAGE_SET_CDMA_SUBSCRIPTION: + handleSetCdmaSubscriptionMode(msg); + break; + } + } + + private void handleSetCdmaSubscriptionMode(Message msg) { + mPhone = PhoneFactory.getDefaultPhone(); + AsyncResult ar = (AsyncResult) msg.obj; + + if (ar.exception == null) { + // Get the original string entered by the user + int cdmaSubscriptionMode = Integer.valueOf((String) ar.userObj).intValue(); + Secure.putInt(mPhone.getContext().getContentResolver(), + Secure.CDMA_SUBSCRIPTION_MODE, + cdmaSubscriptionMode ); + } else { + Log.e(LOG_TAG, "Setting Cdma subscription source failed"); + } + } + } +} diff --git a/phone/src/com/android/phone2/CdmaRoamingListPreference.java b/phone/src/com/android/phone2/CdmaSystemSelectListPreference.java index ac247cd..055981c 100644 --- a/phone/src/com/android/phone2/CdmaRoamingListPreference.java +++ b/phone/src/com/android/phone2/CdmaSystemSelectListPreference.java @@ -28,10 +28,9 @@ import android.util.AttributeSet; import android.util.Log; import com.android.internal.telephony.Phone; -import com.android.internal.telephony.PhoneFactory; import com.android.internal.telephony.TelephonyProperties; -public class CdmaRoamingListPreference extends ListPreference { +public class CdmaSystemSelectListPreference extends ListPreference { private static final String LOG_TAG = "CdmaRoamingListPreference"; private static final boolean DBG = true; @@ -39,16 +38,16 @@ public class CdmaRoamingListPreference extends ListPreference { private Phone mPhone; private MyHandler mHandler = new MyHandler();; - public CdmaRoamingListPreference(Context context, AttributeSet attrs) { + public CdmaSystemSelectListPreference(Context context, AttributeSet attrs) { super(context, attrs); - mPhone = PhoneFactory.getDefaultPhone(); + mPhone = PhoneApp.getPhone(); mHandler = new MyHandler(); mPhone.queryCdmaRoamingPreference( mHandler.obtainMessage(MyHandler.MESSAGE_GET_ROAMING_PREFERENCE)); } - public CdmaRoamingListPreference(Context context) { + public CdmaSystemSelectListPreference(Context context) { this(context, null); } diff --git a/phone/src/com/android/phone2/CdmaVoicePrivacyCheckBoxPreference.java b/phone/src/com/android/phone2/CdmaVoicePrivacyCheckBoxPreference.java index 6408365..9714970 100644 --- a/phone/src/com/android/phone2/CdmaVoicePrivacyCheckBoxPreference.java +++ b/phone/src/com/android/phone2/CdmaVoicePrivacyCheckBoxPreference.java @@ -1,7 +1,7 @@ package com.android.phone2; import com.android.internal.telephony.Phone; -import com.android.internal.telephony.PhoneFactory; + import android.content.Context; import android.os.AsyncResult; import android.os.Handler; @@ -20,7 +20,7 @@ public class CdmaVoicePrivacyCheckBoxPreference extends CheckBoxPreference { public CdmaVoicePrivacyCheckBoxPreference(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); - phone = PhoneFactory.getDefaultPhone(); + phone = PhoneApp.getPhone(); phone.getEnhancedVoicePrivacy(mHandler.obtainMessage(MyHandler.MESSAGE_GET_VP)); } diff --git a/phone/src/com/android/phone2/CellBroadcastSms.java b/phone/src/com/android/phone2/CellBroadcastSms.java index ed34700..7114c78 100644 --- a/phone/src/com/android/phone2/CellBroadcastSms.java +++ b/phone/src/com/android/phone2/CellBroadcastSms.java @@ -24,7 +24,6 @@ import android.preference.Preference; import android.preference.PreferenceScreen; import android.preference.PreferenceActivity; import com.android.internal.telephony.Phone; -import com.android.internal.telephony.PhoneFactory; import com.android.internal.telephony.RILConstants; import android.os.AsyncResult; @@ -338,7 +337,7 @@ public class CellBroadcastSms extends PreferenceActivity addPreferencesFromResource(R.xml.cell_broadcast_sms); - mPhone = PhoneFactory.getDefaultPhone(); + mPhone = PhoneApp.getPhone(); mHandler = new MyHandler(); PreferenceScreen prefSet = getPreferenceScreen(); diff --git a/phone/src/com/android/phone2/ChangeIccPinScreen.java b/phone/src/com/android/phone2/ChangeIccPinScreen.java index 34078e0..e890321 100644 --- a/phone/src/com/android/phone2/ChangeIccPinScreen.java +++ b/phone/src/com/android/phone2/ChangeIccPinScreen.java @@ -37,7 +37,6 @@ import android.widget.Toast; import com.android.internal.telephony.CommandException; import com.android.internal.telephony.IccCard; import com.android.internal.telephony.Phone; -import com.android.internal.telephony.PhoneFactory; /** * "Change ICC PIN" UI for the Phone app. @@ -92,7 +91,7 @@ public class ChangeIccPinScreen extends Activity { public void onCreate(Bundle icicle) { super.onCreate(icicle); - mPhone = PhoneFactory.getDefaultPhone(); + mPhone = PhoneApp.getPhone(); resolveIntent(); diff --git a/phone/src/com/android/phone2/DTMFTwelveKeyDialer.java b/phone/src/com/android/phone2/DTMFTwelveKeyDialer.java index da2313b..0947316 100755 --- a/phone/src/com/android/phone2/DTMFTwelveKeyDialer.java +++ b/phone/src/com/android/phone2/DTMFTwelveKeyDialer.java @@ -20,7 +20,6 @@ import android.media.AudioManager; import android.media.ToneGenerator; import android.os.Handler; import android.os.Message; -import android.os.SystemProperties; import android.provider.Settings; import android.telephony.PhoneNumberUtils; import android.text.Editable; @@ -62,11 +61,11 @@ public class DTMFTwelveKeyDialer implements private ToneGenerator mToneGenerator; private Object mToneGeneratorLock = new Object(); - // indicate if we want to enable the DTMF tone playback. - private boolean mDTMFToneEnabled; + // indicate if we want to enable the local tone playback. + private boolean mLocalToneEnabled; - // DTMF tone type - private int mDTMFToneType; + // indicates that we are using automatically shortened DTMF tones + boolean mShortTone; // indicate if the confirmation from TelephonyFW is pending. private boolean mDTMFBurstCnfPending = false; @@ -405,7 +404,7 @@ public class DTMFTwelveKeyDialer implements if (DBG) log("DTMFTwelveKeyDialer constructor... this = " + this); mInCallScreen = parent; - mPhone = PhoneApp.getInstance().phone; + mPhone = PhoneApp.getPhone(); // The passed-in DTMFTwelveKeyDialerView *should* always be // non-null, now that the in-call UI uses only portrait mode. @@ -450,7 +449,6 @@ public class DTMFTwelveKeyDialer implements mDialerDrawer.setOnDrawerOpenListener(this); mDialerDrawer.setOnDrawerCloseListener(this); } - } /** @@ -467,12 +465,10 @@ public class DTMFTwelveKeyDialer implements mDialerDrawer.setOnDrawerOpenListener(null); mDialerDrawer.setOnDrawerCloseListener(null); } - if (mPhone.getPhoneType() == Phone.PHONE_TYPE_CDMA) { - mHandler.removeMessages(DTMF_SEND_CNF); - synchronized (mDTMFQueue) { - mDTMFBurstCnfPending = false; - mDTMFQueue.clear(); - } + mHandler.removeMessages(DTMF_SEND_CNF); + synchronized (mDTMFQueue) { + mDTMFBurstCnfPending = false; + mDTMFQueue.clear(); } closeDialer(false); } @@ -513,17 +509,17 @@ public class DTMFTwelveKeyDialer implements // see if we need to play local tones. if (mPhone.getContext().getResources().getBoolean(R.bool.allow_local_dtmf_tones)) { - mDTMFToneEnabled = Settings.System.getInt(mInCallScreen.getContentResolver(), + mLocalToneEnabled = Settings.System.getInt(mInCallScreen.getContentResolver(), Settings.System.DTMF_TONE_WHEN_DIALING, 1) == 1; } else { - mDTMFToneEnabled = false; + mLocalToneEnabled = false; } - if (DBG) log("- startDialerSession: mDTMFToneEnabled = " + mDTMFToneEnabled); + if (DBG) log("- startDialerSession: mLocalToneEnabled = " + mLocalToneEnabled); // create the tone generator // if the mToneGenerator creation fails, just continue without it. It is // a local audio signal, and is not as important as the dtmf tone itself. - if (mDTMFToneEnabled) { + if (mLocalToneEnabled) { synchronized (mToneGeneratorLock) { if (mToneGenerator == null) { try { @@ -863,55 +859,49 @@ public class DTMFTwelveKeyDialer implements } /** - * Starts playing a DTMF tone. Also begins the local tone playback, - * if enabled. - * The access of this function is package rather than private - * since this is being referred from InCallScreen. - * InCallScreen calls this function to utilize the DTMF ToneGenerator properties - * defined here. - * @param tone a tone code from {@link ToneGenerator} + * Plays the local tone based the phone type. */ - /* package */ void startDtmfTone(char tone) { + public void startTone(char c) { + // Only play the tone if it exists. + if (!mToneMap.containsKey(c)) { + return; + } + // Read the settings as it may be changed by the user during the call + mShortTone = TelephonyCapabilities.useShortDtmfTones(mPhone, mPhone.getContext()); + if (DBG) log("startDtmfTone()..."); - mPhone.startDtmf(tone); - // if local tone playback is enabled, start it. - if (mDTMFToneEnabled) { - synchronized (mToneGeneratorLock) { - if (mToneGenerator == null) { - if (DBG) log("startDtmfTone: mToneGenerator == null, tone: " + tone); - } else { - if (DBG) log("starting local tone " + tone); - mToneGenerator.startTone(mToneMap.get(tone)); - } - } + // For Short DTMF we need to play the local tone for fixed duration + if (mShortTone) { + sendShortDtmfToNetwork(c); + } else { + // Pass as a char to be sent to network + Log.i(LOG_TAG, "send long dtmf for " + c); + mPhone.startDtmf(c); } + startLocalToneIfNeeded(c); } /** - * Stops playing the current DTMF tone. - * - * The ToneStopper class (similar to that in {@link TwelveKeyDialer#mToneStopper}) - * has been removed in favor of synchronous start / stop calls since tone duration - * is now a function of the input. - * The acess of this function is package rather than private - * since this is being referred from InCallScreen. - * InCallScreen calls this function to utilize the DTMF ToneGenerator properties - * defined here. + * Plays the local tone based the phone type. */ - /* package */ void stopDtmfTone() { - if (DBG) log("stopDtmfTone()..."); - mPhone.stopDtmf(); - - // if local tone playback is enabled, stop it. - if (DBG) log("trying to stop local tone..."); - if (mDTMFToneEnabled) { + public void startLocalToneIfNeeded(char c) { + // if local tone playback is enabled, start it. + // Only play the tone if it exists. + if (!mToneMap.containsKey(c)) { + return; + } + if (mLocalToneEnabled) { synchronized (mToneGeneratorLock) { if (mToneGenerator == null) { - if (DBG) log("stopDtmfTone: mToneGenerator == null"); + if (DBG) log("startDtmfTone: mToneGenerator == null, tone: " + c); } else { - if (DBG) log("stopping local tone."); - mToneGenerator.stopTone(); + if (DBG) log("starting local tone " + c); + int toneDuration = -1; + if (mShortTone) { + toneDuration = DTMF_DURATION_MS; + } + mToneGenerator.startTone(mToneMap.get(c), toneDuration); } } } @@ -932,79 +922,32 @@ public class DTMFTwelveKeyDialer implements } /** - * Plays the local tone based the phone type. - */ - private void startTone(char c) { - int phoneType = mPhone.getPhoneType(); - if (phoneType == Phone.PHONE_TYPE_GSM) { - startDtmfTone(c); - } else if (phoneType == Phone.PHONE_TYPE_CDMA) { - startToneCdma(c); - } else { - throw new IllegalStateException("Unexpected phone type: " + phoneType); - } - } - - /** * Stops the local tone based on the phone type. */ - private void stopTone() { - int phoneType = mPhone.getPhoneType(); - if (phoneType == Phone.PHONE_TYPE_GSM) { - stopDtmfTone(); - } else if (phoneType == Phone.PHONE_TYPE_CDMA) { - // Cdma case we do stopTone only for Long DTMF Setting - if (mDTMFToneType == CallFeaturesSetting.DTMF_TONE_TYPE_LONG) { - stopToneCdma(); - } - } else { - throw new IllegalStateException("Unexpected phone type: " + phoneType); + public void stopTone() { + if (!mShortTone) { + if (DBG) log("stopping remote tone."); + mPhone.stopDtmf(); + stopLocalToneIfNeeded(); } } /** - * Plays tone when the DTMF setting is normal(Short). - */ - void startToneCdma(char tone) { - if (DBG) log("startToneCdma('" + tone + "')..."); - - // Read the settings as it may be changed by the user during the call - mDTMFToneType = Settings.System.getInt(mInCallScreen.getContentResolver(), - Settings.System.DTMF_TONE_TYPE_WHEN_DIALING, - CallFeaturesSetting.DTMF_TONE_TYPE_NORMAL); - // For Short DTMF we need to play the local tone for fixed duration - if (mDTMFToneType == CallFeaturesSetting.DTMF_TONE_TYPE_NORMAL) { - sendShortDtmfToNetwork (tone); - } else { - // Pass as a char to be sent to network - Log.i(LOG_TAG, "send long dtmf for " + tone); - mPhone.startDtmf(tone); - } - - startLocalToneCdma(tone); - } - - /** - * Plays local tone for CDMA. + * Stops the local tone based on the phone type. */ - void startLocalToneCdma(char tone) { - if (DBG) log("startLocalToneCdma('" + tone + "')..." - + " mDTMFToneEnabled = " + mDTMFToneEnabled + " this = " + this); - - // if local tone playback is enabled, start it. - if (mDTMFToneEnabled) { - synchronized (mToneGeneratorLock) { - if (mToneGenerator == null) { - if (DBG) log("startToneCdma: mToneGenerator == null, tone: " + tone); - } else { - if (DBG) log("starting local tone " + tone); - - // Start the new tone. - int toneDuration = -1; - if (mDTMFToneType == CallFeaturesSetting.DTMF_TONE_TYPE_NORMAL) { - toneDuration = DTMF_DURATION_MS; + public void stopLocalToneIfNeeded() { + if (!mShortTone) { + if (DBG) log("stopping remote tone."); + // if local tone playback is enabled, stop it. + if (DBG) log("trying to stop local tone..."); + if (mLocalToneEnabled) { + synchronized (mToneGeneratorLock) { + if (mToneGenerator == null) { + if (DBG) log("stopLocalTone: mToneGenerator == null"); + } else { + if (DBG) log("stopping local tone."); + mToneGenerator.stopTone(); } - mToneGenerator.startTone(mToneMap.get(tone), toneDuration); } } } @@ -1031,35 +974,6 @@ public class DTMFTwelveKeyDialer implements } /** - * Stops the dtmf from being sent over the network for Long DTMF case - * and stops local DTMF key feedback tone. - */ - private void stopToneCdma() { - if (DBG) log("stopping remote tone."); - - mPhone.stopDtmf(); - stopLocalToneCdma(); - } - - /** - * Stops the local dtmf tone. - */ - void stopLocalToneCdma() { - // if local tone playback is enabled, stop it. - if (DBG) log("trying to stop local tone..."); - if (mDTMFToneEnabled) { - synchronized (mToneGeneratorLock) { - if (mToneGenerator == null) { - if (DBG) log("stopLocalToneCdma: mToneGenerator == null"); - } else { - if (DBG) log("stopping local tone."); - mToneGenerator.stopTone(); - } - } - } - } - - /** * Handles Burst Dtmf Confirmation from the Framework. */ void handleBurstDtmfConfirmation() { diff --git a/phone/src/com/android/phone2/DeleteFdnContactScreen.java b/phone/src/com/android/phone2/DeleteFdnContactScreen.java index b8eb8dc..74e0624 100644 --- a/phone/src/com/android/phone2/DeleteFdnContactScreen.java +++ b/phone/src/com/android/phone2/DeleteFdnContactScreen.java @@ -93,16 +93,20 @@ public class DeleteFdnContactScreen extends Activity { mName = intent.getStringExtra(INTENT_EXTRA_NAME); mNumber = intent.getStringExtra(INTENT_EXTRA_NUMBER); - if (TextUtils.isEmpty(mName)) { + if (TextUtils.isEmpty(mNumber)) { finish(); } } private void deleteContact() { StringBuilder buf = new StringBuilder(); - buf.append("tag='"); - buf.append(mName); - buf.append("' AND number='"); + if (TextUtils.isEmpty(mName)) { + buf.append("number='"); + } else { + buf.append("tag='"); + buf.append(mName); + buf.append("' AND number='"); + } buf.append(mNumber); buf.append("' AND pin2='"); buf.append(mPin2); diff --git a/phone/src/com/android/phone2/EditFdnContactScreen.java b/phone/src/com/android/phone2/EditFdnContactScreen.java index 6dcf596..c17cc9a 100644 --- a/phone/src/com/android/phone2/EditFdnContactScreen.java +++ b/phone/src/com/android/phone2/EditFdnContactScreen.java @@ -205,9 +205,7 @@ public class EditFdnContactScreen extends Activity { mName = intent.getStringExtra(INTENT_EXTRA_NAME); mNumber = intent.getStringExtra(INTENT_EXTRA_NUMBER); - if (TextUtils.isEmpty(mName) && TextUtils.isEmpty(mNumber)) { - mAddContact = true; - } + mAddContact = TextUtils.isEmpty(mNumber); } /** diff --git a/phone/src/com/android/phone2/EditPhoneNumberPreference.java b/phone/src/com/android/phone2/EditPhoneNumberPreference.java index 56d32a2..92af9da 100644 --- a/phone/src/com/android/phone2/EditPhoneNumberPreference.java +++ b/phone/src/com/android/phone2/EditPhoneNumberPreference.java @@ -187,7 +187,7 @@ public class EditPhoneNumberPreference extends EditTextPreference { @Override protected void onBindDialogView(View view) { // default the button clicked to be the cancel button. - mButtonClicked = DialogInterface.BUTTON2; + mButtonClicked = DialogInterface.BUTTON_NEGATIVE; super.onBindDialogView(view); @@ -307,7 +307,7 @@ public class EditPhoneNumberPreference extends EditTextPreference { @Override public void onClick(DialogInterface dialog, int which) { // The neutral button (button3) is always the toggle. - if ((mConfirmationMode == CM_ACTIVATION) && (which == DialogInterface.BUTTON3)) { + if ((mConfirmationMode == CM_ACTIVATION) && (which == DialogInterface.BUTTON_NEUTRAL)) { //flip the toggle if we are in the correct mode. setToggled(!isToggled()); } @@ -321,8 +321,8 @@ public class EditPhoneNumberPreference extends EditTextPreference { // phone numbers and calling the close action listener. protected void onDialogClosed(boolean positiveResult) { // A positive result is technically either button1 or button3. - if ((mButtonClicked == DialogInterface.BUTTON1) || - (mButtonClicked == DialogInterface.BUTTON3)){ + if ((mButtonClicked == DialogInterface.BUTTON_POSITIVE) || + (mButtonClicked == DialogInterface.BUTTON_NEUTRAL)){ setPhoneNumber(getEditText().getText().toString()); super.onDialogClosed(positiveResult); setText(getStringValue()); diff --git a/phone/src/com/android/phone2/EmergencyCallHandler.java b/phone/src/com/android/phone2/EmergencyCallHandler.java index 2181ae4..de2129a 100644 --- a/phone/src/com/android/phone2/EmergencyCallHandler.java +++ b/phone/src/com/android/phone2/EmergencyCallHandler.java @@ -26,7 +26,6 @@ import android.os.Handler; import android.os.Message; import android.provider.Settings; import com.android.internal.telephony.Phone; -import com.android.internal.telephony.PhoneFactory; import android.telephony.ServiceState; import android.view.WindowManager; @@ -107,7 +106,7 @@ public class EmergencyCallHandler extends Activity { super.onCreate(icicle); // setup the phone and get the retry count embedded in the intent. - Phone phone = PhoneFactory.getDefaultPhone(); + Phone phone = PhoneApp.getPhone(); int retryCount = getIntent().getIntExtra(EMERGENCY_CALL_RETRY_KEY, INITIAL_ATTEMPT); // create a new message object. diff --git a/phone/src/com/android/phone2/EmergencyCallbackModeExitDialog.java b/phone/src/com/android/phone2/EmergencyCallbackModeExitDialog.java index 54bfc5c..d36d5d8 100644 --- a/phone/src/com/android/phone2/EmergencyCallbackModeExitDialog.java +++ b/phone/src/com/android/phone2/EmergencyCallbackModeExitDialog.java @@ -40,7 +40,6 @@ import android.os.SystemProperties; import android.util.Log; import com.android.internal.telephony.Phone; -import com.android.internal.telephony.PhoneFactory; import com.android.internal.telephony.TelephonyIntents; import com.android.internal.telephony.TelephonyProperties; @@ -92,7 +91,7 @@ public class EmergencyCallbackModeExitDialog extends Activity implements OnDismi waitForConnectionCompleteThread.start(); // Register ECM timer reset notfication - mPhone = PhoneFactory.getDefaultPhone(); + mPhone = PhoneApp.getPhone(); mPhone.registerForEcmTimerReset(mTimerResetHandler, ECM_TIMER_RESET, null); // Register receiver for intent closing the dialog diff --git a/phone/src/com/android/phone2/EnableFdnScreen.java b/phone/src/com/android/phone2/EnableFdnScreen.java index 6a68679..bb3d2c7 100644 --- a/phone/src/com/android/phone2/EnableFdnScreen.java +++ b/phone/src/com/android/phone2/EnableFdnScreen.java @@ -31,7 +31,6 @@ import android.widget.TextView; import com.android.internal.telephony.CommandException; import com.android.internal.telephony.Phone; -import com.android.internal.telephony.PhoneFactory; /** * UI to enable/disable FDN. @@ -68,7 +67,7 @@ public class EnableFdnScreen extends Activity { setContentView(R.layout.enable_fdn_screen); setupView(); - mPhone = PhoneFactory.getDefaultPhone(); + mPhone = PhoneApp.getPhone(); mEnable = !mPhone.getIccCard().getIccFdnEnabled(); int id = mEnable ? R.string.enable_fdn : R.string.disable_fdn; @@ -78,7 +77,7 @@ public class EnableFdnScreen extends Activity { @Override protected void onResume() { super.onResume(); - mPhone = PhoneFactory.getDefaultPhone(); + mPhone = PhoneApp.getPhone(); } private void setupView() { diff --git a/phone/src/com/android/phone2/EnableIccPinScreen.java b/phone/src/com/android/phone2/EnableIccPinScreen.java index 3bd4e46..9ad7b03 100644 --- a/phone/src/com/android/phone2/EnableIccPinScreen.java +++ b/phone/src/com/android/phone2/EnableIccPinScreen.java @@ -31,7 +31,6 @@ import android.widget.TextView; import com.android.internal.telephony.CommandException; import com.android.internal.telephony.Phone; -import com.android.internal.telephony.PhoneFactory; /** * UI to enable/disable the ICC PIN. @@ -68,7 +67,7 @@ public class EnableIccPinScreen extends Activity { setContentView(R.layout.enable_sim_pin_screen); setupView(); - mPhone = PhoneFactory.getDefaultPhone(); + mPhone = PhoneApp.getPhone(); mEnable = !mPhone.getIccCard().getIccLockEnabled(); int id = mEnable ? R.string.enable_sim_pin : R.string.disable_sim_pin; diff --git a/phone/src/com/android/phone2/FakePhoneActivity.java b/phone/src/com/android/phone2/FakePhoneActivity.java index 67d9350..141b54e 100644 --- a/phone/src/com/android/phone2/FakePhoneActivity.java +++ b/phone/src/com/android/phone2/FakePhoneActivity.java @@ -54,10 +54,10 @@ public class FakePhoneActivity extends Activity { } }); - mRadioControl = PhoneApp.getInstance().phone.getSimulatedRadioControl(); + mRadioControl = PhoneApp.getPhone().getSimulatedRadioControl(); Log.i(TAG, "- PhoneApp.getInstance(): " + PhoneApp.getInstance()); - Log.i(TAG, "- PhoneApp.getInstance().phone: " + PhoneApp.getInstance().phone); + Log.i(TAG, "- PhoneApp.getPhone(): " + PhoneApp.getPhone()); Log.i(TAG, "- mRadioControl: " + mRadioControl); } diff --git a/phone/src/com/android/phone2/FdnSetting.java b/phone/src/com/android/phone2/FdnSetting.java index 5dbece0..eeedc6f 100644 --- a/phone/src/com/android/phone2/FdnSetting.java +++ b/phone/src/com/android/phone2/FdnSetting.java @@ -29,7 +29,6 @@ import android.widget.Toast; import com.android.internal.telephony.CommandException; import com.android.internal.telephony.Phone; -import com.android.internal.telephony.PhoneFactory; /** * FDN settings UI for the Phone app. @@ -384,7 +383,7 @@ public class FdnSetting extends PreferenceActivity addPreferencesFromResource(R.xml.fdn_setting); - mPhone = PhoneFactory.getDefaultPhone(); + mPhone = PhoneApp.getPhone(); //get UI object references PreferenceScreen prefSet = getPreferenceScreen(); @@ -413,7 +412,7 @@ public class FdnSetting extends PreferenceActivity @Override protected void onResume() { super.onResume(); - mPhone = PhoneFactory.getDefaultPhone(); + mPhone = PhoneApp.getPhone(); updateEnableFDN(); } diff --git a/phone/src/com/android/phone2/GsmUmtsCallOptions.java b/phone/src/com/android/phone2/GsmUmtsCallOptions.java index a87d2b9..ec1b85a 100644 --- a/phone/src/com/android/phone2/GsmUmtsCallOptions.java +++ b/phone/src/com/android/phone2/GsmUmtsCallOptions.java @@ -23,7 +23,6 @@ import android.preference.PreferenceActivity; import android.preference.PreferenceScreen; import com.android.internal.telephony.Phone; -import com.android.internal.telephony.PhoneFactory; public class GsmUmtsCallOptions extends PreferenceActivity { private static final String LOG_TAG = "GsmUmtsCallOptions"; @@ -35,7 +34,7 @@ public class GsmUmtsCallOptions extends PreferenceActivity { addPreferencesFromResource(R.xml.gsm_umts_call_options); - if (PhoneFactory.getDefaultPhone().getPhoneType() != Phone.PHONE_TYPE_GSM) { + if (PhoneApp.getPhone().getPhoneType() != Phone.PHONE_TYPE_GSM) { //disable the entire screen getPreferenceScreen().setEnabled(false); } diff --git a/phone/src/com/android/phone2/GsmUmtsOptions.java b/phone/src/com/android/phone2/GsmUmtsOptions.java index 99f36a4..6593a52 100644 --- a/phone/src/com/android/phone2/GsmUmtsOptions.java +++ b/phone/src/com/android/phone2/GsmUmtsOptions.java @@ -16,7 +16,6 @@ package com.android.phone2; -import android.os.Bundle; import android.preference.CheckBoxPreference; import android.preference.Preference; import android.preference.PreferenceActivity; @@ -28,7 +27,8 @@ import com.android.internal.telephony.PhoneFactory; /** * List of Network-specific settings screens. */ -public class GsmUmtsOptions extends PreferenceActivity { +public class GsmUmtsOptions { + private static final String LOG_TAG = "GsmUmtsOptions"; private PreferenceScreen mButtonAPNExpand; private PreferenceScreen mButtonOperatorSelectionExpand; @@ -37,30 +37,39 @@ public class GsmUmtsOptions extends PreferenceActivity { private static final String BUTTON_APN_EXPAND_KEY = "button_apn_key"; private static final String BUTTON_OPERATOR_SELECTION_EXPAND_KEY = "button_carrier_sel_key"; private static final String BUTTON_PREFER_2G_KEY = "button_prefer_2g_key"; + private PreferenceActivity mPrefActivity; + private PreferenceScreen mPrefScreen; + public GsmUmtsOptions(PreferenceActivity prefActivity, PreferenceScreen prefScreen) { + mPrefActivity = prefActivity; + mPrefScreen = prefScreen; + create(); + } - @Override - protected void onCreate(Bundle icicle) { - super.onCreate(icicle); - - addPreferencesFromResource(R.xml.gsm_umts_options); - PreferenceScreen prefSet = getPreferenceScreen(); - mButtonAPNExpand = (PreferenceScreen) prefSet.findPreference(BUTTON_APN_EXPAND_KEY); + protected void create() { + mPrefActivity.addPreferencesFromResource(R.xml.gsm_umts_options); + mButtonAPNExpand = (PreferenceScreen) mPrefScreen.findPreference(BUTTON_APN_EXPAND_KEY); mButtonOperatorSelectionExpand = - (PreferenceScreen) prefSet.findPreference(BUTTON_OPERATOR_SELECTION_EXPAND_KEY); - mButtonPrefer2g = (CheckBoxPreference) prefSet.findPreference(BUTTON_PREFER_2G_KEY); + (PreferenceScreen) mPrefScreen.findPreference(BUTTON_OPERATOR_SELECTION_EXPAND_KEY); + mButtonPrefer2g = (CheckBoxPreference) mPrefScreen.findPreference(BUTTON_PREFER_2G_KEY); if (PhoneFactory.getDefaultPhone().getPhoneType() != Phone.PHONE_TYPE_GSM) { + log("Not a GSM phone"); mButtonAPNExpand.setEnabled(false); mButtonOperatorSelectionExpand.setEnabled(false); mButtonPrefer2g.setEnabled(false); } } - @Override - public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) { + public boolean preferenceTreeClick(Preference preference) { if (preference.getKey().equals(BUTTON_PREFER_2G_KEY)) { + log("preferenceTreeClick: return true"); return true; } + log("preferenceTreeClick: return false"); return false; } + + protected void log(String s) { + android.util.Log.d(LOG_TAG, s); + } } diff --git a/phone/src/com/android/phone2/IccNetworkDepersonalizationPanel.java b/phone/src/com/android/phone2/IccNetworkDepersonalizationPanel.java index 390d47e..27cfce1 100644 --- a/phone/src/com/android/phone2/IccNetworkDepersonalizationPanel.java +++ b/phone/src/com/android/phone2/IccNetworkDepersonalizationPanel.java @@ -35,7 +35,6 @@ import android.widget.LinearLayout; import android.widget.TextView; import com.android.internal.telephony.Phone; -import com.android.internal.telephony.PhoneFactory; /** * "SIM network unlock" PIN entry screen. @@ -149,7 +148,7 @@ public class IccNetworkDepersonalizationPanel extends IccPanel { mStatusPanel = (LinearLayout) findViewById(R.id.status_panel); mStatusText = (TextView) findViewById(R.id.status_text); - mPhone = PhoneFactory.getDefaultPhone(); + mPhone = PhoneApp.getPhone(); } @Override diff --git a/phone/src/com/android/phone2/InCallControlState.java b/phone/src/com/android/phone2/InCallControlState.java index d154d55..17bc4c3 100644 --- a/phone/src/com/android/phone2/InCallControlState.java +++ b/phone/src/com/android/phone2/InCallControlState.java @@ -102,20 +102,17 @@ public class InCallControlState { final boolean hasHoldingCall = !mPhone.getBackgroundCall().isIdle(); // Manage conference: - int phoneType = mPhone.getPhoneType(); - if (phoneType == Phone.PHONE_TYPE_GSM) { + if (TelephonyCapabilities.supportsConferenceCallManagement(mPhone)) { // This item is visible only if the foreground call is a // conference call, and it's enabled unless the "Manage // conference" UI is already up. manageConferenceVisible = PhoneUtils.isConferenceCall(fgCall); manageConferenceEnabled = manageConferenceVisible && !mInCallScreen.isManageConferenceMode(); - } else if (phoneType == Phone.PHONE_TYPE_CDMA) { - // CDMA has no concept of managing a conference call. + } else { + // This device has no concept of managing a conference call. manageConferenceVisible = false; manageConferenceEnabled = false; - } else { - throw new IllegalStateException("Unexpected phone type: " + phoneType); } // "Add call": @@ -141,20 +138,14 @@ public class InCallControlState { // "Mute": only enabled when the foreground call is ACTIVE. // (It's meaningless while on hold, or while DIALING/ALERTING.) - // Also disabled (on CDMA devices) during emergency calls. - if (phoneType == Phone.PHONE_TYPE_CDMA) { - Connection c = fgCall.getLatestConnection(); - boolean isEmergencyCall = false; - if (c != null) isEmergencyCall = PhoneNumberUtils.isEmergencyNumber(c.getAddress()); - - if (isEmergencyCall) { // disable "Mute" item - canMute = false; - muteIndicatorOn = false; - } else { - canMute = hasActiveForegroundCall; - muteIndicatorOn = PhoneUtils.getMute(mPhone); - } - } else if (phoneType == Phone.PHONE_TYPE_GSM) { + // It's also explicitly disabled during emergency calls. + Connection c = fgCall.getLatestConnection(); + boolean isEmergencyCall = false; + if (c != null) isEmergencyCall = PhoneNumberUtils.isEmergencyNumber(c.getAddress()); + if (isEmergencyCall) { // disable "Mute" item + canMute = false; + muteIndicatorOn = false; + } else { canMute = hasActiveForegroundCall; muteIndicatorOn = PhoneUtils.getMute(mPhone); } @@ -168,8 +159,8 @@ public class InCallControlState { dialpadVisible = mInCallScreen.isDialerOpened(); // "Hold: - if (phoneType == Phone.PHONE_TYPE_GSM) { - // GSM phones have the concept of "Hold" and "Unhold". + if (TelephonyCapabilities.supportsHoldAndUnhold(mPhone)) { + // This phone has the concept of explicit "Hold" and "Unhold" actions. supportsHold = true; // "On hold" means that there's a holding call and // *no* foreground call. (If there *is* a foreground call, @@ -180,8 +171,8 @@ public class InCallControlState { boolean okToHold = hasActiveForegroundCall && !hasHoldingCall; boolean okToUnhold = onHold; canHold = okToHold || okToUnhold; - } else if (phoneType == Phone.PHONE_TYPE_CDMA) { - // CDMA has no concept of "putting a call on hold." + } else { + // This device has no concept of "putting a call on hold." supportsHold = false; onHold = false; canHold = false; diff --git a/phone/src/com/android/phone2/InCallMenu.java b/phone/src/com/android/phone2/InCallMenu.java index d6ad635..9b04b38 100755 --- a/phone/src/com/android/phone2/InCallMenu.java +++ b/phone/src/com/android/phone2/InCallMenu.java @@ -210,12 +210,11 @@ class InCallMenu { // // Row 0: - // This usually has "Show/Hide dialpad", but that gets replaced by - // "Manage conference" if a conference call is active. + // This usually has "Show/Hide dialpad", but that might be replaced by + // "Manage conference" if a conference call is active (but only + // on phones that support "Manage conference" in the first place.) PhoneApp app = PhoneApp.getInstance(); - // As managing conference is only valid for GSM and not for CDMA - int phoneType = app.phone.getPhoneType(); - if (phoneType == Phone.PHONE_TYPE_GSM) { + if (TelephonyCapabilities.supportsConferenceCallManagement(app.phone)) { mInCallMenuView.addItemView(mManageConference, 0); } mInCallMenuView.addItemView(mShowDialpad, 0); @@ -229,16 +228,19 @@ class InCallMenu { // Row 2: // In this row we see *either* bluetooth/speaker/mute/hold // *or* answerAndHold/answerAndEnd, but never all 6 together. - // For CDMA only Answer or Ignore option is valid for a Call Waiting scenario - if (phoneType == Phone.PHONE_TYPE_CDMA) { - mInCallMenuView.addItemView(mAnswer, 2); - mInCallMenuView.addItemView(mIgnore, 2); - } else if (phoneType == Phone.PHONE_TYPE_GSM) { + if (TelephonyCapabilities.supportsHoldAndUnhold(app.phone)) { mInCallMenuView.addItemView(mHold, 2); + } + // For phones that allow explicit "Answer & Hold" and "Answer & + // End" actions for a call-waiting call, provide menu items for + // those. Otherwise, just provide basic "Answer" and "Ignore" + // items. + if (TelephonyCapabilities.supportsAnswerAndHold(app.phone)) { mInCallMenuView.addItemView(mAnswerAndHold, 2); mInCallMenuView.addItemView(mAnswerAndEnd, 2); } else { - throw new IllegalStateException("Unexpected phone type: " + phoneType); + mInCallMenuView.addItemView(mAnswer, 2); + mInCallMenuView.addItemView(mIgnore, 2); } mInCallMenuView.addItemView(mMute, 2); mInCallMenuView.addItemView(mSpeaker, 2); @@ -275,7 +277,8 @@ class InCallMenu { final boolean hasHoldingCall = !phone.getBackgroundCall().isIdle(); // For OTA call, only show dialpad, endcall, speaker, and mute menu items - if (hasActiveCall && (PhoneApp.getInstance().isOtaCallInActiveState())) { + if (hasActiveCall && TelephonyCapabilities.supportsOtasp(phone) && + (PhoneApp.getInstance().isOtaCallInActiveState())) { mAnswerAndHold.setVisible(false); mAnswerAndHold.setEnabled(false); mAnswerAndEnd.setVisible(false); @@ -316,37 +319,35 @@ class InCallMenu { // Special cases when an incoming call is ringing. if (hasRingingCall) { - // In the "call waiting" state, show ONLY the "answer & end" - // and "answer & hold" buttons, and nothing else. - // TODO: be sure to test this for "only one line in use and it's - // active" AND for "only one line in use and it's on hold". if (hasActiveCall && !hasHoldingCall) { - int phoneType = phone.getPhoneType(); - // For CDMA only make "Answer" and "Ignore" visible - if (phoneType == Phone.PHONE_TYPE_CDMA) { - mAnswer.setVisible(true); - mAnswer.setEnabled(true); - mIgnore.setVisible(true); - mIgnore.setEnabled(true); - - // Explicitly remove GSM menu items - mAnswerAndHold.setVisible(false); - mAnswerAndEnd.setVisible(false); - } else if (phoneType == Phone.PHONE_TYPE_GSM) { + // In the "call waiting" state, some devices allow separate + // "Answer & End" and "Answer & Hold" actions, and other + // devices just get basic "Answer" and "Ignore" actions. + if (TelephonyCapabilities.supportsAnswerAndHold(phone)) { mAnswerAndHold.setVisible(true); mAnswerAndHold.setEnabled(true); mAnswerAndEnd.setVisible(true); mAnswerAndEnd.setEnabled(true); - // Explicitly remove CDMA menu items + // Explicitly remove unused items mAnswer.setVisible(false); mIgnore.setVisible(false); - - mManageConference.setVisible(false); } else { - throw new IllegalStateException("Unexpected phone type: " + phoneType); + // Just make the basic "Answer" and "Ignore" visible + mAnswer.setVisible(true); + mAnswer.setEnabled(true); + mIgnore.setVisible(true); + mIgnore.setEnabled(true); + + // Explicitly remove unused items + mAnswerAndHold.setVisible(false); + mAnswerAndEnd.setVisible(false); } + // And regardless of the "Answer & Hold" capability of the + // current phone, disable everything else that's irrelevant to + // the call-waiting state. + mManageConference.setVisible(false); mShowDialpad.setVisible(false); mEndCall.setVisible(false); mAddCall.setVisible(false); diff --git a/phone/src/com/android/phone2/InCallScreen.java b/phone/src/com/android/phone2/InCallScreen.java index 0ff451f..e0e1024 100755 --- a/phone/src/com/android/phone2/InCallScreen.java +++ b/phone/src/com/android/phone2/InCallScreen.java @@ -52,12 +52,14 @@ import android.view.MotionEvent; import android.view.View; import android.view.ViewConfiguration; import android.view.ViewGroup; +import android.view.ViewStub; import android.view.Window; import android.view.WindowManager; import android.view.accessibility.AccessibilityEvent; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.widget.EditText; +import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.SlidingDrawer; import android.widget.TextView; @@ -302,7 +304,7 @@ public class InCallScreen extends Activity private boolean mIsDestroyed = false; private boolean mIsForegroundActivity = false; - // For use with CDMA Pause/Wait dialogs + // For use with Pause/Wait dialogs private String mPostDialStrAfterPause; private boolean mPauseInProgress = false; @@ -567,42 +569,6 @@ public class InCallScreen extends Activity initInCallScreen(); - // Create the dtmf dialer. The dialer view we use depends on the - // current platform: - // - // - On non-prox-sensor devices, it's the dialpad contained inside - // a SlidingDrawer widget (see dtmf_twelve_key_dialer.xml). - // - // - On "full touch UI" devices, it's the compact non-sliding - // dialpad that appears on the upper half of the screen, - // above the main cluster of InCallTouchUi buttons - // (see non_drawer_dialpad.xml). - // - // TODO: These should both be ViewStubs, and right here we should - // inflate one or the other. (Also, while doing that, let's also - // move this block of code over to initInCallScreen().) - // - SlidingDrawer dialerDrawer; - if (isTouchUiEnabled()) { - // This is a "full touch" device. - mDialerView = (DTMFTwelveKeyDialerView) findViewById(R.id.non_drawer_dtmf_dialer); - if (DBG) log("- Full touch device! Found dialerView: " + mDialerView); - dialerDrawer = null; // No SlidingDrawer used on this device. - } else { - // Use the old-style dialpad contained within the SlidingDrawer. - mDialerView = (DTMFTwelveKeyDialerView) findViewById(R.id.dtmf_dialer); - if (DBG) log("- Using SlidingDrawer-based dialpad. Found dialerView: " + mDialerView); - dialerDrawer = (SlidingDrawer) findViewById(R.id.dialer_container); - if (DBG) log(" ...and the SlidingDrawer: " + dialerDrawer); - } - // Sanity-check that (regardless of the device) at least the - // dialer view is present: - if (mDialerView == null) { - Log.e(LOG_TAG, "onCreate: couldn't find dialerView", new IllegalStateException()); - } - // Finally, create the DTMFTwelveKeyDialer instance. - mDialer = new DTMFTwelveKeyDialer(this, mDialerView, dialerDrawer); - registerForPhoneStates(); // No need to change wake state here; that happens in onResume() when we @@ -684,6 +650,7 @@ public class InCallScreen extends Activity // Check for any failures that happened during onCreate() or onNewIntent(). if (DBG) log("- onResume: initial status = " + mInCallInitialStatus); + boolean handledStartupError = false; if (mInCallInitialStatus != InCallInitStatus.SUCCESS) { if (DBG) log("- onResume: failure during startup: " + mInCallInitialStatus); @@ -691,6 +658,7 @@ public class InCallScreen extends Activity // something more specific to let the user deal with the // problem. handleStartupError(mInCallInitialStatus); + handledStartupError = true; // But it *is* OK to continue with the rest of onResume(), // since any further setup steps (like updateScreen() and the @@ -710,10 +678,8 @@ public class InCallScreen extends Activity takeKeyEvents(true); - boolean phoneIsCdma = (mPhone.getPhoneType() == Phone.PHONE_TYPE_CDMA); - boolean inOtaCall = false; - if (phoneIsCdma) { + if (TelephonyCapabilities.supportsOtasp(mPhone)) { inOtaCall = initOtaState(); } if (!inOtaCall) { @@ -729,13 +695,38 @@ public class InCallScreen extends Activity InCallInitStatus status = syncWithPhoneState(); if (status != InCallInitStatus.SUCCESS) { - if (DBG) log("- syncWithPhoneState failed! status = " + status); + if (DBG) log("- onResume: syncWithPhoneState failed! status = " + status); // Couldn't update the UI, presumably because the phone is totally - // idle. But don't endInCallScreenSession immediately, since we might still - // have an error dialog up that the user needs to see. - // (And in that case, the error dialog is responsible for calling - // endInCallScreenSession when the user dismisses it.) - } else if (phoneIsCdma) { + // idle. + + if (handledStartupError) { + // Do NOT bail out of the in-call UI, since there's + // presumably a dialog visible right now (see the call to + // handleStartupError() above.) + // + // In this case, stay here for now, and we'll eventually + // leave the InCallScreen when the user presses the + // dialog's OK button (see bailOutAfterErrorDialog()). + Log.i(LOG_TAG, " ==> syncWithPhoneState failed, but staying here anyway."); + } else { + // The phone is idle, and we did NOT handle a + // startup error during this pass thru onResume. + // + // This basically means that we're being resumed because of + // some action *other* than a new intent. (For example, + // the user pressing POWER to wake up the device, causing + // the InCallScreen to come back to the foreground.) + // + // In this scenario we do NOT want to stay here on the + // InCallScreen: we're not showing any useful info to the + // user (like a dialog), and the in-call UI itself is + // useless if there's no active call. So bail out. + Log.i(LOG_TAG, " ==> syncWithPhoneState failed; bailing out!"); + dismissAllDialogs(); + endInCallScreenSession(); + return; + } + } else if (TelephonyCapabilities.supportsOtasp(mPhone)) { if (mInCallScreenMode == InCallScreenMode.OTA_NORMAL || mInCallScreenMode == InCallScreenMode.OTA_ENDED) { mDialer.setHandleVisible(false); @@ -1034,26 +1025,18 @@ public class InCallScreen extends Activity if (!mRegisteredForPhoneStates) { mPhone.registerForPreciseCallStateChanged(mHandler, PHONE_STATE_CHANGED, null); mPhone.registerForDisconnect(mHandler, PHONE_DISCONNECT, null); - int phoneType = mPhone.getPhoneType(); - if (phoneType == Phone.PHONE_TYPE_GSM) { - mPhone.registerForMmiInitiate(mHandler, PhoneApp.MMI_INITIATE, null); - - // register for the MMI complete message. Upon completion, - // PhoneUtils will bring up a system dialog instead of the - // message display class in PhoneUtils.displayMMIComplete(). - // We'll listen for that message too, so that we can finish - // the activity at the same time. - mPhone.registerForMmiComplete(mHandler, PhoneApp.MMI_COMPLETE, null); - } else if (phoneType == Phone.PHONE_TYPE_CDMA) { - if (DBG) log("Registering for Call Waiting."); - mPhone.registerForCallWaiting(mHandler, PHONE_CDMA_CALL_WAITING, null); - } else { - throw new IllegalStateException("Unexpected phone type: " + phoneType); - } - + mPhone.registerForMmiInitiate(mHandler, PhoneApp.MMI_INITIATE, null); + + // register for the MMI complete message. Upon completion, + // PhoneUtils will bring up a system dialog instead of the + // message display class in PhoneUtils.displayMMIComplete(). + // We'll listen for that message too, so that we can finish + // the activity at the same time. + mPhone.registerForMmiComplete(mHandler, PhoneApp.MMI_COMPLETE, null); + mPhone.registerForCallWaiting(mHandler, PHONE_CDMA_CALL_WAITING, null); mPhone.setOnPostDialCharacter(mHandler, POST_ON_DIAL_CHARS, null); mPhone.registerForSuppServiceFailed(mHandler, SUPP_SERVICE_FAILED, null); - if (phoneType == Phone.PHONE_TYPE_CDMA) { + if (TelephonyCapabilities.supportsOtasp(mPhone)) { mPhone.registerForCdmaOtaStatusChange(mHandler, EVENT_OTA_PROVISION_CHANGE, null); } mRegisteredForPhoneStates = true; @@ -1072,6 +1055,11 @@ public class InCallScreen extends Activity /* package */ void updateAfterRadioTechnologyChange() { if (DBG) Log.d(LOG_TAG, "updateAfterRadioTechnologyChange()..."); + + // Reset the call screen since the calls cannot be transferred + // across radio technologies. + resetInCallScreenMode(); + // Unregister for all events from the old obsolete phone unregisterForPhoneStates(); @@ -1132,7 +1120,7 @@ public class InCallScreen extends Activity // InCallScreen UI started with Intent of ACTION_SHOW_ACTIVATION // to show OTA Activation screen at power up. if ((action.equals(ACTION_SHOW_ACTIVATION)) - && ((mPhone.getPhoneType() == Phone.PHONE_TYPE_CDMA))) { + && (TelephonyCapabilities.supportsOtasp(mPhone))) { setInCallScreenMode(InCallScreenMode.OTA_NORMAL); if ((app.cdmaOtaProvisionData != null) && (!app.cdmaOtaProvisionData.isOtaCallIntentProcessed)) { @@ -1238,6 +1226,42 @@ public class InCallScreen extends Activity // Helper class to run the "Manage conference" UI mManageConferenceUtils = new ManageConferenceUtils(this, mPhone); + + // Create the dtmf dialer. The dialer view we use depends on the + // current platform: + // + // - On non-prox-sensor devices, it's the dialpad contained inside + // a SlidingDrawer widget (see dtmf_twelve_key_dialer.xml). + // + // - On "full touch UI" devices, it's the compact non-sliding + // dialpad that appears on the upper half of the screen, + // above the main cluster of InCallTouchUi buttons + // (see non_drawer_dialpad.xml). + // + SlidingDrawer dialerDrawer; + if (isTouchUiEnabled()) { + // This is a "full touch" device. + ViewStub stub = (ViewStub)findViewById(R.id.non_drawer_dialpad_stub); + stub.inflate(); + mDialerView = (DTMFTwelveKeyDialerView) findViewById(R.id.non_drawer_dtmf_dialer); + if (DBG) log("- Full touch device! Found dialerView: " + mDialerView); + dialerDrawer = null; // No SlidingDrawer used on this device. + } else { + // Use the old-style dialpad contained within the SlidingDrawer. + ViewStub stub = (ViewStub)findViewById(R.id.dtmf_dialer_stub); + stub.inflate(); + mDialerView = (DTMFTwelveKeyDialerView) findViewById(R.id.dtmf_dialer); + if (DBG) log("- Using SlidingDrawer-based dialpad. Found dialerView: " + mDialerView); + dialerDrawer = (SlidingDrawer) findViewById(R.id.dialer_container); + if (DBG) log(" ...and the SlidingDrawer: " + dialerDrawer); + } + // Sanity-check that (regardless of the device) at least the + // dialer view is present: + if (mDialerView == null) { + Log.e(LOG_TAG, "onCreate: couldn't find dialerView", new IllegalStateException()); + } + // Finally, create the DTMFTwelveKeyDialer instance. + mDialer = new DTMFTwelveKeyDialer(this, mDialerView, dialerDrawer); } /** @@ -2034,17 +2058,19 @@ public class InCallScreen extends Activity if (VDBG) log("handlePostOnDialChar: state = " + state + ", ch = " + ch); - int phoneType = mPhone.getPhoneType(); switch (state) { case STARTED: - if (phoneType == Phone.PHONE_TYPE_CDMA) { - mDialer.stopLocalToneCdma(); - if (mPauseInProgress) { - showPausePromptDialogCDMA(c, mPostDialStrAfterPause); - } - mPauseInProgress = false; - mDialer.startLocalToneCdma(ch); + mDialer.stopLocalToneIfNeeded(); + if (mPauseInProgress) { + /** + * Note that on some devices, this will never happen, + * because we will not ever enter the PAUSE state. + */ + showPausePromptDialog(c, mPostDialStrAfterPause); } + mPauseInProgress = false; + mDialer.startLocalToneIfNeeded(ch); + // TODO: is this needed, now that you can't actually // type DTMF chars or dial directly from here? // If so, we'd need to yank you out of the in-call screen @@ -2053,35 +2079,28 @@ public class InCallScreen extends Activity break; case WAIT: + // wait shows a prompt. if (DBG) log("handlePostOnDialChars: show WAIT prompt..."); + mDialer.stopLocalToneIfNeeded(); String postDialStr = c.getRemainingPostDialString(); - if (phoneType == Phone.PHONE_TYPE_CDMA) { - mDialer.stopLocalToneCdma(); - showWaitPromptDialogCDMA(c, postDialStr); - } else if (phoneType == Phone.PHONE_TYPE_GSM) { - showWaitPromptDialogGSM(c, postDialStr); - } else { - throw new IllegalStateException("Unexpected phone type: " + phoneType); - } + showWaitPromptDialog(c, postDialStr); break; case WILD: if (DBG) log("handlePostOnDialChars: show WILD prompt"); + mDialer.stopLocalToneIfNeeded(); showWildPromptDialog(c); break; case COMPLETE: - if (phoneType == Phone.PHONE_TYPE_CDMA) { - mDialer.stopLocalToneCdma(); - } + mDialer.stopLocalToneIfNeeded(); break; case PAUSE: - if (phoneType == Phone.PHONE_TYPE_CDMA) { - mPostDialStrAfterPause = c.getRemainingPostDialString(); - mDialer.stopLocalToneCdma(); - mPauseInProgress = true; - } + // pauses for a brief period of time then continue dialing. + mDialer.stopLocalToneIfNeeded(); + mPostDialStrAfterPause = c.getRemainingPostDialString(); + mPauseInProgress = true; break; default: @@ -2090,52 +2109,12 @@ public class InCallScreen extends Activity } } - private void showWaitPromptDialogGSM(final Connection c, String postDialStr) { - if (DBG) log("showWaitPromptDialogGSM: '" + postDialStr + "'..."); - - Resources r = getResources(); - StringBuilder buf = new StringBuilder(); - buf.append(r.getText(R.string.wait_prompt_str)); - buf.append(postDialStr); - - // if (DBG) log("- mWaitPromptDialog = " + mWaitPromptDialog); - if (mWaitPromptDialog != null) { - if (DBG) log("- DISMISSING mWaitPromptDialog."); - mWaitPromptDialog.dismiss(); // safe even if already dismissed - mWaitPromptDialog = null; - } - - mWaitPromptDialog = new AlertDialog.Builder(this) - .setMessage(buf.toString()) - .setPositiveButton(R.string.send_button, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int whichButton) { - if (DBG) log("handle WAIT_PROMPT_CONFIRMED, proceed..."); - c.proceedAfterWaitChar(); - PhoneApp.getInstance().pokeUserActivity(); - } - }) - .setOnCancelListener(new DialogInterface.OnCancelListener() { - public void onCancel(DialogInterface dialog) { - if (DBG) log("handle POST_DIAL_CANCELED!"); - c.cancelPostDial(); - PhoneApp.getInstance().pokeUserActivity(); - } - }) - .create(); - mWaitPromptDialog.getWindow().addFlags( - WindowManager.LayoutParams.FLAG_BLUR_BEHIND); - mWaitPromptDialog.show(); - } - /** - * Processes the CDMA specific requirements of a WAIT character in a - * dial string. - * * Pop up an alert dialog with OK and Cancel buttons to allow user to * Accept or Reject the WAIT inserted as part of the Dial string. */ - private void showWaitPromptDialogCDMA(final Connection c, String postDialStr) { - if (DBG) log("showWaitPromptDialogCDMA: '" + postDialStr + "'..."); + private void showWaitPromptDialog(final Connection c, String postDialStr) { + if (DBG) log("showWaitPromptDialogChoice: '" + postDialStr + "'..."); Resources r = getResources(); StringBuilder buf = new StringBuilder(); @@ -2167,6 +2146,7 @@ public class InCallScreen extends Activity .create(); mWaitPromptDialog.getWindow().addFlags( WindowManager.LayoutParams.FLAG_BLUR_BEHIND); + mWaitPromptDialog.show(); } @@ -2174,7 +2154,7 @@ public class InCallScreen extends Activity * Pop up an alert dialog which waits for 2 seconds for each P (Pause) Character entered * as part of the Dial String. */ - private void showPausePromptDialogCDMA(final Connection c, String postDialStrAfterPause) { + private void showPausePromptDialog(final Connection c, String postDialStrAfterPause) { Resources r = getResources(); StringBuilder buf = new StringBuilder(); buf.append(r.getText(R.string.pause_prompt_str)); @@ -2378,13 +2358,13 @@ public class InCallScreen extends Activity && (fgLatestConnection.getPostDialState() == Connection.PostDialState.WAIT)) { if(DBG) log("show the Wait dialog for CDMA"); postDialStr = fgLatestConnection.getRemainingPostDialString(); - showWaitPromptDialogCDMA(fgLatestConnection, postDialStr); + showWaitPromptDialog(fgLatestConnection, postDialStr); } } else if (phoneType == Phone.PHONE_TYPE_GSM) { for (Connection cn : fgConnections) { if ((cn != null) && (cn.getPostDialState() == Connection.PostDialState.WAIT)) { postDialStr = cn.getRemainingPostDialString(); - showWaitPromptDialogGSM(cn, postDialStr); + showWaitPromptDialog(cn, postDialStr); } } } else { @@ -2413,27 +2393,33 @@ public class InCallScreen extends Activity // Make sure the Phone is "in use". (If not, we shouldn't be on // this screen in the first place.) - // Need to treat running MMI codes as a connection as well. - // Do not check for getPendingMmiCodes when phone is a CDMA phone - int phoneType = mPhone.getPhoneType(); - - if ((phoneType == Phone.PHONE_TYPE_CDMA) + // An active or just-ended OTA call counts as "in use". + if (TelephonyCapabilities.supportsOtasp(mPhone) && ((mInCallScreenMode == InCallScreenMode.OTA_NORMAL) - || (mInCallScreenMode == InCallScreenMode.OTA_ENDED))) { + || (mInCallScreenMode == InCallScreenMode.OTA_ENDED))) { // Even when OTA Call ends, need to show OTA End UI, // so return Success to allow UI update. return InCallInitStatus.SUCCESS; } - if ((phoneType == Phone.PHONE_TYPE_CDMA) - || !mForegroundCall.isIdle() || !mBackgroundCall.isIdle() || !mRingingCall.isIdle() - || !mPhone.getPendingMmiCodes().isEmpty()) { + // If an MMI code is running that also counts as "in use". + // + // TODO: We currently only call getPendingMmiCodes() for GSM + // phones. (The code's been that way all along.) But CDMAPhone + // does in fact implement getPendingMmiCodes(), so should we + // check that here regardless of the phone type? + boolean hasPendingMmiCodes = + (mPhone.getPhoneType() == Phone.PHONE_TYPE_GSM) + && !mPhone.getPendingMmiCodes().isEmpty(); + + if (!mForegroundCall.isIdle() || !mBackgroundCall.isIdle() || !mRingingCall.isIdle() + || hasPendingMmiCodes) { if (VDBG) log("syncWithPhoneState: it's ok to be here; update the screen..."); updateScreen(); return InCallInitStatus.SUCCESS; } - if (DBG) log("syncWithPhoneState: phone is idle; we shouldn't be here!"); + Log.i(LOG_TAG, "syncWithPhoneState: phone is idle (shouldn't be here)"); return InCallInitStatus.PHONE_NOT_IN_USE; } @@ -2552,7 +2538,7 @@ public class InCallScreen extends Activity final PhoneApp app = PhoneApp.getInstance(); - if ((mPhone.getPhoneType() == Phone.PHONE_TYPE_CDMA) && (mPhone.isOtaSpNumber(number))) { + if ((TelephonyCapabilities.supportsOtasp(mPhone)) && (mPhone.isOtaSpNumber(number))) { if (DBG) log("placeCall: isOtaSpNumber() returns true"); setInCallScreenMode(InCallScreenMode.OTA_NORMAL); if (app.cdmaOtaProvisionData != null) { @@ -2569,15 +2555,8 @@ public class InCallScreen extends Activity int callStatus; Uri contactUri = intent.getData(); - if (null != mProviderGatewayUri && - !(isEmergencyNumber || isEmergencyIntent) && - PhoneUtils.isRoutableViaGateway(number)) { // Filter out MMI, OTA and other codes. - - callStatus = PhoneUtils.placeCallVia( - this, mPhone, number, contactUri, mProviderGatewayUri); - } else { - callStatus = PhoneUtils.placeCall(mPhone, number, contactUri); - } + callStatus = PhoneUtils.placeCall(this, mPhone, number, contactUri, + (isEmergencyNumber || isEmergencyIntent), mProviderGatewayUri); switch (callStatus) { case PhoneUtils.CALL_STATUS_DIALED: @@ -3190,9 +3169,11 @@ public class InCallScreen extends Activity mProviderAddress); TextView message = (TextView) findViewById(R.id.callingVia); - message.setCompoundDrawablesWithIntrinsicBounds(mProviderIcon, null, null, null); message.setText(text); + ImageView image = (ImageView) findViewById(R.id.callingViaIcon); + image.setImageDrawable(mProviderIcon); + overlay.setVisibility(View.VISIBLE); // Remove any zombie messages and then send a message to @@ -4682,7 +4663,7 @@ public class InCallScreen extends Activity return false; } - if (mPhone.getPhoneType() != Phone.PHONE_TYPE_CDMA) { + if (!TelephonyCapabilities.supportsOtasp(mPhone)) { return false; } @@ -4765,7 +4746,7 @@ public class InCallScreen extends Activity private boolean initOtaState() { boolean inOtaCall = false; - if (mPhone.getPhoneType() == Phone.PHONE_TYPE_CDMA) { + if (TelephonyCapabilities.supportsOtasp(mPhone)) { final PhoneApp app = PhoneApp.getInstance(); if ((app.cdmaOtaScreenState == null) || (app.cdmaOtaProvisionData == null)) { @@ -4803,7 +4784,7 @@ public class InCallScreen extends Activity public void updateMenuItems() { if (mInCallMenu != null) { - boolean okToShowMenu = mInCallMenu.updateItems(PhoneApp.getInstance().phone); + boolean okToShowMenu = mInCallMenu.updateItems(PhoneApp.getPhone()); if (!okToShowMenu) { dismissMenu(true); } diff --git a/phone/src/com/android/phone2/InCallTouchUi.java b/phone/src/com/android/phone2/InCallTouchUi.java index a568b65..edec37b 100644 --- a/phone/src/com/android/phone2/InCallTouchUi.java +++ b/phone/src/com/android/phone2/InCallTouchUi.java @@ -183,7 +183,7 @@ public class InCallTouchUi extends FrameLayout mSwapButton = (ImageButton) mInCallControls.findViewById(R.id.swapButton); mSwapButton.setOnClickListener(this); mSwapButtonLabel = (TextView) mInCallControls.findViewById(R.id.swapButtonLabel); - if (PhoneApp.getInstance().phone.getPhoneType() == Phone.PHONE_TYPE_CDMA) { + if (PhoneApp.getPhone().getPhoneType() == Phone.PHONE_TYPE_CDMA) { // In CDMA we use a generalized text - "Manage call", as behavior on selecting // this option depends entirely on what the current call state is. mSwapButtonLabel.setText(R.string.onscreenManageCallsText); diff --git a/phone/src/com/android/phone2/NetworkSetting.java b/phone/src/com/android/phone2/NetworkSetting.java index 7fcf75f..df893ba 100644 --- a/phone/src/com/android/phone2/NetworkSetting.java +++ b/phone/src/com/android/phone2/NetworkSetting.java @@ -218,7 +218,7 @@ public class NetworkSetting extends PreferenceActivity addPreferencesFromResource(R.xml.carrier_select); - mPhone = PhoneApp.getInstance().phone; + mPhone = PhoneApp.getPhone(); mNetworkList = (PreferenceGroup) getPreferenceScreen().findPreference(LIST_NETWORKS_KEY); mNetworkMap = new HashMap<Preference, NetworkInfo>(); diff --git a/phone/src/com/android/phone2/NotificationMgr.java b/phone/src/com/android/phone2/NotificationMgr.java index d9f1972..2e7503a 100644 --- a/phone/src/com/android/phone2/NotificationMgr.java +++ b/phone/src/com/android/phone2/NotificationMgr.java @@ -84,8 +84,8 @@ public class NotificationMgr implements CallerInfoAsyncQuery.OnQueryCompleteList private StatusBarManager mStatusBar; private StatusBarMgr mStatusBarMgr; private Toast mToast; - private IBinder mSpeakerphoneIcon; - private IBinder mMuteIcon; + private boolean mShowingSpeakerphoneIcon; + private boolean mShowingMuteIcon; // used to track the missed call counter, default to 0. private int mNumberMissedCalls = 0; @@ -433,16 +433,16 @@ public class NotificationMgr implements CallerInfoAsyncQuery.OnQueryCompleteList } void notifySpeakerphone() { - if (mSpeakerphoneIcon == null) { - mSpeakerphoneIcon = mStatusBar.addIcon("speakerphone", - android.R.drawable.stat_sys_speakerphone, 0); + if (!mShowingSpeakerphoneIcon) { + mStatusBar.setIcon("speakerphone", android.R.drawable.stat_sys_speakerphone, 0); + mShowingSpeakerphoneIcon = true; } } void cancelSpeakerphone() { - if (mSpeakerphoneIcon != null) { - mStatusBar.removeIcon(mSpeakerphoneIcon); - mSpeakerphoneIcon = null; + if (mShowingSpeakerphoneIcon) { + mStatusBar.removeIcon("speakerphone"); + mShowingSpeakerphoneIcon = false; } } @@ -463,15 +463,16 @@ public class NotificationMgr implements CallerInfoAsyncQuery.OnQueryCompleteList } void notifyMute() { - if (mMuteIcon == null) { - mMuteIcon = mStatusBar.addIcon("mute", android.R.drawable.stat_notify_call_mute, 0); + if (mShowingMuteIcon) { + mStatusBar.setIcon("mute", android.R.drawable.stat_notify_call_mute, 0); + mShowingMuteIcon = true; } } void cancelMute() { - if (mMuteIcon != null) { - mStatusBar.removeIcon(mMuteIcon); - mMuteIcon = null; + if (mShowingMuteIcon) { + mStatusBar.removeIcon("mute"); + mShowingMuteIcon = false; } } @@ -502,9 +503,7 @@ public class NotificationMgr implements CallerInfoAsyncQuery.OnQueryCompleteList // Display the appropriate "in-call" icon in the status bar, // which depends on the current phone and/or bluetooth state. - - - boolean enhancedVoicePrivacy = PhoneApp.getInstance().notifier.getCdmaVoicePrivacyState(); + boolean enhancedVoicePrivacy = PhoneApp.getInstance().notifier.getVoicePrivacyState(); if (DBG) log("updateInCallNotification: enhancedVoicePrivacy = " + enhancedVoicePrivacy); if (!hasActiveCall && hasHoldingCall) { @@ -749,7 +748,7 @@ public class NotificationMgr implements CallerInfoAsyncQuery.OnQueryCompleteList } } - if (mPhone.getPhoneType() == Phone.PHONE_TYPE_CDMA) { + if (TelephonyCapabilities.supportsVoiceMessageCount(mPhone)) { int vmCount = mPhone.getVoiceMessageCount(); String titleFormat = mContext.getString(R.string.notification_voicemail_title_count); notificationTitle = String.format(titleFormat, vmCount); @@ -815,7 +814,7 @@ public class NotificationMgr implements CallerInfoAsyncQuery.OnQueryCompleteList if (showExpandedNotification) { Intent intent = new Intent(Intent.ACTION_MAIN); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - intent.setClassName("com.android.phone", + intent.setClassName("com.android.phone2", "com.android.phone2.CallFeaturesSetting"); notification = new Notification( @@ -903,7 +902,7 @@ public class NotificationMgr implements CallerInfoAsyncQuery.OnQueryCompleteList intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); // Use NetworkSetting to handle the selection intent - intent.setComponent(new ComponentName("com.android.phone", + intent.setComponent(new ComponentName("com.android.phone2", "com.android.phone2.NetworkSetting")); PendingIntent pi = PendingIntent.getActivity(mContext, 0, intent, 0); @@ -926,7 +925,7 @@ public class NotificationMgr implements CallerInfoAsyncQuery.OnQueryCompleteList * @param serviceState Phone service state */ void updateNetworkSelection(int serviceState) { - if (mPhone.getPhoneType() == Phone.PHONE_TYPE_GSM) { + if (TelephonyCapabilities.supportsNetworkSelection(mPhone)) { // get the shared preference of network_selection. // empty is auto mode, otherwise it is the operator alpha name // in case there is no operator name, check the operator numeric diff --git a/phone/src/com/android/phone2/OtaStartupReceiver.java b/phone/src/com/android/phone2/OtaStartupReceiver.java index bd16435..d38976f 100644 --- a/phone/src/com/android/phone2/OtaStartupReceiver.java +++ b/phone/src/com/android/phone2/OtaStartupReceiver.java @@ -53,13 +53,13 @@ public class OtaStartupReceiver extends BroadcastReceiver { public void onReceive(Context context, Intent intent) { mContext = context; - if (!OtaUtils.isCdmaPhone()) { - if (DBG) Log.d(TAG, "Not a CDMA phone, no need to process OTA"); + if (!TelephonyCapabilities.supportsOtasp(PhoneApp.getPhone())) { + if (DBG) Log.d(TAG, "OTASP not supported, nothing to do."); return; } if (shouldPostpone(context)) { - if (DBG) Log.d(TAG, "Postponing CDMA provisioning until wizard runs"); + if (DBG) Log.d(TAG, "Postponing OTASP until wizard runs"); return; } diff --git a/phone/src/com/android/phone2/OtaUtils.java b/phone/src/com/android/phone2/OtaUtils.java index 1632cb9..5a4ebc1 100644 --- a/phone/src/com/android/phone2/OtaUtils.java +++ b/phone/src/com/android/phone2/OtaUtils.java @@ -48,6 +48,13 @@ import android.widget.ProgressBar; import android.widget.TextView; /** + * TODO: This is Over The Air Service Provisioning (OTASP) + * A better name would be OtaspUtils.java. + * + * TODO: OTASP could UI may be substantially different on + * future devices, and may not necessarily be built-in + * to the InCallScreen. + * * Handles all OTA Call related logic and UI functionality. * The InCallScreen interacts with this class to perform an OTA Call. * @@ -58,8 +65,6 @@ import android.widget.TextView; */ public class OtaUtils { private static final String LOG_TAG = "OtaUtils"; - private static final String UNACTIVATED_MIN2_VALUE = "000000"; - private static final String UNACTIVATED_MIN_VALUE = "1111110111"; private static final boolean DBG = (PhoneApp.DBG_LEVEL >= 1); public static final int OTA_SHOW_ACTIVATION_SCREEN_OFF = 0; @@ -145,22 +150,6 @@ public class OtaUtils { } /** - * Returns true if the phone needs activation. - * - * @param minString the phone's MIN configuration string - * @return true if phone needs activation - * @throws OtaConfigurationException if the string is invalid - */ - public static boolean needsActivation(String minString) throws IllegalArgumentException { - if (minString == null || (minString.length() < 6)) { - throw new IllegalArgumentException(); - } - return (minString.equals(UNACTIVATED_MIN_VALUE) - || minString.substring(0,6).equals(UNACTIVATED_MIN2_VALUE)) - || SystemProperties.getBoolean("test_cdma_setup", false); - } - - /** * Starts the OTA provisioning call. If the MIN isn't available yet, it returns false and adds * an event to return the request to the calling app when it becomes available. * @@ -184,20 +173,9 @@ public class OtaUtils { phone.registerForSubscriptionInfoReady(handler, request, null); return false; } - phone.unregisterForSubscriptionInfoReady(handler); - String min = phone.getCdmaMin(); - - if (DBG) log("min_string: " + min); - - boolean phoneNeedsActivation = false; - try { - phoneNeedsActivation = needsActivation(min); - } catch (IllegalArgumentException e) { - if (DBG) log("invalid MIN string, exit"); - return true; // If the MIN string is wrong, there's nothing else we can do. - } + boolean phoneNeedsActivation = phone.needsOtaServiceProvisioning(); if (DBG) log("phoneNeedsActivation is set to " + phoneNeedsActivation); int otaShowActivationScreen = context.getResources().getInteger( @@ -429,7 +407,7 @@ public class OtaUtils { /** * Show either programming success dialog when OTA provisioning succeeds, or - * programming failure dialog when it fails. See {@link otaShowProgramFailure} + * programming failure dialog when it fails. See {@link #otaShowProgramFailure} * for more details. */ public void otaShowSuccessFailure() { @@ -1013,7 +991,7 @@ public class OtaUtils { Log.d(LOG_TAG, msg); } - public static boolean isCdmaPhone() { - return (PhoneApp.getInstance().phone.getPhoneType() == Phone.PHONE_TYPE_CDMA); + private static boolean isCdmaPhone() { + return (PhoneApp.getPhone().getPhoneType() == Phone.PHONE_TYPE_CDMA); } } diff --git a/phone/src/com/android/phone2/OutgoingCallBroadcaster.java b/phone/src/com/android/phone2/OutgoingCallBroadcaster.java index e7994af..2ad7e07 100644 --- a/phone/src/com/android/phone2/OutgoingCallBroadcaster.java +++ b/phone/src/com/android/phone2/OutgoingCallBroadcaster.java @@ -95,8 +95,8 @@ public class OutgoingCallBroadcaster extends Activity { number = getResultData(); final PhoneApp app = PhoneApp.getInstance(); - int phoneType = app.phone.getPhoneType(); - if (phoneType == Phone.PHONE_TYPE_CDMA) { + + if (TelephonyCapabilities.supportsOtasp(app.phone)) { boolean activateState = (app.cdmaOtaScreenState.otaScreenState == OtaUtils.CdmaOtaScreenState.OtaScreenState.OTA_STATUS_ACTIVATION); boolean dialogState = (app.cdmaOtaScreenState.otaScreenState @@ -124,9 +124,9 @@ public class OutgoingCallBroadcaster extends Activity { if (number == null) { if (DBG) Log.v(TAG, "CALL cancelled (null number), returning..."); return; - } else if ((phoneType == Phone.PHONE_TYPE_CDMA) - && ((app.phone.getState() != Phone.State.IDLE) - && (app.phone.isOtaSpNumber(number)))) { + } else if (TelephonyCapabilities.supportsOtasp(app.phone) + && (app.phone.getState() != Phone.State.IDLE) + && (app.phone.isOtaSpNumber(number))) { if (DBG) Log.v(TAG, "Call is active, a 2nd OTA call cancelled -- returning."); return; } else if (PhoneNumberUtils.isEmergencyNumber(number)) { @@ -286,7 +286,7 @@ public class OutgoingCallBroadcaster extends Activity { if (number == null || TextUtils.isEmpty(number)) { if (intent.getBooleanExtra(EXTRA_SEND_EMPTY_FLASH, false)) { Log.i(TAG, "onCreate: SEND_EMPTY_FLASH..."); - PhoneUtils.sendEmptyFlash(PhoneApp.getInstance().phone); + PhoneUtils.sendEmptyFlash(PhoneApp.getPhone()); finish(); return; } else { diff --git a/phone/src/com/android/phone2/PhoneApp.java b/phone/src/com/android/phone2/PhoneApp.java index 0072f3a..936292d 100755 --- a/phone/src/com/android/phone2/PhoneApp.java +++ b/phone/src/com/android/phone2/PhoneApp.java @@ -387,6 +387,7 @@ public class PhoneApp extends Application implements AccelerometerListener.Orien @Override public void onCreate() { if (VDBG) Log.v(LOG_TAG, "onCreate()..."); + Log.v(LOG_TAG, "haha"); ContentResolver resolver = getContentResolver(); @@ -458,9 +459,7 @@ public class PhoneApp extends Application implements AccelerometerListener.Orien } // register for MMI/USSD - if (phoneType == Phone.PHONE_TYPE_GSM) { - phone.registerForMmiComplete(mHandler, MMI_COMPLETE, null); - } + phone.registerForMmiComplete(mHandler, MMI_COMPLETE, null); // register connection tracking to PhoneUtils PhoneUtils.initializeConnectionHandler(phone); @@ -527,9 +526,7 @@ public class PhoneApp extends Application implements AccelerometerListener.Orien } } - boolean phoneIsCdma = (phone.getPhoneType() == Phone.PHONE_TYPE_CDMA); - - if (phoneIsCdma) { + if (TelephonyCapabilities.supportsOtasp(phone)) { cdmaOtaProvisionData = new OtaUtils.CdmaOtaProvisionData(); cdmaOtaConfigData = new OtaUtils.CdmaOtaConfigData(); cdmaOtaScreenState = new OtaUtils.CdmaOtaScreenState(); @@ -588,6 +585,13 @@ public class PhoneApp extends Application implements AccelerometerListener.Orien return sMe; } + /** + * Returns the Phone associated with this instance + */ + static Phone getPhone() { + return getInstance().phone; + } + Ringer getRinger() { return ringer; } @@ -613,7 +617,7 @@ public class PhoneApp extends Application implements AccelerometerListener.Orien intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS | Intent.FLAG_ACTIVITY_NO_USER_ACTION); - intent.setClassName("com.android.phone", getCallScreenClassName()); + intent.setClassName("com.android.phone2", getCallScreenClassName()); return intent; } @@ -707,11 +711,12 @@ public class PhoneApp extends Application implements AccelerometerListener.Orien */ void dismissCallScreen() { if (mInCallScreen != null) { - if (mInCallScreen.isOtaCallInActiveState() + if ((TelephonyCapabilities.supportsOtasp(phone)) && + (mInCallScreen.isOtaCallInActiveState() || mInCallScreen.isOtaCallInEndState() || ((cdmaOtaScreenState != null) && (cdmaOtaScreenState.otaScreenState - != CdmaOtaScreenState.OtaScreenState.OTA_STATUS_UNDEFINED))) { + != CdmaOtaScreenState.OtaScreenState.OTA_STATUS_UNDEFINED)))) { // TODO: During OTA Call, display should not become dark to // allow user to see OTA UI update. Phone app needs to hold // a SCREEN_DIM_WAKE_LOCK wake lock during the entire OTA call. @@ -1255,11 +1260,12 @@ public class PhoneApp extends Application implements AccelerometerListener.Orien private void initForNewRadioTechnology() { if (DBG) Log.d(LOG_TAG, "initForNewRadioTechnology..."); - if (phone.getPhoneType() == Phone.PHONE_TYPE_CDMA) { + if (phone.getPhoneType() == Phone.PHONE_TYPE_CDMA) { // Create an instance of CdmaPhoneCallState and initialize it to IDLE cdmaPhoneCallState = new CdmaPhoneCallState(); cdmaPhoneCallState.CdmaPhoneCallStateInit(); - + } + if (TelephonyCapabilities.supportsOtasp(phone)) { //create instances of CDMA OTA data classes if (cdmaOtaProvisionData == null) { cdmaOtaProvisionData = new OtaUtils.CdmaOtaProvisionData(); @@ -1273,6 +1279,9 @@ public class PhoneApp extends Application implements AccelerometerListener.Orien if (cdmaOtaInCallScreenUiState == null) { cdmaOtaInCallScreenUiState = new OtaUtils.CdmaOtaInCallScreenUiState(); } + } else { + //Clean up OTA data in GSM/UMTS. It is valid only for CDMA + clearOtaState(); } ringer.updateRingerContextAfterRadioTechnologyChange(this.phone); @@ -1459,7 +1468,7 @@ public class PhoneApp extends Application implements AccelerometerListener.Orien } else if (action.equals(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED)) { handleServiceStateChanged(intent); } else if (action.equals(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED)) { - if (phone.getPhoneType() == Phone.PHONE_TYPE_CDMA) { + if (TelephonyCapabilities.supportsEcm(phone)) { Log.d(LOG_TAG, "Emergency Callback Mode arrived in PhoneApp."); // Start Emergency Callback Mode service if (intent.getBooleanExtra("phoneinECMState", false)) { @@ -1467,8 +1476,10 @@ public class PhoneApp extends Application implements AccelerometerListener.Orien EmergencyCallbackModeService.class)); } } else { - Log.e(LOG_TAG, "Error! Emergency Callback Mode not supported for " + - phone.getPhoneName() + " phones"); + // It doesn't make sense to get ACTION_EMERGENCY_CALLBACK_MODE_CHANGED + // on a device that doesn't support ECM in the first place. + Log.e(LOG_TAG, "Got ACTION_EMERGENCY_CALLBACK_MODE_CHANGED, " + + "but ECM isn't supported for phone: " + phone.getPhoneName()); } } else if (action.equals(Intent.ACTION_DOCK_EVENT)) { mDockState = intent.getIntExtra(Intent.EXTRA_DOCK_STATE, @@ -1544,21 +1555,9 @@ public class PhoneApp extends Application implements AccelerometerListener.Orien // If service just returned, start sending out the queued messages ServiceState ss = ServiceState.newFromBundle(intent.getExtras()); - boolean hasService = true; - boolean isCdma = false; - String eriText = ""; - if (ss != null) { int state = ss.getState(); NotificationMgr.getDefault().updateNetworkSelection(state); - switch (state) { - case ServiceState.STATE_OUT_OF_SERVICE: - case ServiceState.STATE_POWER_OFF: - hasService = false; - break; - } - } else { - hasService = false; } } diff --git a/phone/src/com/android/phone2/PhoneInterfaceManager.java b/phone/src/com/android/phone2/PhoneInterfaceManager.java index e42f95b..f46ae52 100644 --- a/phone/src/com/android/phone2/PhoneInterfaceManager.java +++ b/phone/src/com/android/phone2/PhoneInterfaceManager.java @@ -135,18 +135,7 @@ public class PhoneInterfaceManager extends ITelephony.Stub { case CMD_END_CALL: request = (MainThreadRequest) msg.obj; - boolean hungUp = false; - int phoneType = mPhone.getPhoneType(); - if (phoneType == Phone.PHONE_TYPE_CDMA) { - // CDMA: If the user presses the Power button we treat it as - // ending the complete call session - hungUp = PhoneUtils.hangupRingingAndActive(mPhone); - } else if (phoneType == Phone.PHONE_TYPE_GSM) { - // GSM: End the call as per the Phone state - hungUp = PhoneUtils.hangup(mPhone); - } else { - throw new IllegalStateException("Unexpected phone type: " + phoneType); - } + boolean hungUp = PhoneUtils.hangup(mPhone); if (DBG) log("CMD_END_CALL: " + (hungUp ? "hung up!" : "no call to hang up")); request.result = hungUp; // Wake up the requesting thread @@ -209,7 +198,7 @@ public class PhoneInterfaceManager extends ITelephony.Stub { private void publish() { if (DBG) log("publish: " + this); - //ServiceManager.addService("phone", this); + ServiceManager.addService("phone", this); } // @@ -665,20 +654,8 @@ public class PhoneInterfaceManager extends ITelephony.Stub { /** * Returns true if CDMA provisioning needs to run. */ - public boolean getCdmaNeedsProvisioning() { - if (getActivePhoneType() == Phone.PHONE_TYPE_GSM) { - return false; - } - - boolean needsProvisioning = false; - String cdmaMin = mPhone.getCdmaMin(); - try { - needsProvisioning = OtaUtils.needsActivation(cdmaMin); - } catch (IllegalArgumentException e) { - // shouldn't get here unless hardware is misconfigured - Log.e(LOG_TAG, "CDMA MIN string " + ((cdmaMin == null) ? "was null" : "was too short")); - } - return needsProvisioning; + public boolean needsOtaServiceProvisioning() { + return mPhone.needsOtaServiceProvisioning(); } /** @@ -715,6 +692,8 @@ public class PhoneInterfaceManager extends ITelephony.Stub { return TelephonyManager.NETWORK_TYPE_EVDO_0; case ServiceState.RADIO_TECHNOLOGY_EVDO_A: return TelephonyManager.NETWORK_TYPE_EVDO_A; + case ServiceState.RADIO_TECHNOLOGY_EVDO_B: + return TelephonyManager.NETWORK_TYPE_EVDO_B; default: return TelephonyManager.NETWORK_TYPE_UNKNOWN; } diff --git a/phone/src/com/android/phone2/PhoneUtils.java b/phone/src/com/android/phone2/PhoneUtils.java index d7e9e73..b064226 100755 --- a/phone/src/com/android/phone2/PhoneUtils.java +++ b/phone/src/com/android/phone2/PhoneUtils.java @@ -276,11 +276,10 @@ public class PhoneUtils { //if (DBG) log("sPhone.acceptCall"); phone.acceptCall(); answered = true; - if (phoneIsCdma) { - // automatically reset mute state to unmuted for CDMA - // TODO: Would GSM want this also? - setMute(phone, false); - } + + // Always reset to "unmuted" for a freshly-answered call + setMute(phone, false); + setAudioMode(phone.getContext(), AudioManager.MODE_IN_CALL); // Check is phone in any dock, and turn on speaker accordingly @@ -336,37 +335,43 @@ public class PhoneUtils { } static boolean hangupRingingCall(Phone phone) { - if (DBG) log("hangup ringing call"); + if (DBG) log("hangupRingingCall()..."); Call ringing = phone.getRingingCall(); - int phoneType = phone.getPhoneType(); + Call.State state = ringing.getState(); - if (phoneType == Phone.PHONE_TYPE_CDMA) { - // CDMA: Ringing call and Call waiting hangup is handled differently. - // For Call waiting we DO NOT call the conventional hangup(call) function - // as in CDMA we just want to hungup the Call waiting connection. - Call.State state = ringing.getState(); - if (state == Call.State.INCOMING) { - if (DBG) log("hangup ringing call"); - return hangup(ringing); - } else if (state == Call.State.WAITING) { - if (DBG) log("hangup Call waiting call"); + if (state == Call.State.INCOMING) { + // Regular incoming call (with no other active calls) + if (DBG) log("- regular incoming call: hangup()"); + return hangup(ringing); + } else if (state == Call.State.WAITING) { + // Call-waiting: there's an incoming call, but another call is + // already active. + // TODO: It would be better for the telephony layer to provide + // a "hangupWaitingCall()" API that works on all devices, + // rather than us having to check the phone type here and do + // the notifier.sendCdmaCallWaitingReject() hack for CDMA phones. + if (phone.getPhoneType() == Phone.PHONE_TYPE_CDMA) { + // CDMA: Ringing call and Call waiting hangup is handled differently. + // For Call waiting we DO NOT call the conventional hangup(call) function + // as in CDMA we just want to hangup the Call waiting connection. + if (DBG) log("- CDMA-specific call-waiting hangup"); final CallNotifier notifier = PhoneApp.getInstance().notifier; notifier.sendCdmaCallWaitingReject(); return true; } else { - // This should never happen cause hangupRingingCall should always be called - // if the call.isRinging() returns TRUE, which basically means that the call - // should either be in INCOMING or WAITING state - if (DBG) log("No Ringing call to hangup"); - return false; + // Otherwise, the regular hangup() API works for + // call-waiting calls too. + if (DBG) log("- call-waiting call: hangup()"); + return hangup(ringing); } - } else if (phoneType == Phone.PHONE_TYPE_GSM) { - // GSM: Ringing Call and Call waiting, both are hungup by calling - // hangup(call) function. - if (DBG) log("hangup ringing call"); - return hangup(ringing); } else { - throw new IllegalStateException("Unexpected phone type: " + phoneType); + // Unexpected state: the ringing call isn't INCOMING or + // WAITING, so there's no reason to have called + // hangupRingingCall() in the first place. + // (Presumably the incoming call went away at the exact moment + // we got here, so just do nothing.) + Log.w(LOG_TAG, "hangupRingingCall: no INCOMING or WAITING call"); + return false; } } @@ -492,173 +497,149 @@ public class PhoneUtils { /** * Dial the number using the phone passed in. * + * If the connection is establised, this method issues a sync call + * that may block to query the caller info. + * TODO: Change the logic to use the async query. + * + * @param context To perform the CallerInfo query. * @param phone the Phone object. - * @param number to be dialed as requested by the user. - * @param contactRef that triggered the call. Either a 'tel:' or a - * 'content://contacts' uri depending on how the call was - * initiated (dialpad vs contact). - * @return either CALL_STATUS_DIALED, CALL_STATUS_DIALED_MMI, or CALL_STATUS_FAILED + * @param number to be dialed as requested by the user. This is + * NOT the phone number to connect to. It is used only to build the + * call card and to update the call log. See above for restrictions. + * @param contactRef that triggered the call. Typically a 'tel:' + * uri but can also be a 'content://contacts' one. + * @param isEmergencyCall indicates that whether or not this is an + * emergency call + * @param gatewayUri Is the address used to setup the connection, null + * if not using a gateway + * + * @return either CALL_STATUS_DIALED or CALL_STATUS_FAILED */ - static int placeCall(Phone phone, String number, Uri contactRef) { + public static int placeCall(Context context, Phone phone, + String number, Uri contactRef, boolean isEmergencyCall, + Uri gatewayUri) { + if (DBG) log("placeCall '" + number + "' GW:'" + gatewayUri + "'"); + boolean useGateway = false; + if (null != gatewayUri && + !isEmergencyCall && + PhoneUtils.isRoutableViaGateway(number)) { // Filter out MMI, OTA and other codes. + useGateway = true; + } + int status = CALL_STATUS_DIALED; - try { - if (DBG) log("placeCall: '" + number + "'..."); + Connection connection; + String numberToDial; + if (useGateway) { + // TODO: 'tel' should be a constant defined in framework base + // somewhere (it is in webkit.) + if (null == gatewayUri || !"tel".equals(gatewayUri.getScheme())) { + Log.e(LOG_TAG, "Unsupported URL:" + gatewayUri); + return CALL_STATUS_FAILED; + } - Connection cn = phone.dial(number); - if (DBG) log("===> phone.dial() returned: " + cn); + // We can use getSchemeSpecificPart because we don't allow # + // in the gateway numbers (treated a fragment delim.) However + // if we allow more complex gateway numbers sequence (with + // passwords or whatnot) that use #, this may break. + // TODO: Need to support MMI codes. + numberToDial = gatewayUri.getSchemeSpecificPart(); + } else { + numberToDial = number; + } - int phoneType = phone.getPhoneType(); + try { + connection = phone.dial(numberToDial); + } catch (CallStateException ex) { + Log.e(LOG_TAG, "Exception dialing ", ex); + connection = null; + } - // On GSM phones, null is returned for MMI codes - if (cn == null) { - if (phoneType == Phone.PHONE_TYPE_GSM) { - if (DBG) log("dialed MMI code: " + number); - status = CALL_STATUS_DIALED_MMI; - // Set dialed MMI command to service - if (mNwService != null) { - try { - mNwService.setMmiString(number); - if (DBG) log("Extended NW bindService setUssdString (" + number + ")"); - } catch (RemoteException e) { - mNwService = null; - } + int phoneType = phone.getPhoneType(); + + // On GSM phones, null is returned for MMI codes + if (null == connection) { + if (phoneType == Phone.PHONE_TYPE_GSM && gatewayUri == null) { + if (DBG) log("dialed MMI code: " + number); + status = CALL_STATUS_DIALED_MMI; + // Set dialed MMI command to service + if (mNwService != null) { + try { + mNwService.setMmiString(number); + if (DBG) log("Extended NW bindService setUssdString (" + number + ")"); + } catch (RemoteException e) { + mNwService = null; } - } else { - status = PhoneUtils.CALL_STATUS_FAILED; } } else { - PhoneApp app = PhoneApp.getInstance(); + status = CALL_STATUS_FAILED; + } + } else { + PhoneApp app = PhoneApp.getInstance(); + if (phoneType == Phone.PHONE_TYPE_CDMA) { + updateCdmaCallStateOnNewOutgoingCall(app); + } - if (phoneType == Phone.PHONE_TYPE_CDMA) { - updateCdmaCallStateOnNewOutgoingCall(app); - } + PhoneUtils.setAudioControlState(PhoneUtils.AUDIO_OFFHOOK); - PhoneUtils.setAudioControlState(PhoneUtils.AUDIO_OFFHOOK); + // Clean up the number to be displayed. + if (phoneType == Phone.PHONE_TYPE_CDMA) { + number = CdmaConnection.formatDialString(number); + } + number = PhoneNumberUtils.extractNetworkPortion(number); + number = PhoneNumberUtils.convertKeypadLettersToDigits(number); + number = PhoneNumberUtils.formatNumber(number); + if (gatewayUri == null) { // phone.dial() succeeded: we're now in a normal phone call. // attach the URI to the CallerInfo Object if it is there, // otherwise just attach the Uri Reference. // if the uri does not have a "content" scheme, then we treat // it as if it does NOT have a unique reference. - String content = phone.getContext().getContentResolver().SCHEME_CONTENT; + String content = context.getContentResolver().SCHEME_CONTENT; if ((contactRef != null) && (contactRef.getScheme().equals(content))) { - Object userDataObject = cn.getUserData(); + Object userDataObject = connection.getUserData(); if (userDataObject == null) { - cn.setUserData(contactRef); + connection.setUserData(contactRef); } else { // TODO: This branch is dead code, we have - // just created the connection 'cn' which has + // just created the connection which has // no user data (null) by default. if (userDataObject instanceof CallerInfo) { - ((CallerInfo) userDataObject).contactRefUri = contactRef; + ((CallerInfo) userDataObject).contactRefUri = contactRef; } else { - ((CallerInfoToken) userDataObject).currentInfo.contactRefUri = - contactRef; + ((CallerInfoToken) userDataObject).currentInfo.contactRefUri = + contactRef; } } } - setAudioMode(phone.getContext(), AudioManager.MODE_IN_CALL); + } else { + // Get the caller info synchronously because we need the final + // CallerInfo object to update the dialed number with the one + // requested by the user (and not the provider's gateway number). + CallerInfo info = null; + String content = phone.getContext().getContentResolver().SCHEME_CONTENT; + if ((contactRef != null) && (contactRef.getScheme().equals(content))) { + info = CallerInfo.getCallerInfo(context, contactRef); + } - // Check is phone in any dock, and turn on speaker accordingly - activateSpeakerIfDocked(phone); + // Fallback, lookup contact using the phone number if the + // contact's URI scheme was not content:// or if is was but + // the lookup failed. + if (null == info) { + info = CallerInfo.getCallerInfo(context, number); + } + info.phoneNumber = number; + connection.setUserData(info); } - } catch (CallStateException ex) { - Log.w(LOG_TAG, "Exception from phone.dial()", ex); - status = CALL_STATUS_FAILED; - } - - return status; - } - - /** - * Dial the number using a 3rd party provider gateway. Should - * *NOT* be called if the number is either: - * . An emergency one - * . A GSM MMI code - * . A CDMA feature code - * None of the above is checked in this method, it's the caller's - * responsability to make sure the number is 'valid'. - * - * If the connection is establised, this method issues a sync call - * that may block to query the caller info. - * TODO: Change the logic to use the async query. - * - * @param phone the Phone object. - * @param context To perform the CallerInfo query. - * @param number to be dialed as requested by the user. This is - * NOT the phone number to connect to. It is used only to build the - * call card and to update the call log. See above for restrictions. - * @param contactRef that triggered the call. Typically a 'tel:' - * uri but can also be a 'content://contacts' one. - * @param gatewayUri Is the address used to setup the connection. - * @return either CALL_STATUS_DIALED or CALL_STATUS_FAILED - */ - static int placeCallVia(Context context, Phone phone, - String number, Uri contactRef, Uri gatewayUri) { - if (DBG) log("placeCallVia: '" + number + "' GW:'" + gatewayUri + "'"); - - // TODO: 'tel' should be a contant defined in framework base - // somewhere (it is in webkit.) - if (null == gatewayUri || !"tel".equals(gatewayUri.getScheme())) { - Log.e(LOG_TAG, "Unsupported URL:" + gatewayUri); - return CALL_STATUS_FAILED; - } - - // We can use getSchemeSpecificPart because we don't allow # - // in the gateway numbers (treated a fragment delim.) However - // if we allow more complex gateway numbers sequence (with - // passwords or whatnot) that use #, this may break. - // TODO: Need to support MMI codes. - String gatewayNumber = gatewayUri.getSchemeSpecificPart(); - Connection connection; - try { - connection = phone.dial(gatewayNumber); - } catch (CallStateException ex) { - Log.e(LOG_TAG, "Exception dialing gateway", ex); - connection = null; - } - if (null == connection) { - Log.e(LOG_TAG, "Got null connection."); - return CALL_STATUS_FAILED; - } + setAudioMode(phone.getContext(), AudioManager.MODE_IN_CALL); - PhoneApp app = PhoneApp.getInstance(); - boolean phoneIsCdma = (phone.getPhoneType() == Phone.PHONE_TYPE_CDMA); - - if (phoneIsCdma) { - updateCdmaCallStateOnNewOutgoingCall(app); + if (DBG) log("about to activate speaker"); + // Check is phone in any dock, and turn on speaker accordingly + activateSpeakerIfDocked(phone); } - PhoneUtils.setAudioControlState(PhoneUtils.AUDIO_OFFHOOK); - - // Clean up the number to be displayed. - if (phoneIsCdma) { - number = CdmaConnection.formatDialString(number); - } - number = PhoneNumberUtils.extractNetworkPortion(number); - number = PhoneNumberUtils.convertKeypadLettersToDigits(number); - number = PhoneNumberUtils.formatNumber(number); - - // Get the caller info synchronously because we need the final - // CallerInfo object to update the dialed number with the one - // requested by the user (and not the provider's gateway number). - CallerInfo info = null; - if (ContentResolver.SCHEME_CONTENT.equals(contactRef.getScheme())) { - info = CallerInfo.getCallerInfo(context, contactRef); - } - - // Fallback, lookup contact using the phone number if the - // contact's URI scheme was not content:// or if is was but - // the lookup failed. - if (null == info) { - info = CallerInfo.getCallerInfo(context, number); - } - info.phoneNumber = number; - connection.setUserData(info); - - setAudioMode(phone.getContext(), AudioManager.MODE_IN_CALL); - return CALL_STATUS_DIALED; + return status; } /** @@ -1025,10 +1006,10 @@ public class PhoneUtils { new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { switch (whichButton) { - case DialogInterface.BUTTON1: + case DialogInterface.BUTTON_POSITIVE: phone.sendUssdResponse(inputText.getText().toString()); break; - case DialogInterface.BUTTON2: + case DialogInterface.BUTTON_NEGATIVE: if (mmiCode.isCancelable()) { mmiCode.cancel(); } @@ -2297,19 +2278,21 @@ public class PhoneUtils { /** * Returns whether the phone is in ECM ("Emergency Callback Mode") or not. - * (For non-CDMA phones, this will always return false. - * For CDMA Phones, return true iff PROPERTY_INECM_MODE == "true".) */ /* package */ static boolean isPhoneInEcm(Phone phone) { - boolean phoneInEcm = false; - if ((phone != null) && (phone.getPhoneType() == Phone.PHONE_TYPE_CDMA)) { + if ((phone != null) && TelephonyCapabilities.supportsEcm(phone)) { + // For phones that support ECM, return true iff PROPERTY_INECM_MODE == "true". + // TODO: There ought to be a better API for this than just + // exposing a system property all the way up to the app layer, + // probably a method like "inEcm()" provided by the telephony + // layer. String ecmMode = SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE); if (ecmMode != null) { - phoneInEcm = ecmMode.equals("true"); + return ecmMode.equals("true"); } } - return phoneInEcm; + return false; } diff --git a/phone/src/com/android/phone2/Settings.java b/phone/src/com/android/phone2/Settings.java index bf2b956..50e4d0a 100644 --- a/phone/src/com/android/phone2/Settings.java +++ b/phone/src/com/android/phone2/Settings.java @@ -35,7 +35,6 @@ import android.preference.PreferenceScreen; import android.util.Log; import com.android.internal.telephony.Phone; -import com.android.internal.telephony.PhoneFactory; import com.android.internal.telephony.TelephonyIntents; import com.android.internal.telephony.TelephonyProperties; @@ -48,17 +47,13 @@ public class Settings extends PreferenceActivity implements DialogInterface.OnCl // debug data private static final String LOG_TAG = "NetworkSettings"; private static final boolean DBG = true; - public static final int REQUEST_CODE_EXIT_ECM = 17; + public static final int REQUEST_CODE_EXIT_ECM = 17; //String keys for preference lookup private static final String BUTTON_DATA_ENABLED_KEY = "button_data_enabled_key"; private static final String BUTTON_DATA_USAGE_KEY = "button_data_usage_key"; private static final String BUTTON_PREFERED_NETWORK_MODE = "preferred_network_mode_key"; private static final String BUTTON_ROAMING_KEY = "button_roaming_key"; - private static final String BUTTON_CDMA_ROAMING_KEY = "cdma_roaming_mode_key"; - - private static final String BUTTON_GSM_UMTS_OPTIONS = "gsm_umts_options_key"; - private static final String BUTTON_CDMA_OPTIONS = "cdma_options_key"; static final int preferredNetworkMode = Phone.PREFERRED_NT_MODE; @@ -66,7 +61,6 @@ public class Settings extends PreferenceActivity implements DialogInterface.OnCl private ListPreference mButtonPreferredNetworkMode; private CheckBoxPreference mButtonDataRoam; private CheckBoxPreference mButtonDataEnabled; - private CdmaRoamingListPreference mButtonCdmaRoam; private Preference mButtonDataUsage; private DataUsageListener mDataUsageListener; @@ -77,14 +71,16 @@ public class Settings extends PreferenceActivity implements DialogInterface.OnCl private boolean mOkClicked; //GsmUmts options and Cdma options - GsmUmtsOptions gsmumtsOptions; - CdmaOptions cdmaOptions; + GsmUmtsOptions mGsmUmtsOptions; + CdmaOptions mCdmaOptions; + + private Preference mClickedPreference; //This is a method implemented for DialogInterface.OnClickListener. // Used to dismiss the dialogs when they come up. public void onClick(DialogInterface dialog, int which) { - if (which == DialogInterface.BUTTON1) { + if (which == DialogInterface.BUTTON_POSITIVE) { mPhone.setDataRoamingEnabled(true); mOkClicked = true; } else { @@ -107,13 +103,17 @@ public class Settings extends PreferenceActivity implements DialogInterface.OnCl */ @Override public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) { - if (gsmumtsOptions != null && - gsmumtsOptions.onPreferenceTreeClick(preferenceScreen, preference) == true) { + /** TODO: Refactor and get rid of the if's using subclasses */ + if (mGsmUmtsOptions != null && + mGsmUmtsOptions.preferenceTreeClick(preference) == true) { return true; - } else if (cdmaOptions != null && - cdmaOptions.onPreferenceTreeClick(preferenceScreen, preference) == true) { + } else if (mCdmaOptions != null && + mCdmaOptions.preferenceTreeClick(preference) == true) { if (Boolean.parseBoolean( SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE))) { + + mClickedPreference = preference; + // In ECM mode launch ECM app dialog startActivityForResult( new Intent(TelephonyIntents.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS, null), @@ -127,8 +127,7 @@ public class Settings extends PreferenceActivity implements DialogInterface.OnCl preferredNetworkMode); mButtonPreferredNetworkMode.setValue(Integer.toString(settingsNetworkMode)); return true; - } - else if (preference == mButtonDataRoam) { + } else if (preference == mButtonDataRoam) { if (DBG) log("onPreferenceTreeClick: preference == mButtonDataRoam."); //normally called on the toggle click @@ -143,8 +142,7 @@ public class Settings extends PreferenceActivity implements DialogInterface.OnCl .setNegativeButton(android.R.string.no, this) .show() .setOnDismissListener(this); - } - else { + } else { mPhone.setDataRoamingEnabled(false); } return true; @@ -171,7 +169,7 @@ public class Settings extends PreferenceActivity implements DialogInterface.OnCl addPreferencesFromResource(R.xml.network_setting); - mPhone = PhoneFactory.getDefaultPhone(); + mPhone = PhoneApp.getPhone(); mHandler = new MyHandler(); //get UI object references @@ -193,22 +191,15 @@ public class Settings extends PreferenceActivity implements DialogInterface.OnCl getContentResolver(),android.provider.Settings.Secure.PREFERRED_NETWORK_MODE, preferredNetworkMode); mButtonPreferredNetworkMode.setValue(Integer.toString(settingsNetworkMode)); - // The intent code that resided here in the past has been moved into the - // more conventional location in network_setting.xml - + mCdmaOptions = new CdmaOptions(this, prefSet); + mGsmUmtsOptions = new GsmUmtsOptions(this, prefSet); } else { prefSet.removePreference(mButtonPreferredNetworkMode); - prefSet.removePreference(prefSet.findPreference(BUTTON_GSM_UMTS_OPTIONS)); - prefSet.removePreference(prefSet.findPreference(BUTTON_CDMA_OPTIONS)); int phoneType = mPhone.getPhoneType(); if (phoneType == Phone.PHONE_TYPE_CDMA) { - addPreferencesFromResource(R.xml.cdma_options); - mButtonCdmaRoam = - (CdmaRoamingListPreference) prefSet.findPreference(BUTTON_CDMA_ROAMING_KEY); - cdmaOptions = new CdmaOptions(); + mCdmaOptions = new CdmaOptions(this, prefSet); } else if (phoneType == Phone.PHONE_TYPE_GSM) { - addPreferencesFromResource(R.xml.gsm_umts_options); - gsmumtsOptions = new GsmUmtsOptions(); + mGsmUmtsOptions = new GsmUmtsOptions(this, prefSet); } else { throw new IllegalStateException("Unexpected phone type: " + phoneType); } @@ -457,8 +448,8 @@ public class Settings extends PreferenceActivity implements DialogInterface.OnCl Boolean isChoiceYes = data.getBooleanExtra(EmergencyCallbackModeExitDialog.EXTRA_EXIT_ECM_RESULT, false); if (isChoiceYes) { - // If the phone exits from ECM mode, show the system selection Options - mButtonCdmaRoam.showDialog(null); + // If the phone exits from ECM mode, show the CDMA Options + mCdmaOptions.showDialog(mClickedPreference); } else { // do nothing } diff --git a/phone/src/com/android/phone2/SimContacts.java b/phone/src/com/android/phone2/SimContacts.java index fa15fa3..7f9cb5e 100644 --- a/phone/src/com/android/phone2/SimContacts.java +++ b/phone/src/com/android/phone2/SimContacts.java @@ -130,11 +130,6 @@ public class SimContacts extends ADNList { } } - // From HardCodedSources.java in Contacts app. - // TODO: fix this. - private static final String ACCOUNT_TYPE_GOOGLE = "com.google"; - private static final String GOOGLE_MY_CONTACTS_GROUP = "System Group: My Contacts"; - private static void actuallyImportOneSimContact( final Cursor cursor, final ContentResolver resolver, Account account) { final NamePhoneTypePair namePhoneTypePair = @@ -158,23 +153,6 @@ public class SimContacts extends ADNList { if (account != null) { builder.withValue(RawContacts.ACCOUNT_NAME, account.name); builder.withValue(RawContacts.ACCOUNT_TYPE, account.type); - - // TODO: temporal fix for "My Groups" issue. Need to be refactored. - if (ACCOUNT_TYPE_GOOGLE.equals(account.type)) { - final Cursor tmpCursor = resolver.query(Groups.CONTENT_URI, new String[] { - Groups.SOURCE_ID }, - Groups.TITLE + "=?", new String[] { - GOOGLE_MY_CONTACTS_GROUP }, null); - try { - if (tmpCursor != null && tmpCursor.moveToFirst()) { - myGroupsId = tmpCursor.getString(0); - } - } finally { - if (tmpCursor != null) { - tmpCursor.close(); - } - } - } } else { builder.withValues(sEmptyContentValues); } @@ -291,6 +269,11 @@ public class SimContacts extends ADNList { ImportAllSimContactsThread thread = new ImportAllSimContactsThread(); + // TODO: need to show some error dialog. + if (mCursor == null) { + Log.e(LOG_TAG, "cursor is null. Ignore silently."); + break; + } mProgressDialog = new ProgressDialog(this); mProgressDialog.setTitle(title); mProgressDialog.setMessage(message); @@ -298,9 +281,7 @@ public class SimContacts extends ADNList { mProgressDialog.setButton(DialogInterface.BUTTON_NEGATIVE, getString(R.string.cancel), thread); mProgressDialog.setProgress(0); - if (mCursor != null) { - mProgressDialog.setMax(mCursor.getCount()); - } + mProgressDialog.setMax(mCursor.getCount()); mProgressDialog.show(); thread.start(); diff --git a/phone/src/com/android/phone2/SpecialCharSequenceMgr.java b/phone/src/com/android/phone2/SpecialCharSequenceMgr.java index 3a80bc1..db31bbb 100644 --- a/phone/src/com/android/phone2/SpecialCharSequenceMgr.java +++ b/phone/src/com/android/phone2/SpecialCharSequenceMgr.java @@ -22,7 +22,6 @@ import android.content.Context; import android.content.Intent; import android.net.Uri; import android.provider.Telephony.Intents; -import com.android.internal.telephony.PhoneFactory; import com.android.internal.telephony.Phone; import android.telephony.PhoneNumberUtils; import android.util.Log; @@ -161,7 +160,7 @@ public class SpecialCharSequenceMgr { int index = Integer.parseInt(input.substring(0, len-1)); Intent intent = new Intent(Intent.ACTION_PICK); - intent.setClassName("com.android.phone", + intent.setClassName("com.android.phone2", "com.android.phone2.SimContacts"); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.putExtra("index", index); @@ -199,43 +198,23 @@ public class SpecialCharSequenceMgr { static private boolean handleIMEIDisplay(Context context, String input) { if (input.equals(MMI_IMEI_DISPLAY)) { - int phoneType = PhoneApp.getInstance().phone.getPhoneType(); - if (phoneType == Phone.PHONE_TYPE_CDMA) { - showMEIDPanel(context); - return true; - } else if (phoneType == Phone.PHONE_TYPE_GSM) { - showIMEIPanel(context); - return true; - } + showDeviceIdPanel(context); + return true; } return false; } - // TODO: showIMEIPanel and showMEIDPanel are almost cut and paste - // clones. Refactor. - static private void showIMEIPanel(Context context) { - if (DBG) log("showIMEIPanel"); - - String imeiStr = PhoneFactory.getDefaultPhone().getDeviceId(); - - AlertDialog alert = new AlertDialog.Builder(context) - .setTitle(R.string.imei) - .setMessage(imeiStr) - .setPositiveButton(R.string.ok, null) - .setCancelable(false) - .show(); - alert.getWindow().setType(WindowManager.LayoutParams.TYPE_PRIORITY_PHONE); - } - - static private void showMEIDPanel(Context context) { - if (DBG) log("showMEIDPanel"); + static private void showDeviceIdPanel(Context context) { + if (DBG) log("showDeviceIdPanel()..."); - String meidStr = PhoneFactory.getDefaultPhone().getDeviceId(); + Phone phone = PhoneApp.getPhone(); + int labelId = TelephonyCapabilities.getDeviceIdLabel(phone); + String deviceId = phone.getDeviceId(); AlertDialog alert = new AlertDialog.Builder(context) - .setTitle(R.string.meid) - .setMessage(meidStr) + .setTitle(labelId) + .setMessage(deviceId) .setPositiveButton(R.string.ok, null) .setCancelable(false) .show(); diff --git a/phone/src/com/android/phone2/TelephonyCapabilities.java b/phone/src/com/android/phone2/TelephonyCapabilities.java new file mode 100644 index 0000000..527b813 --- /dev/null +++ b/phone/src/com/android/phone2/TelephonyCapabilities.java @@ -0,0 +1,208 @@ +/* + * Copyright (C) 2010 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. + */ + +package com.android.phone2; + +import android.content.Context; +import android.provider.Settings; +import android.util.Log; + +import com.android.internal.telephony.Phone; + +/** + * TODO: This is intended as a temporary repository for behavior policy + * functions that depend upon the type of phone or the carrier. Ultimately + * these sorts of questions should be answered by the telephony layer. + */ +public class TelephonyCapabilities { + private static final String LOG_TAG = "TelephonyCapabilities"; + + /** This class is never instantiated. */ + private TelephonyCapabilities() { + } + + /** + * On GSM devices, we never use short tones. + * On CDMA devices, it depends upon the settings. + * TODO: I don't think this has anything to do with GSM versus CDMA, + * should we be looking only at the setting? + */ + /* package */ static boolean useShortDtmfTones(Phone phone, Context context) { + int phoneType = phone.getPhoneType(); + if (phoneType == Phone.PHONE_TYPE_GSM) { + return false; + } else if (phoneType == Phone.PHONE_TYPE_CDMA) { + int toneType = android.provider.Settings.System.getInt( + context.getContentResolver(), + Settings.System.DTMF_TONE_TYPE_WHEN_DIALING, + CallFeaturesSetting.DTMF_TONE_TYPE_NORMAL); + if (toneType == CallFeaturesSetting.DTMF_TONE_TYPE_NORMAL) { + return true; + } else { + return false; + } + } else { + throw new IllegalStateException("Unexpected phone type: " + phoneType); + } + } + + /** + * Return true if the current phone supports ECM ("Emergency Callback + * Mode"), which is a feature where the device goes into a special + * state for a short period of time after making an outgoing emergency + * call. + * + * (On current devices, that state lasts 5 minutes. It prevents data + * usage by other apps, to avoid conflicts with any possible incoming + * calls. It also puts up a notification in the status bar, showing a + * countdown while ECM is active, and allowing the user to exit ECM.) + * + * Currently this is assumed to be true for CDMA phones, and false + * otherwise. + * + * TODO: This capability should really be exposed by the telephony + * layer, since it depends on the underlying telephony technology. + * (Or, is this actually carrier-specific? Is it VZW-only?) + */ + /* package */ static boolean supportsEcm(Phone phone) { + return (phone.getPhoneType() == Phone.PHONE_TYPE_CDMA); + } + + /** + * Return true if the current phone supports Over The Air Service + * Provisioning (OTASP) + * + * Currently this is assumed to be true for CDMA phones, and false + * otherwise. + * + * TODO: This capability should really be exposed by the telephony + * layer, since it depends on the underlying telephony technology. + * + * TODO: Watch out: this is also highly carrier-specific, since the + * OTA procedure is different from one carrier to the next, *and* the + * different carriers may want very different onscreen UI as well. + * The procedure may even be different for different devices with the + * same carrier. + * + * So we eventually will need a much more flexible, pluggable design. + * This method here is just a placeholder to reduce hardcoded + * "if (CDMA)" checks sprinkled throughout the rest of the phone app. + * + * TODO: consider using the term "OTASP" rather "OTA" everywhere in the + * phone app, since OTA can also mean over-the-air software updates. + */ + /* package */ static boolean supportsOtasp(Phone phone) { + return (phone.getPhoneType() == Phone.PHONE_TYPE_CDMA); + } + + /** + * Return true if the current phone can retrieve the voice message count. + * + * Currently this is assumed to be true on CDMA phones and false otherwise. + * + * TODO: This capability should really be exposed by the telephony + * layer, since it depends on the underlying telephony technology. + */ + /* package */ static boolean supportsVoiceMessageCount(Phone phone) { + return (phone.getPhoneType() == Phone.PHONE_TYPE_CDMA); + } + + /** + * Return true if this phone allows the user to select which + * network to use. + * + * Currently this is assumed to be true only on GSM phones. + * + * TODO: Should CDMA phones allow this as well? + */ + /* package */ static boolean supportsNetworkSelection(Phone phone) { + return (phone.getPhoneType() == Phone.PHONE_TYPE_GSM); + } + + /** + * Returns a resource ID for a label to use when displaying the + * "device id" of the current device. (This is currently used as the + * title of the "device id" dialog.) + * + * This is specific to the device's telephony technology: the device + * id is called "IMEI" on GSM phones and "MEID" on CDMA phones. + * TODO: ultimately this name should come directly from the + * telephony layer. + */ + /* package */ static int getDeviceIdLabel(Phone phone) { + if (phone.getPhoneType() == Phone.PHONE_TYPE_GSM) { + return R.string.imei; + } else if (phone.getPhoneType() == Phone.PHONE_TYPE_CDMA) { + return R.string.meid; + } else { + Log.w(LOG_TAG, "getDeviceIdLabel: no known label for phone " + + phone.getPhoneName()); + return 0; + } + } + + /** + * Return true if the current phone supports the ability to explicitly + * manage the state of a conference call (i.e. view the participants, + * and hangup or separate individual callers.) + * + * The in-call screen's "Manage conference" UI is available only on + * devices that support this feature. + * + * Currently this is assumed to be true on GSM phones and false otherwise. + * TODO: This capability should really be exposed by the telephony + * layer, since it depends on the underlying telephony technology. + */ + /* package */ static boolean supportsConferenceCallManagement(Phone phone) { + return (phone.getPhoneType() == Phone.PHONE_TYPE_GSM); + } + + /** + * Return true if the current phone supports explicit "Hold" and + * "Unhold" actions for an active call. (If so, the in-call UI will + * provide onscreen "Hold" / "Unhold" buttons.) + * + * Currently this is assumed to be true on GSM phones and false + * otherwise. (In particular, CDMA has no concept of "putting a call + * on hold.") + * TODO: This capability should really be exposed by the telephony + * layer, since it depends on the underlying telephony technology. + */ + /* package */ static boolean supportsHoldAndUnhold(Phone phone) { + return (phone.getPhoneType() == Phone.PHONE_TYPE_GSM); + } + + /** + * Return true if the current phone supports distinct "Answer & Hold" + * and "Answer & End" behaviors in the call-waiting scenario. If so, + * the in-call UI may provide separate buttons or menu items for these + * two actions. + * + * Currently this is assumed to be true on GSM phones and false + * otherwise. (In particular, CDMA has no concept of explicitly + * managing the background call, or "putting a call on hold.") + * + * TODO: This capability should really be exposed by the telephony + * layer, since it depends on the underlying telephony technology. + * + * TODO: It might be better to expose this capability in a more + * generic form, like maybe "supportsExplicitMultipleLineManagement()" + * rather than focusing specifically on call-waiting behavior. + */ + /* package */ static boolean supportsAnswerAndHold(Phone phone) { + return (phone.getPhoneType() == Phone.PHONE_TYPE_GSM); + } +} diff --git a/phone/src/com/android/phone2/TimeConsumingPreferenceActivity.java b/phone/src/com/android/phone2/TimeConsumingPreferenceActivity.java index 2918f07..c1abb13 100644 --- a/phone/src/com/android/phone2/TimeConsumingPreferenceActivity.java +++ b/phone/src/com/android/phone2/TimeConsumingPreferenceActivity.java @@ -1,5 +1,7 @@ package com.android.phone2; +import com.android.internal.telephony.CommandException; + import android.app.AlertDialog; import android.app.Dialog; import android.app.ProgressDialog; @@ -15,6 +17,7 @@ interface TimeConsumingPreferenceListener { public void onStarted(Preference preference, boolean reading); public void onFinished(Preference preference, boolean reading); public void onError(Preference preference, int error); + public void onException(Preference preference, CommandException exception); } public class TimeConsumingPreferenceActivity extends PreferenceActivity @@ -29,6 +32,7 @@ public class TimeConsumingPreferenceActivity extends PreferenceActivity static final int EXCEPTION_ERROR = 300; static final int RESPONSE_ERROR = 400; static final int RADIO_OFF_ERROR = 500; + static final int FDN_CHECK_FAILURE = 600; private final ArrayList<String> mBusyList=new ArrayList<String> (); @@ -55,7 +59,8 @@ public class TimeConsumingPreferenceActivity extends PreferenceActivity return null; } - if (id == RESPONSE_ERROR || id == RADIO_OFF_ERROR || id == EXCEPTION_ERROR) { + if (id == RESPONSE_ERROR || id == RADIO_OFF_ERROR || id == EXCEPTION_ERROR + || id == FDN_CHECK_FAILURE) { AlertDialog.Builder b = new AlertDialog.Builder(this); int msgId; @@ -73,6 +78,11 @@ public class TimeConsumingPreferenceActivity extends PreferenceActivity // Set Button 3 b.setNeutralButton(R.string.close_dialog, this); break; + case FDN_CHECK_FAILURE: + msgId = R.string.fdn_only_error; + // Set Button 2 + b.setNegativeButton(R.string.close_dialog, this); + break; case EXCEPTION_ERROR: default: msgId = R.string.exception_error; @@ -151,6 +161,14 @@ public class TimeConsumingPreferenceActivity extends PreferenceActivity } } + public void onException(Preference preference, CommandException exception) { + if (exception.getCommandError() == CommandException.Error.FDN_CHECK_FAILURE) { + onError(preference, FDN_CHECK_FAILURE); + } else { + preference.setEnabled(false); + onError(preference, EXCEPTION_ERROR); + } + } public void onCancel(DialogInterface dialog) { if (DBG) dumpState(); finish(); diff --git a/phone/src/com/android/phone2/Use2GOnlyCheckBoxPreference.java b/phone/src/com/android/phone2/Use2GOnlyCheckBoxPreference.java index 555b949..aae7410 100644 --- a/phone/src/com/android/phone2/Use2GOnlyCheckBoxPreference.java +++ b/phone/src/com/android/phone2/Use2GOnlyCheckBoxPreference.java @@ -25,7 +25,6 @@ import android.util.AttributeSet; import android.util.Log; import com.android.internal.telephony.Phone; -import com.android.internal.telephony.PhoneFactory; public class Use2GOnlyCheckBoxPreference extends CheckBoxPreference { private static final String LOG_TAG = "Use2GOnlyCheckBoxPreference"; @@ -44,7 +43,7 @@ public class Use2GOnlyCheckBoxPreference extends CheckBoxPreference { public Use2GOnlyCheckBoxPreference(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); - mPhone = PhoneFactory.getDefaultPhone(); + mPhone = PhoneApp.getPhone(); mHandler = new MyHandler(); mPhone.getPreferredNetworkType( mHandler.obtainMessage(MyHandler.MESSAGE_GET_PREFERRED_NETWORK_TYPE)); diff --git a/phone/src2/com/android/internal/telephony/sip/SipConnection.java b/phone/src2/com/android/internal/telephony/sip/SipConnection.java index f7abc1f..b66ce2d 100644 --- a/phone/src2/com/android/internal/telephony/sip/SipConnection.java +++ b/phone/src2/com/android/internal/telephony/sip/SipConnection.java @@ -637,6 +637,12 @@ public class SipConnection extends Connection { return Connection.PRESENTATION_ALLOWED; } + @Override + public UUSInfo getUUSInfo() { + // FIXME: what's this for SIP? + return null; + } + private class MyHandler extends Handler { MyHandler(Looper l) { super(l); @@ -651,7 +657,7 @@ public class SipConnection extends Connection { processNextPostDialChar(); break; case EVENT_WAKE_LOCK_TIMEOUT: - releaseWakeLock(); + //releaseWakeLock(); break; } } |