1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.dialer.janktests; 18 19 import android.content.ContentProviderOperation; 20 import android.content.ContentValues; 21 import android.content.Intent; 22 import android.content.OperationApplicationException; 23 import android.content.pm.PackageManager; 24 import android.database.Cursor; 25 import android.net.Uri; 26 import android.os.RemoteException; 27 import android.os.SystemClock; 28 import android.provider.BaseColumns; 29 import android.provider.CallLog; 30 import android.provider.ContactsContract; 31 import android.provider.ContactsContract.CommonDataKinds; 32 import android.provider.ContactsContract.CommonDataKinds.Phone; 33 import android.provider.ContactsContract.CommonDataKinds.StructuredName; 34 import android.provider.ContactsContract.RawContacts; 35 import android.support.test.uiautomator.By; 36 import android.support.test.uiautomator.Direction; 37 import android.support.test.uiautomator.UiDevice; 38 import android.support.test.uiautomator.UiObject2; 39 import android.support.test.uiautomator.UiObjectNotFoundException; 40 import android.support.test.uiautomator.Until; 41 42 import androidx.test.jank.GfxMonitor; 43 import androidx.test.jank.JankTest; 44 import androidx.test.jank.JankTestBase; 45 46 import java.util.ArrayList; 47 import java.util.Random; 48 49 /** 50 * Jank test for Dialer app 51 * open a contact, initiate call to open the dialing screen 52 * fling call log 53 */ 54 public class DialerJankTests extends JankTestBase { 55 private static final int TIMEOUT = 5000; 56 private static final int INNER_LOOP = 5; 57 private static final int EXPECTED_FRAMES = 100; 58 private static final String PACKAGE_NAME = "com.google.android.dialer"; 59 private static final String RES_PACKAGE_NAME = "com.android.dialer"; 60 private static final String RES_PACKAGE_NAME2 = "com.android.contacts"; 61 private static final String RES_PACKAGE_NAME3 = "android"; 62 private static final String APP_NAME = "Phone"; 63 private static final String CONTACT_NAME = "A AAA Test Account"; 64 private static final String CONTACT_NUMBER = "2468"; 65 private UiDevice mDevice; 66 static final int PICK_CONTACT_REQUEST = 1; 67 68 @Override setUp()69 public void setUp() throws Exception { 70 super.setUp(); 71 mDevice = UiDevice.getInstance(getInstrumentation()); 72 mDevice.setOrientationNatural(); 73 } 74 75 @Override tearDown()76 protected void tearDown() throws Exception { 77 mDevice.unfreezeRotation(); 78 super.tearDown(); 79 } 80 launchApp(String packageName)81 public void launchApp(String packageName) { 82 PackageManager pm = getInstrumentation().getContext().getPackageManager(); 83 Intent appIntent = pm.getLaunchIntentForPackage(packageName); 84 appIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 85 getInstrumentation().getContext().startActivity(appIntent); 86 mDevice.waitForIdle(); 87 } 88 launchDialer()89 public void launchDialer () throws OperationApplicationException, RemoteException { 90 if (!doesContactExist()) { 91 insertNewContacts(); 92 } 93 launchApp(PACKAGE_NAME); 94 mDevice.waitForIdle(); 95 96 // Open contacts list 97 UiObject2 contacts = mDevice.wait(Until.findObject(By.desc("Contacts")), TIMEOUT); 98 assertNotNull("Contacts can't be found", contacts); 99 contacts.clickAndWait(Until.newWindow(), TIMEOUT); 100 // Find a contact by a given contact-name 101 UiObject2 contactName = mDevice.wait(Until.findObject( 102 By.res(RES_PACKAGE_NAME, "cliv_name_textview").text(CONTACT_NAME)), TIMEOUT); 103 assertNotNull("Contactname can't be found", contactName); 104 contactName.clickAndWait(Until.newWindow(), TIMEOUT); 105 // Click on dial-icon beside contact-number to ensure test is ready to be executed 106 UiObject2 contactNumber = mDevice.wait(Until.findObject( 107 By.res(RES_PACKAGE_NAME2,"header").text(CONTACT_NUMBER)), TIMEOUT); 108 assertNotNull("Contact number can't be found", contactNumber); 109 contactNumber.clickAndWait(Until.newWindow(), TIMEOUT); 110 111 UiObject2 endCall = mDevice.wait(Until.findObject(By.res(RES_PACKAGE_NAME, 112 "floating_end_call_action_button")), 2 * TIMEOUT); 113 endCall.clickAndWait(Until.newWindow(), TIMEOUT);; 114 SystemClock.sleep(200); 115 } 116 117 @JankTest(beforeTest="launchDialer", expectedFrames=EXPECTED_FRAMES) 118 @GfxMonitor(processName=PACKAGE_NAME) testDialerCallInit()119 public void testDialerCallInit() { 120 for (int i = 0; i < INNER_LOOP; i++) { 121 UiObject2 contactNumber = mDevice.wait(Until.findObject( 122 By.res(RES_PACKAGE_NAME2,"header").text(CONTACT_NUMBER)), TIMEOUT); 123 assertNotNull("Contact number can't be found", contactNumber); 124 contactNumber.clickAndWait(Until.newWindow(), TIMEOUT); 125 UiObject2 endCall = mDevice.wait(Until.findObject(By.res(RES_PACKAGE_NAME, 126 "floating_end_call_action_button")), 2 * TIMEOUT); 127 endCall.clickAndWait(Until.newWindow(), TIMEOUT); 128 SystemClock.sleep(200); 129 } 130 } 131 launchCallLog()132 public void launchCallLog() throws UiObjectNotFoundException { 133 if (getCallLogCount() < 100) { 134 for (int i = 0; i < 100; i++) { 135 addNumToCalLog(getRandomPhoneNumber()); 136 } 137 } 138 launchApp(PACKAGE_NAME); 139 mDevice.waitForIdle(); 140 // Find 'Call History' and click 141 mDevice.wait(Until.findObject(By.desc("Call History")), TIMEOUT).click(); 142 mDevice.wait(Until.findObject(By.res(RES_PACKAGE_NAME,"lists_pager")), TIMEOUT); 143 } 144 145 @JankTest(beforeTest="launchCallLog", expectedFrames=EXPECTED_FRAMES) 146 @GfxMonitor(processName=PACKAGE_NAME) testDialerCallLogFling()147 public void testDialerCallLogFling() { 148 UiObject2 callLog = mDevice.wait(Until.findObject( 149 By.res(RES_PACKAGE_NAME,"lists_pager")), TIMEOUT); 150 assertNotNull("Call log can't be found", callLog); 151 for (int i = 0; i < INNER_LOOP; i++) { 152 callLog.fling(Direction.DOWN); 153 SystemClock.sleep(100); 154 callLog.fling(Direction.UP); 155 SystemClock.sleep(100); 156 } 157 } 158 159 // Method to insert a new contact insertNewContacts()160 public void insertNewContacts() throws OperationApplicationException, RemoteException { 161 ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>(); 162 int rawContactID = ops.size(); 163 // to insert a new raw contact in the table ContactsContract.RawContacts 164 ops.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI) 165 .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, "Test") 166 .withValue(RawContacts.ACCOUNT_NAME, CONTACT_NAME) 167 .build()); 168 169 // to insert display name in the table ContactsContract.Data 170 ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) 171 .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, rawContactID) 172 .withValue(ContactsContract.Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE) 173 .withValue(StructuredName.DISPLAY_NAME, CONTACT_NAME) 174 .build()); 175 176 // to insert Mobile Number in the table ContactsContract.Data 177 ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) 178 .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, rawContactID) 179 .withValue(ContactsContract.Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE) 180 .withValue(Phone.NUMBER, CONTACT_NUMBER) 181 .withValue(Phone.TYPE, CommonDataKinds.Phone.TYPE_MOBILE) 182 .build()); 183 184 // Executing all the insert operations as a single database transaction 185 getInstrumentation().getContext().getContentResolver() 186 .applyBatch(ContactsContract.AUTHORITY, ops); 187 } 188 189 // Checks whether certain contact exists or not doesContactExist()190 public boolean doesContactExist() { 191 Uri uri = Uri.withAppendedPath( 192 ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(CONTACT_NUMBER)); 193 Cursor contactLookup = getInstrumentation().getContext().getContentResolver().query( 194 uri, new String[] { 195 BaseColumns._ID, 196 ContactsContract.PhoneLookup.DISPLAY_NAME }, 197 null, 198 null, 199 null); 200 boolean found = false; 201 try { 202 if (contactLookup != null && contactLookup.getCount() > 0) { 203 contactLookup.moveToNext(); 204 if (contactLookup.getString(contactLookup.getColumnIndex( 205 ContactsContract.Data.DISPLAY_NAME)).equals(CONTACT_NAME)) 206 found = true; 207 } 208 } finally { 209 if (contactLookup != null) { 210 contactLookup.close(); 211 } 212 } 213 214 return found; 215 } 216 217 // Inserts a new entry in the call log addNumToCalLog(String number)218 public void addNumToCalLog(String number){ 219 ContentValues values = new ContentValues(); 220 values.put(CallLog.Calls.NUMBER, number); 221 values.put(CallLog.Calls.DATE, System.currentTimeMillis()); 222 values.put(CallLog.Calls.DURATION, 0); 223 values.put(CallLog.Calls.TYPE, CallLog.Calls.OUTGOING_TYPE); 224 values.put(CallLog.Calls.NEW, 1); 225 values.put(CallLog.Calls.CACHED_NAME, ""); 226 values.put(CallLog.Calls.CACHED_NUMBER_TYPE, 0); 227 values.put(CallLog.Calls.CACHED_NUMBER_LABEL, ""); 228 getInstrumentation().getContext().getContentResolver() 229 .insert(CallLog.Calls.CONTENT_URI, values); 230 } 231 232 // Gets call log count getCallLogCount()233 public int getCallLogCount() { 234 Cursor cursor = getInstrumentation().getContext().getContentResolver() 235 .query(CallLog.Calls.CONTENT_URI, null, null, null, null); 236 return cursor.getCount(); 237 } 238 239 // Generates a random phone number getRandomPhoneNumber()240 public String getRandomPhoneNumber() { 241 Random rand = new Random(); 242 int num1 = (rand.nextInt(7) + 1) * 100 + (rand.nextInt(8) * 10) + rand.nextInt(8); 243 int num2 = rand.nextInt(743); 244 int num3 = rand.nextInt(10000); 245 246 return String.format("%03d-%03d-%04d", num1, num2, num3); 247 } 248 } 249