120a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks/*
220a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks * Copyright (C) 2018 The Android Open Source Project
320a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks *
420a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks * Licensed under the Apache License, Version 2.0 (the "License"); you may not
520a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks * use this file except in compliance with the License. You may obtain a copy of
620a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks * the License at
720a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks *
820a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks * http://www.apache.org/licenses/LICENSE-2.0
920a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks *
1020a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks * Unless required by applicable law or agreed to in writing, software
1120a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
1220a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
1320a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks * License for the specific language governing permissions and limitations under
1420a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks * the License.
1520a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks */
1620a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks
1720a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubankspackage com.android.frameworks.perftests.am.tests;
1820a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks
1920a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanksimport android.content.ComponentName;
2020a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanksimport android.content.Context;
2120a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanksimport android.content.Intent;
2220a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanksimport android.content.ServiceConnection;
2320a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanksimport android.os.IBinder;
2420a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanksimport android.support.test.filters.LargeTest;
2520a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanksimport android.support.test.runner.AndroidJUnit4;
2620a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks
2720a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanksimport com.android.frameworks.perftests.am.util.Constants;
28ebd2ea0daf7d5bbeba8b6444c81b023ea55bececArthur Eubanksimport com.android.frameworks.perftests.am.util.TargetPackageUtils;
2920a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks
3020a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanksimport org.junit.Assert;
3120a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanksimport org.junit.Test;
3220a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanksimport org.junit.runner.RunWith;
3320a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks
3420a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks@RunWith(AndroidJUnit4.class)
3520a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks@LargeTest
3620a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubankspublic class ServiceBindPerfTest extends BasePerfTest {
3720a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks    /**
3820a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks     * Create and return a ServiceConnection that will add the current time with type
3920a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks     * Constants.TYPE_SERVICE_CONNECTED.
4020a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks     */
4120a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks    private ServiceConnection createServiceConnectionReportTime() {
4220a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks        return new ServiceConnection() {
4320a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks            @Override
4420a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks            public void onServiceConnected(ComponentName name, IBinder service) {
4520a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks                addReceivedTimeNs(Constants.TYPE_SERVICE_CONNECTED);
4620a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks            }
4720a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks
4820a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks            @Override
4920a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks            public void onServiceDisconnected(ComponentName name) {
5020a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks            }
5120a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks        };
5220a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks    }
5320a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks
5420a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks    /**
5520a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks     * Try to bind to the service with the input parameters, throwing a RuntimeException with the
5620a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks     * errorMessage on failure.
5720a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks     */
5820a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks    private void bindService(Intent intent, ServiceConnection serviceConnection, int flags) {
5920a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks        final boolean success = mContext.bindService(intent, serviceConnection, flags);
6020a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks        Assert.assertTrue("Could not bind to service", success);
6120a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks    }
6220a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks
6320a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks    /**
6420a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks     * Benchmark time from Context.bindService() to Service.onBind() when target package is not
6520a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks     * running.
6620a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks     */
6720a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks    @Test
6820a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks    public void bindServiceNotRunning() {
6920a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks        runPerfFunction(() -> {
7020a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks            final Intent intent = createServiceIntent();
7120a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks            final ServiceConnection serviceConnection = createServiceConnectionReportTime();
7220a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks
7320a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks            final long startTimeNs = System.nanoTime();
7420a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks            bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
7520a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks            try {
7620a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks                final long endTimeNs = getReceivedTimeNs(Constants.TYPE_SERVICE_CONNECTED);
7720a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks                return endTimeNs - startTimeNs;
7820a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks            } finally {
79ebd2ea0daf7d5bbeba8b6444c81b023ea55bececArthur Eubanks                TargetPackageUtils.unbindFromService(mContext, serviceConnection);
8020a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks            }
8120a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks        });
8220a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks    }
8320a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks
8420a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks    /**
8520a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks     * Benchmark time from Context.bindService() to Service.onBind() when target package is running.
8620a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks     */
8720a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks    @Test
8820a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks    public void bindServiceRunning() {
8920a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks        runPerfFunction(() -> {
9020a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks            startTargetPackage();
9120a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks
9220a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks            final Intent intent = createServiceIntent();
9320a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks            final ServiceConnection serviceConnection = createServiceConnectionReportTime();
9420a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks
9520a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks            final long startTimeNs = System.nanoTime();
9620a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks            bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
9720a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks            try {
9820a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks                final long endTimeNs = getReceivedTimeNs(Constants.TYPE_SERVICE_CONNECTED);
9920a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks                return endTimeNs - startTimeNs;
10020a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks            } finally {
101ebd2ea0daf7d5bbeba8b6444c81b023ea55bececArthur Eubanks                TargetPackageUtils.unbindFromService(mContext, serviceConnection);
10220a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks            }
10320a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks        });
10420a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks    }
10520a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks
10620a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks    /**
10720a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks     * Benchmark time from Context.bindService() to Service.onBind() when service is already bound
10820a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks     * to.
10920a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks     */
11020a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks    @Test
11120a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks    public void bindServiceAlreadyBound() {
11220a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks        runPerfFunction(() -> {
11320a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks            startTargetPackage();
11420a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks
11520a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks            final Intent intent = createServiceIntent();
116ebd2ea0daf7d5bbeba8b6444c81b023ea55bececArthur Eubanks            final ServiceConnection alreadyBoundServiceConnection =
117ebd2ea0daf7d5bbeba8b6444c81b023ea55bececArthur Eubanks                    TargetPackageUtils.bindAndWaitForConnectedService(mContext, intent);
11820a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks
11920a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks            try {
12020a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks                final ServiceConnection serviceConnection = createServiceConnectionReportTime();
12120a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks
12220a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks                final long startTimeNs = System.nanoTime();
12320a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks                try {
12420a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks                    bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
12520a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks                    final long endTimeNs = getReceivedTimeNs(Constants.TYPE_SERVICE_CONNECTED);
12620a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks                    return endTimeNs - startTimeNs;
12720a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks                } finally {
128ebd2ea0daf7d5bbeba8b6444c81b023ea55bececArthur Eubanks                    TargetPackageUtils.unbindFromService(mContext, serviceConnection);
12920a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks                }
13020a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks            } finally {
131ebd2ea0daf7d5bbeba8b6444c81b023ea55bececArthur Eubanks                TargetPackageUtils.unbindFromService(mContext, alreadyBoundServiceConnection);
13220a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks            }
13320a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks        });
13420a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks    }
13520a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks
13620a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks    /**
13720a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks     * Benchmark time from Context.bindService() (without BIND_ALLOW_OOM_MANAGEMENT) to
13820a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks     * Service.onBind() when service is already bound to with BIND_ALLOW_OOM_MANAGEMENT.
13920a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks     */
14020a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks    @Test
14120a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks    public void bindServiceAllowOomManagement() {
14220a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks        runPerfFunction(() -> {
14320a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks            final Intent intentNoOom = createServiceIntent();
144ebd2ea0daf7d5bbeba8b6444c81b023ea55bececArthur Eubanks            final ServiceConnection serviceConnectionOom =
145ebd2ea0daf7d5bbeba8b6444c81b023ea55bececArthur Eubanks                    TargetPackageUtils.bindAndWaitForConnectedService(mContext, intentNoOom,
146ebd2ea0daf7d5bbeba8b6444c81b023ea55bececArthur Eubanks                            Context.BIND_ALLOW_OOM_MANAGEMENT);
14720a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks
14820a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks            try {
14920a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks                final ServiceConnection serviceConnectionNoOom =
15020a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks                        createServiceConnectionReportTime();
15120a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks                try {
15220a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks                    final long startTimeNs = System.nanoTime();
15320a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks                    bindService(intentNoOom, serviceConnectionNoOom, Context.BIND_AUTO_CREATE);
15420a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks                    final long endTimeNs = getReceivedTimeNs(Constants.TYPE_SERVICE_CONNECTED);
15520a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks
15620a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks                    return endTimeNs - startTimeNs;
15720a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks                } finally {
158ebd2ea0daf7d5bbeba8b6444c81b023ea55bececArthur Eubanks                    TargetPackageUtils.unbindFromService(mContext, serviceConnectionNoOom);
15920a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks                }
16020a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks            } finally {
161ebd2ea0daf7d5bbeba8b6444c81b023ea55bececArthur Eubanks                TargetPackageUtils.unbindFromService(mContext, serviceConnectionOom);
16220a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks            }
16320a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks        });
16420a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks    }
16520a29576ef3773535d44dec7aadeb17d89bd5f07Arthur Eubanks}
166