1 /* <lambda>null2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file 5 * except in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the 10 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 11 * KIND, either express or implied. See the License for the specific language governing 12 * permissions and limitations under the License. 13 */ 14 15 package com.google.android.startop.iorap 16 17 import android.os.ServiceManager 18 import androidx.test.filters.MediumTest 19 import org.junit.Test 20 import org.mockito.Mockito.argThat 21 import org.mockito.Mockito.eq 22 import org.mockito.Mockito.inOrder 23 import org.mockito.Mockito.spy 24 import org.mockito.Mockito.timeout 25 26 // @Ignore("Test is disabled until iorapd is added to init and there's selinux policies for it") 27 @MediumTest 28 class IIorapIntegrationTest { 29 /** 30 * @throws ServiceManager.ServiceNotFoundException if iorapd service could not be found 31 */ 32 private val iorapService: IIorap by lazy { 33 // TODO: connect to 'iorapd.stub' which doesn't actually do any work other than reply. 34 IIorap.Stub.asInterface(ServiceManager.getServiceOrThrow("iorapd")) 35 36 // Use 'adb shell setenforce 0' otherwise this whole test fails, 37 // because the servicemanager is not allowed to hand out the binder token for iorapd. 38 39 // TODO: implement the selinux policies for iorapd. 40 } 41 42 // A dummy binder stub implementation is required to use with mockito#spy. 43 // Mockito overrides the methods at runtime and tracks how methods were invoked. 44 open class DummyTaskListener : ITaskListener.Stub() { 45 // Note: make parameters nullable to avoid the kotlin IllegalStateExceptions 46 // from using the mockito matchers (eq, argThat, etc). 47 override fun onProgress(requestId: RequestId?, result: TaskResult?) { 48 } 49 50 override fun onComplete(requestId: RequestId?, result: TaskResult?) { 51 } 52 } 53 54 private fun testAnyMethod(func: (RequestId) -> Unit) { 55 val taskListener = spy(DummyTaskListener())!! 56 57 try { 58 iorapService.setTaskListener(taskListener) 59 // Note: Binder guarantees total order for oneway messages sent to the same binder 60 // interface, so we don't need any additional blocking here before sending later calls. 61 62 // Every new method call should have a unique request id. 63 val requestId = RequestId.nextValueForSequence()!! 64 65 // Apply the specific function under test. 66 func(requestId) 67 68 // Typical mockito behavior is to allow any-order callbacks, but we want to test order. 69 val inOrder = inOrder(taskListener) 70 71 // The "stub" behavior of iorapd is that every request immediately gets a response of 72 // BEGAN,ONGOING,COMPLETED 73 inOrder.verify(taskListener, timeout(100)) 74 .onProgress(eq(requestId), argThat { it!!.state == TaskResult.STATE_BEGAN }) 75 inOrder.verify(taskListener, timeout(100)) 76 .onProgress(eq(requestId), argThat { it!!.state == TaskResult.STATE_ONGOING }) 77 inOrder.verify(taskListener, timeout(100)) 78 .onComplete(eq(requestId), argThat { it!!.state == TaskResult.STATE_COMPLETED }) 79 inOrder.verifyNoMoreInteractions() 80 } finally { 81 // iorapService.setTaskListener(null) 82 // FIXME: null is broken, C++ side sees a non-null object. 83 } 84 } 85 86 @Test 87 fun testOnPackageEvent() { 88 /* 89 testAnyMethod { requestId : RequestId -> 90 iorapService.onPackageEvent(requestId, 91 PackageEvent.createReplaced( 92 Uri.parse("https://www.google.com"), "com.fake.package")) 93 } 94 */ 95 // FIXME: Broken for some reason. C++ side never sees this call. 96 } 97 98 @Test 99 fun testOnAppIntentEvent() { 100 testAnyMethod { requestId: RequestId -> 101 iorapService.onAppIntentEvent(requestId, AppIntentEvent.createDefaultIntentChanged( 102 ActivityInfo("dont care", "dont care"), 103 ActivityInfo("dont care 2", "dont care 2"))) 104 } 105 } 106 107 @Test 108 fun testOnSystemServiceEvent() { 109 testAnyMethod { requestId: RequestId -> 110 iorapService.onSystemServiceEvent(requestId, 111 SystemServiceEvent(SystemServiceEvent.TYPE_START)) 112 } 113 } 114 115 @Test 116 fun testOnSystemServiceUserEvent() { 117 testAnyMethod { requestId: RequestId -> 118 iorapService.onSystemServiceUserEvent(requestId, 119 SystemServiceUserEvent(SystemServiceUserEvent.TYPE_START_USER, 0)) 120 } 121 } 122 } 123