diff options
| author | Nicolas Catania <niko@google.com> | 2009-09-15 18:32:02 -0700 |
|---|---|---|
| committer | Nicolas Catania <niko@google.com> | 2009-09-16 11:11:05 -0700 |
| commit | 60d45f0f0320801a16db2ad038453c098e98966c (patch) | |
| tree | c8f71ada93307d98f6192fd568bd244ac6734ada /telephony | |
| parent | 46ad796186bdca8bac75607340aa0fac0c34a9d8 (diff) | |
| download | frameworks_base-60d45f0f0320801a16db2ad038453c098e98966c.zip frameworks_base-60d45f0f0320801a16db2ad038453c098e98966c.tar.gz frameworks_base-60d45f0f0320801a16db2ad038453c098e98966c.tar.bz2 | |
Added a field to track if the call is to a voicemail instance.
Refactored common code between CallerInfo and CallerInfoAsyncQuery that deal
with voicemail number comparison.
In CallerInfo.java added a new field mIsVoiceMail to indicate this is a
voicemail call.
Added a new method to convert the CallerInfo into a VM instance.
Added a new method to generate a debug string from an instance.
PhoneNumberUtils has a new method "isVoiceMailNumber" to check if a number
is a VM one. I left the method as hidden. Previously any security exception
failure was cached in a static variable. I removed that and
privilege the optmistic scenario. I am not sure if the security exception
is only for the 'regular' telephony layer and if it applies if a 3rd party
VM app is installed (e.g googlevoice), hence i removed the cashing to make
sure we can pick up new voicemail providers when installed/enabled/disabled.
Bug:2112640
Diffstat (limited to 'telephony')
7 files changed, 191 insertions, 65 deletions
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java index 4368464..2672c6d 100644 --- a/telephony/java/android/telephony/PhoneNumberUtils.java +++ b/telephony/java/android/telephony/PhoneNumberUtils.java @@ -129,6 +129,8 @@ public class PhoneNumberUtils return uri.getSchemeSpecificPart(); } + // TODO: We don't check for SecurityException here (requires + // READ_PHONE_STATE permission). if (scheme.equals("voicemail")) { return TelephonyManager.getDefault().getVoiceMailNumber(); } @@ -1179,6 +1181,35 @@ public class PhoneNumberUtils } /** + * isVoiceMailNumber: checks a given number against the voicemail + * number provided by the RIL and SIM card. The caller must have + * the READ_PHONE_STATE credential. + * + * @param number the number to look up. + * @return true if the number is in the list of voicemail. False + * otherwise, including if the caller does not have the permission + * to read the VM number. + * @hide TODO: pending API Council approval + */ + public static boolean isVoiceMailNumber(String number) { + String vmNumber; + + try { + vmNumber = TelephonyManager.getDefault().getVoiceMailNumber(); + } catch (SecurityException ex) { + return false; + } + + // Strip the separators from the number before comparing it + // to the list. + number = extractNetworkPortion(number); + + // compare tolerates null so we need to make sure that we + // don't return true when both are null. + return !TextUtils.isEmpty(number) && compare(number, vmNumber); + } + + /** * Translates any alphabetic letters (i.e. [A-Za-z]) in the * specified phone number into the equivalent numeric digits, * according to the phone keypad letter mapping described in diff --git a/telephony/java/com/android/internal/telephony/CallerInfo.java b/telephony/java/com/android/internal/telephony/CallerInfo.java index c8490e9..01b1746 100644 --- a/telephony/java/com/android/internal/telephony/CallerInfo.java +++ b/telephony/java/com/android/internal/telephony/CallerInfo.java @@ -101,13 +101,12 @@ public class CallerInfo { public boolean isCachedPhotoCurrent; private boolean mIsEmergency; - - // Don't keep checking VM if it's going to throw an exception for this proc. - private static boolean sSkipVmCheck = false; + private boolean mIsVoiceMail; public CallerInfo() { // TODO: Move all the basic initialization here? mIsEmergency = false; + mIsVoiceMail = false; } /** @@ -220,32 +219,15 @@ public class CallerInfo { public static CallerInfo getCallerInfo(Context context, String number) { if (TextUtils.isEmpty(number)) { return null; - } else { - // Change the callerInfo number ONLY if it is an emergency number - // or if it is the voicemail number. If it is either, take a - // shortcut and skip the query. - if (PhoneNumberUtils.isEmergencyNumber(number)) { - return new CallerInfo().markAsEmergency(context); - } else { - try { - if (!sSkipVmCheck && PhoneNumberUtils.compare(number, - TelephonyManager.getDefault().getVoiceMailNumber())) { - CallerInfo ci = new CallerInfo(); - - // Note we're setting the phone number here (refer to javadoc - // comments at the top of CallerInfo class). - ci.phoneNumber = TelephonyManager.getDefault().getVoiceMailAlphaTag(); - // TODO: FIND ANOTHER ICON - //info.photoResource = android.R.drawable.badge_voicemail; - return ci; - } - } catch (SecurityException ex) { - // Don't crash if this process doesn't have permission to - // retrieve VM number. It's still allowed to look up caller info. - // But don't try it again. - sSkipVmCheck = true; - } - } + } + + // Change the callerInfo number ONLY if it is an emergency number + // or if it is the voicemail number. If it is either, take a + // shortcut and skip the query. + if (PhoneNumberUtils.isEmergencyNumber(number)) { + return new CallerInfo().markAsEmergency(context); + } else if (PhoneNumberUtils.isVoiceMailNumber(number)) { + return new CallerInfo().markAsVoiceMail(); } Uri contactUri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number)); @@ -304,6 +286,13 @@ public class CallerInfo { } /** + * @return true if the caller info is a voicemail number. + */ + public boolean isVoiceMailNumber() { + return mIsVoiceMail; + } + + /** * Mark this CallerInfo as an emergency call. * @param context To lookup the localized 'Emergency Number' string. * @return this instance. @@ -323,6 +312,37 @@ public class CallerInfo { return this; } + + /** + * Mark this CallerInfo as a voicemail call. The voicemail label + * is obtained from the telephony manager. Caller must hold the + * READ_PHONE_STATE permission otherwise the phoneNumber will be + * set to null. + * @return this instance. + */ + // TODO: As in the emergency number handling, we end up writing a + // string in the phone number field. + /* package */ CallerInfo markAsVoiceMail() { + mIsVoiceMail = true; + + try { + String voiceMailLabel = TelephonyManager.getDefault().getVoiceMailAlphaTag(); + + phoneNumber = voiceMailLabel; + } catch (SecurityException se) { + // Should never happen: if this process does not have + // permission to retrieve VM tag, it should not have + // permission to retrieve VM number and would not call + // this method. + // Leave phoneNumber untouched. + Log.e(TAG, "Cannot access VoiceMail.", se); + } + // TODO: There is no voicemail picture? + // FIXME: FIND ANOTHER ICON + // photoResource = android.R.drawable.badge_voicemail; + return this; + } + private static String normalize(String s) { if (s == null || s.length() > 0) { return s; @@ -330,4 +350,31 @@ public class CallerInfo { return null; } } + + /** + * @return a string debug representation of this instance. + */ + public String toString() { + return new StringBuilder(384) + .append("\nname: " + name) + .append("\nphoneNumber: " + phoneNumber) + .append("\ncnapName: " + cnapName) + .append("\nnumberPresentation: " + numberPresentation) + .append("\nnamePresentation: " + namePresentation) + .append("\ncontactExits: " + contactExists) + .append("\nphoneLabel: " + phoneLabel) + .append("\nnumberType: " + numberType) + .append("\nnumberLabel: " + numberLabel) + .append("\nphotoResource: " + photoResource) + .append("\nperson_id: " + person_id) + .append("\nneedUpdate: " + needUpdate) + .append("\ncontactRefUri: " + contactRefUri) + .append("\ncontactRingtoneUri: " + contactRefUri) + .append("\nshouldSendToVoicemail: " + shouldSendToVoicemail) + .append("\ncachedPhoto: " + cachedPhoto) + .append("\nisCachedPhotoCurrent: " + isCachedPhotoCurrent) + .append("\nemergency: " + mIsEmergency) + .append("\nvoicemail " + mIsVoiceMail) + .toString(); + } } diff --git a/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java b/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java index 4227a84..802e79b 100644 --- a/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java +++ b/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java @@ -47,9 +47,6 @@ public class CallerInfoAsyncQuery { private CallerInfoAsyncQueryHandler mHandler; - // Don't keep checking VM if it's going to throw an exception for this proc. - private static boolean sSkipVmCheck = false; - /** * Interface for a CallerInfoAsyncQueryHandler result return. */ @@ -227,18 +224,7 @@ public class CallerInfoAsyncQuery { // comments at the top of CallerInfo class). mCallerInfo = new CallerInfo().markAsEmergency(mQueryContext); } else if (cw.event == EVENT_VOICEMAIL_NUMBER) { - mCallerInfo = new CallerInfo(); - try { - // Note we're setting the phone number here (refer to javadoc - // comments at the top of CallerInfo class). - mCallerInfo.phoneNumber = - TelephonyManager.getDefault().getVoiceMailAlphaTag(); - } catch (SecurityException ex) { - // Should never happen: if this process does not have - // permission to retrieve VM tag, it should not have - // permission to retrieve VM number and would not generate - // an EVENT_VOICEMAIL_NUMBER. But if it happens, don't crash. - } + mCallerInfo = new CallerInfo().markAsVoiceMail(); } else { mCallerInfo = CallerInfo.getCallerInfo(mQueryContext, mQueryUri, cursor); // Use the number entered by the user for display. @@ -258,7 +244,7 @@ public class CallerInfoAsyncQuery { //notify the listener that the query is complete. if (cw.listener != null) { if (DBG) log("notifying listener: " + cw.listener.getClass().toString() + - " for token: " + token); + " for token: " + token + mCallerInfo); cw.listener.onQueryComplete(token, cw.cookie, mCallerInfo); } } @@ -315,23 +301,10 @@ public class CallerInfoAsyncQuery { // check to see if these are recognized numbers, and use shortcuts if we can. if (PhoneNumberUtils.isEmergencyNumber(number)) { cw.event = EVENT_EMERGENCY_NUMBER; + } else if (PhoneNumberUtils.isVoiceMailNumber(number)) { + cw.event = EVENT_VOICEMAIL_NUMBER; } else { - String vmNumber = null; - if (!sSkipVmCheck){ - try { - vmNumber = TelephonyManager.getDefault().getVoiceMailNumber(); - } catch (SecurityException ex) { - // Don't crash if this process doesn't have permission to - // retrieve VM number. It's still allowed to look up caller info. - // But don't try it again. - sSkipVmCheck = true; - } - } - if (PhoneNumberUtils.compare(number, vmNumber)) { - cw.event = EVENT_VOICEMAIL_NUMBER; - } else { - cw.event = EVENT_NEW_QUERY; - } + cw.event = EVENT_NEW_QUERY; } c.mHandler.startQuery (token, cw, contactRef, null, null, null, null); diff --git a/telephony/tests/TelephonyTest/AndroidManifest.xml b/telephony/tests/TelephonyTest/AndroidManifest.xml index c0cc0d5..b2a481b 100644 --- a/telephony/tests/TelephonyTest/AndroidManifest.xml +++ b/telephony/tests/TelephonyTest/AndroidManifest.xml @@ -28,8 +28,9 @@ </intent-filter> </activity> </application> - <instrumentation android:name=".TelephonyUnitTestRunner" - android:targetPackage="com.android.telephonytest" - android:label="Telephony unit tests InstrumentationRunner"> - </instrumentation> + <instrumentation android:name=".TelephonyUnitTestRunner" + android:targetPackage="com.android.telephonytest" + android:label="Telephony unit tests InstrumentationRunner"> + </instrumentation> + <uses-permission android:name="android.permission.READ_PHONE_STATE" /> </manifest> diff --git a/telephony/tests/TelephonyTest/src/com/android/telephonytest/TelephonyUnitTestRunner.java b/telephony/tests/TelephonyTest/src/com/android/telephonytest/TelephonyUnitTestRunner.java index 5da940d..9e1af31 100644 --- a/telephony/tests/TelephonyTest/src/com/android/telephonytest/TelephonyUnitTestRunner.java +++ b/telephony/tests/TelephonyTest/src/com/android/telephonytest/TelephonyUnitTestRunner.java @@ -37,6 +37,7 @@ public class TelephonyUnitTestRunner extends InstrumentationTestRunner { public TestSuite getAllTests() { TestSuite suite = new InstrumentationTestSuite(this); suite.addTestSuite(com.android.telephonytest.unit.CallerInfoUnitTest.class); + suite.addTestSuite(com.android.telephonytest.unit.PhoneNumberUtilsUnitTest.class); return suite; } diff --git a/telephony/tests/TelephonyTest/src/com/android/telephonytest/unit/CallerInfoUnitTest.java b/telephony/tests/TelephonyTest/src/com/android/telephonytest/unit/CallerInfoUnitTest.java index 4cd0266..0f24f15 100644 --- a/telephony/tests/TelephonyTest/src/com/android/telephonytest/unit/CallerInfoUnitTest.java +++ b/telephony/tests/TelephonyTest/src/com/android/telephonytest/unit/CallerInfoUnitTest.java @@ -107,6 +107,16 @@ public class CallerInfoUnitTest extends AndroidTestCase { assertIsValidEmergencyCallerInfo(); } + // TODO: Add more tests: + /** + * Check if the voice mail number cannot be retrieved that the + * original phone number is preserved. + */ + /** + * Check the markAs* methods work. + */ + + // // Helpers // diff --git a/telephony/tests/TelephonyTest/src/com/android/telephonytest/unit/PhoneNumberUtilsUnitTest.java b/telephony/tests/TelephonyTest/src/com/android/telephonytest/unit/PhoneNumberUtilsUnitTest.java new file mode 100644 index 0000000..2d3c548 --- /dev/null +++ b/telephony/tests/TelephonyTest/src/com/android/telephonytest/unit/PhoneNumberUtilsUnitTest.java @@ -0,0 +1,63 @@ +/* + * 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.telephonytest.unit; +import android.test.AndroidTestCase; +import android.test.suitebuilder.annotation.SmallTest; +import android.util.Log; + +import android.telephony.PhoneNumberUtils; +import android.telephony.TelephonyManager; + +/* + * Check the PhoneNumberUtils utility class works as expected. + * + */ + +public class PhoneNumberUtilsUnitTest extends AndroidTestCase { + private String mVoiceMailNumber; + private static final String TAG = "PhoneNumberUtilsUnitTest"; + + @Override + protected void setUp() throws Exception { + super.setUp(); + // FIXME: Why are we getting a security exception here? The + // permission is declared in the manifest.... + // mVoiceMailNumber = TelephonyManager.getDefault().getVoiceMailNumber(); + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + } + + /** + * Basic checks for the VoiceMail number. + * Assumes READ_PHONE_STATE permission and we don't have it. + */ + // TODO: Figure out why we don't have the permission declared in the manifest. + @SmallTest + public void testWithNumberNotEqualToVoiceMail() throws Exception { + assertFalse(PhoneNumberUtils.isVoiceMailNumber("911")); + assertFalse(PhoneNumberUtils.isVoiceMailNumber("tel:911")); + assertFalse(PhoneNumberUtils.isVoiceMailNumber("+18001234567")); + assertFalse(PhoneNumberUtils.isVoiceMailNumber("")); + assertFalse(PhoneNumberUtils.isVoiceMailNumber(null)); + // FIXME: + // assertTrue(PhoneNumberUtils.isVoiceMailNumber(mVoiceMailNumber)); + } + +} |
