| /* |
| * 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.content.ContentResolver; |
| import android.content.Context; |
| import android.content.res.Resources; |
| import com.android.internal.telephony.CallerInfo; |
| import com.android.internal.telephony.CallerInfoAsyncQuery; |
| import android.util.Log; |
| import android.os.Looper; |
| import android.test.ActivityInstrumentationTestCase; |
| import android.util.StringBuilderPrinter; |
| |
| /* |
| * Check the CallerInfo utility class works as expected. |
| * |
| */ |
| |
| public class CallerInfoUnitTest extends AndroidTestCase { |
| private CallerInfo mInfo; |
| private Context mContext; |
| |
| private static final String kEmergencyNumber = "Emergency Number"; |
| private static final int kToken = 0xdeadbeef; |
| private static final String TAG = "CallerInfoUnitTest"; |
| |
| @Override |
| protected void setUp() throws Exception { |
| super.setUp(); |
| mContext = new MockContext(); |
| mInfo = new CallerInfo(); |
| } |
| |
| @Override |
| protected void tearDown() throws Exception { |
| super.tearDown(); |
| } |
| |
| /** |
| * Checks the caller info instance is flagged as an emergency if |
| * the number is an emergency one. There is no test for the |
| * contact based constructors because emergency number are not in |
| * the contact DB. |
| */ |
| @SmallTest |
| public void testEmergencyIsProperlySet() throws Exception { |
| assertFalse(mInfo.isEmergencyNumber()); |
| |
| mInfo = CallerInfo.getCallerInfo(mContext, "911"); |
| assertIsValidEmergencyCallerInfo(); |
| |
| mInfo = CallerInfo.getCallerInfo(mContext, "tel:911"); |
| assertIsValidEmergencyCallerInfo(); |
| |
| |
| // This one hits the content resolver. |
| mInfo = CallerInfo.getCallerInfo(mContext, "18001234567"); |
| assertFalse(mInfo.isEmergencyNumber()); |
| } |
| |
| /** |
| * Same as testEmergencyIsProperlySet but uses the async query api. |
| */ |
| @SmallTest |
| public void testEmergencyIsProperlySetUsingAsyncQuery() throws Exception { |
| QueryRunner query; |
| |
| query = new QueryRunner("911"); |
| query.runAndCheckCompletion(); |
| assertIsValidEmergencyCallerInfo(); |
| |
| query = new QueryRunner("tel:911"); |
| query.runAndCheckCompletion(); |
| assertIsValidEmergencyCallerInfo(); |
| |
| query = new QueryRunner("18001234567"); |
| query.runAndCheckCompletion(); |
| assertFalse(mInfo.isEmergencyNumber()); |
| } |
| |
| /** |
| * For emergency caller info, phoneNumber should be set to the |
| * string emergency_call_dialog_number_for_display and the |
| * photoResource should be set to the picture_emergency drawable. |
| */ |
| @SmallTest |
| public void testEmergencyNumberAndPhotoAreSet() throws Exception { |
| mInfo = CallerInfo.getCallerInfo(mContext, "911"); |
| |
| 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 |
| // |
| |
| // Partial implementation of MockResources. |
| public class MockResources extends android.test.mock.MockResources |
| { |
| @Override |
| public String getString(int resId) throws Resources.NotFoundException { |
| switch (resId) { |
| case com.android.internal.R.string.emergency_call_dialog_number_for_display: |
| return kEmergencyNumber; |
| default: |
| throw new UnsupportedOperationException("Missing handling for resid " + resId); |
| } |
| } |
| } |
| |
| // Partial implementation of MockContext. |
| public class MockContext extends android.test.mock.MockContext { |
| private ContentResolver mResolver; |
| private Resources mResources; |
| |
| public MockContext() { |
| mResolver = new android.test.mock.MockContentResolver(); |
| mResources = new MockResources(); |
| } |
| |
| @Override |
| public ContentResolver getContentResolver() { |
| return mResolver; |
| } |
| |
| @Override |
| public Resources getResources() { |
| return mResources; |
| } |
| } |
| |
| /** |
| * Class to run a CallerInfoAsyncQuery in a separate thread, with |
| * its own Looper. We cannot use the main Looper because on the |
| * 1st quit the thread is maked dead, ie no further test can use |
| * it. Also there is not way to inject a Looper instance in the |
| * query, so we have to use a thread with its own looper. |
| */ |
| private class QueryRunner extends Thread |
| implements CallerInfoAsyncQuery.OnQueryCompleteListener { |
| private Looper mLooper; |
| private String mNumber; |
| private boolean mAsyncCompleted; |
| |
| public QueryRunner(String number) { |
| super(); |
| mNumber = number; |
| } |
| |
| // Run the query in the thread, wait for completion. |
| public void runAndCheckCompletion() throws InterruptedException { |
| start(); |
| join(); |
| assertTrue(mAsyncCompleted); |
| } |
| |
| @Override |
| public void run() { |
| Looper.prepare(); |
| mLooper = Looper.myLooper(); |
| mAsyncCompleted = false; |
| // The query will pick the thread local looper we've just prepared. |
| CallerInfoAsyncQuery.startQuery(kToken, mContext, mNumber, this, null); |
| mLooper.loop(); |
| } |
| |
| // Quit the Looper on the 1st callback |
| // (EVENT_EMERGENCY_NUMBER). There is another message |
| // (EVENT_END_OF_QUEUE) that will never be delivered because |
| // the test has exited. The corresponding stack trace |
| // "Handler{xxxxx} sending message to a Handler on a dead |
| // thread" can be ignored. |
| public void onQueryComplete(int token, Object cookie, CallerInfo info) { |
| mAsyncCompleted = true; |
| mInfo = info; |
| mLooper.quit(); |
| } |
| } |
| |
| /** |
| * Fail if mInfo does not contain a valid emergency CallerInfo instance. |
| */ |
| private void assertIsValidEmergencyCallerInfo() throws Exception { |
| assertTrue(mInfo.isEmergencyNumber()); |
| |
| // For emergency caller info, phoneNumber should be set to the |
| // string emergency_call_dialog_number_for_display and the |
| // photoResource should be set to the picture_emergency drawable. |
| assertEquals(kEmergencyNumber, mInfo.phoneNumber); |
| assertEquals(com.android.internal.R.drawable.picture_emergency, mInfo.photoResource); |
| |
| // The name should be null |
| assertNull(mInfo.name); |
| assertEquals(0, mInfo.namePresentation); |
| assertNull(mInfo.cnapName); |
| assertEquals(0, mInfo.numberPresentation); |
| |
| assertFalse(mInfo.contactExists); |
| assertEquals(0, mInfo.person_id); |
| assertFalse(mInfo.needUpdate); |
| assertNull(mInfo.contactRefUri); |
| |
| assertNull(mInfo.phoneLabel); |
| assertEquals(0, mInfo.numberType); |
| assertNull(mInfo.numberLabel); |
| |
| assertNull(mInfo.contactRingtoneUri); |
| assertFalse(mInfo.shouldSendToVoicemail); |
| |
| assertNull(mInfo.cachedPhoto); |
| assertFalse(mInfo.isCachedPhotoCurrent); |
| } |
| } |