1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 * use this file except in compliance with the License. You may obtain a copy of 6 * 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, WITHOUT 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 * License for the specific language governing permissions and limitations under 14 * the License. 15 */ 16 17 package com.android.frameworks.perftests.am.tests; 18 19 import android.content.ComponentName; 20 import android.content.Context; 21 import android.content.Intent; 22 import android.content.ServiceConnection; 23 import android.os.IBinder; 24 import android.support.test.filters.LargeTest; 25 import android.support.test.runner.AndroidJUnit4; 26 27 import com.android.frameworks.perftests.am.util.Constants; 28 import com.android.frameworks.perftests.am.util.TargetPackageUtils; 29 30 import org.junit.Assert; 31 import org.junit.Test; 32 import org.junit.runner.RunWith; 33 34 @RunWith(AndroidJUnit4.class) 35 @LargeTest 36 public class ServiceBindPerfTest extends BasePerfTest { 37 /** 38 * Create and return a ServiceConnection that will add the current time with type 39 * Constants.TYPE_SERVICE_CONNECTED. 40 */ 41 private ServiceConnection createServiceConnectionReportTime() { 42 return new ServiceConnection() { 43 @Override 44 public void onServiceConnected(ComponentName name, IBinder service) { 45 addReceivedTimeNs(Constants.TYPE_SERVICE_CONNECTED); 46 } 47 48 @Override 49 public void onServiceDisconnected(ComponentName name) { 50 } 51 }; 52 } 53 54 /** 55 * Try to bind to the service with the input parameters, throwing a RuntimeException with the 56 * errorMessage on failure. 57 */ 58 private void bindService(Intent intent, ServiceConnection serviceConnection, int flags) { 59 final boolean success = mContext.bindService(intent, serviceConnection, flags); 60 Assert.assertTrue("Could not bind to service", success); 61 } 62 63 /** 64 * Benchmark time from Context.bindService() to Service.onBind() when target package is not 65 * running. 66 */ 67 @Test 68 public void bindServiceNotRunning() { 69 runPerfFunction(() -> { 70 final Intent intent = createServiceIntent(); 71 final ServiceConnection serviceConnection = createServiceConnectionReportTime(); 72 73 final long startTimeNs = System.nanoTime(); 74 bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE); 75 try { 76 final long endTimeNs = getReceivedTimeNs(Constants.TYPE_SERVICE_CONNECTED); 77 return endTimeNs - startTimeNs; 78 } finally { 79 TargetPackageUtils.unbindFromService(mContext, serviceConnection); 80 } 81 }); 82 } 83 84 /** 85 * Benchmark time from Context.bindService() to Service.onBind() when target package is running. 86 */ 87 @Test 88 public void bindServiceRunning() { 89 runPerfFunction(() -> { 90 startTargetPackage(); 91 92 final Intent intent = createServiceIntent(); 93 final ServiceConnection serviceConnection = createServiceConnectionReportTime(); 94 95 final long startTimeNs = System.nanoTime(); 96 bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE); 97 try { 98 final long endTimeNs = getReceivedTimeNs(Constants.TYPE_SERVICE_CONNECTED); 99 return endTimeNs - startTimeNs; 100 } finally { 101 TargetPackageUtils.unbindFromService(mContext, serviceConnection); 102 } 103 }); 104 } 105 106 /** 107 * Benchmark time from Context.bindService() to Service.onBind() when service is already bound 108 * to. 109 */ 110 @Test 111 public void bindServiceAlreadyBound() { 112 runPerfFunction(() -> { 113 startTargetPackage(); 114 115 final Intent intent = createServiceIntent(); 116 final ServiceConnection alreadyBoundServiceConnection = 117 TargetPackageUtils.bindAndWaitForConnectedService(mContext, intent); 118 119 try { 120 final ServiceConnection serviceConnection = createServiceConnectionReportTime(); 121 122 final long startTimeNs = System.nanoTime(); 123 try { 124 bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE); 125 final long endTimeNs = getReceivedTimeNs(Constants.TYPE_SERVICE_CONNECTED); 126 return endTimeNs - startTimeNs; 127 } finally { 128 TargetPackageUtils.unbindFromService(mContext, serviceConnection); 129 } 130 } finally { 131 TargetPackageUtils.unbindFromService(mContext, alreadyBoundServiceConnection); 132 } 133 }); 134 } 135 136 /** 137 * Benchmark time from Context.bindService() (without BIND_ALLOW_OOM_MANAGEMENT) to 138 * Service.onBind() when service is already bound to with BIND_ALLOW_OOM_MANAGEMENT. 139 */ 140 @Test 141 public void bindServiceAllowOomManagement() { 142 runPerfFunction(() -> { 143 final Intent intentNoOom = createServiceIntent(); 144 final ServiceConnection serviceConnectionOom = 145 TargetPackageUtils.bindAndWaitForConnectedService(mContext, intentNoOom, 146 Context.BIND_ALLOW_OOM_MANAGEMENT); 147 148 try { 149 final ServiceConnection serviceConnectionNoOom = 150 createServiceConnectionReportTime(); 151 try { 152 final long startTimeNs = System.nanoTime(); 153 bindService(intentNoOom, serviceConnectionNoOom, Context.BIND_AUTO_CREATE); 154 final long endTimeNs = getReceivedTimeNs(Constants.TYPE_SERVICE_CONNECTED); 155 156 return endTimeNs - startTimeNs; 157 } finally { 158 TargetPackageUtils.unbindFromService(mContext, serviceConnectionNoOom); 159 } 160 } finally { 161 TargetPackageUtils.unbindFromService(mContext, serviceConnectionOom); 162 } 163 }); 164 } 165 } 166