1 /* 2 * Copyright (C) 2018 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 android.os; 18 19 import android.app.Service; 20 import android.content.ComponentName; 21 import android.content.Context; 22 import android.content.Intent; 23 import android.content.ServiceConnection; 24 25 import java.util.concurrent.BlockingQueue; 26 import java.util.concurrent.LinkedBlockingQueue; 27 import java.util.concurrent.TimeUnit; 28 29 /** 30 * Service used by {@link BinderWorkSourceTest}. 31 */ 32 public class BinderWorkSourceNestedService extends Service { 33 private final IBinderWorkSourceNestedService.Stub mBinder = 34 new IBinderWorkSourceNestedService.Stub() { 35 36 public int[] nestedCallWithWorkSourceToSet(int uidToBlame) { 37 final int uid = Binder.getCallingWorkSourceUid(); 38 if (uidToBlame != ThreadLocalWorkSource.UID_NONE) { 39 Binder.setCallingWorkSourceUid(uidToBlame); 40 } 41 final int nestedUid = callGetIncomingWorkSourceUid(); 42 return new int[] {uid, nestedUid}; 43 } 44 45 public int[] nestedCall() { 46 final int uid = Binder.getCallingWorkSourceUid(); 47 final int nestedUid = callGetIncomingWorkSourceUid(); 48 return new int[] {uid, nestedUid}; 49 } 50 51 private int callGetIncomingWorkSourceUid() { 52 BlockingQueue<IBinderWorkSourceService> blockingQueue = 53 new LinkedBlockingQueue<>(); 54 ServiceConnection mConnection = new ServiceConnection() { 55 public void onServiceConnected(ComponentName name, IBinder service) { 56 blockingQueue.add(IBinderWorkSourceService.Stub.asInterface(service)); 57 } 58 59 public void onServiceDisconnected(ComponentName name) { 60 } 61 }; 62 63 Context context = getApplicationContext(); 64 context.bindService( 65 new Intent(context, BinderWorkSourceService.class), 66 mConnection, Context.BIND_AUTO_CREATE); 67 68 final IBinderWorkSourceService service; 69 try { 70 service = blockingQueue.poll(30, TimeUnit.SECONDS); 71 } catch (InterruptedException e) { 72 throw new RuntimeException(e); 73 } 74 if (service == null) { 75 throw new RuntimeException("Gave up waiting for BinderWorkSourceService"); 76 } 77 78 try { 79 return service.getIncomingWorkSourceUid(); 80 } catch (RemoteException e) { 81 throw new RuntimeException(e); 82 } finally { 83 context.unbindService(mConnection); 84 } 85 } 86 }; 87 onBind(Intent intent)88 public IBinder onBind(Intent intent) { 89 return mBinder; 90 } 91 } 92