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 com.android.internal.infra; 18 19 import android.annotation.NonNull; 20 import android.content.ComponentName; 21 import android.content.Context; 22 import android.os.Handler; 23 import android.os.IInterface; 24 import android.util.Slog; 25 26 import java.io.PrintWriter; 27 import java.util.ArrayList; 28 29 /** 30 * Base class representing a remote service that can queue multiple pending requests while not 31 * bound. 32 * 33 * @param <S> the concrete remote service class 34 * @param <I> the interface of the binder service 35 */ 36 public abstract class AbstractMultiplePendingRequestsRemoteService<S 37 extends AbstractMultiplePendingRequestsRemoteService<S, I>, I extends IInterface> 38 extends AbstractRemoteService<S, I> { 39 40 private final int mInitialCapacity; 41 42 protected ArrayList<BasePendingRequest<S, I>> mPendingRequests; 43 AbstractMultiplePendingRequestsRemoteService(@onNull Context context, @NonNull String serviceInterface, @NonNull ComponentName componentName, int userId, @NonNull VultureCallback<S> callback, @NonNull Handler handler, int bindingFlags, boolean verbose, int initialCapacity)44 public AbstractMultiplePendingRequestsRemoteService(@NonNull Context context, 45 @NonNull String serviceInterface, @NonNull ComponentName componentName, int userId, 46 @NonNull VultureCallback<S> callback, @NonNull Handler handler, 47 int bindingFlags, boolean verbose, int initialCapacity) { 48 super(context, serviceInterface, componentName, userId, callback, handler, bindingFlags, 49 verbose); 50 mInitialCapacity = initialCapacity; 51 } 52 53 @Override // from AbstractRemoteService handlePendingRequests()54 void handlePendingRequests() { 55 if (mPendingRequests != null) { 56 final int size = mPendingRequests.size(); 57 if (mVerbose) Slog.v(mTag, "Sending " + size + " pending requests"); 58 for (int i = 0; i < size; i++) { 59 mPendingRequests.get(i).run(); 60 } 61 mPendingRequests = null; 62 } 63 } 64 65 @Override // from AbstractRemoteService handleOnDestroy()66 protected void handleOnDestroy() { 67 if (mPendingRequests != null) { 68 final int size = mPendingRequests.size(); 69 if (mVerbose) Slog.v(mTag, "Canceling " + size + " pending requests"); 70 for (int i = 0; i < size; i++) { 71 mPendingRequests.get(i).cancel(); 72 } 73 mPendingRequests = null; 74 } 75 } 76 77 @Override // from AbstractRemoteService handleBindFailure()78 final void handleBindFailure() { 79 if (mPendingRequests != null) { 80 final int size = mPendingRequests.size(); 81 if (mVerbose) Slog.v(mTag, "Sending failure to " + size + " pending requests"); 82 for (int i = 0; i < size; i++) { 83 final BasePendingRequest<S, I> request = mPendingRequests.get(i); 84 request.onFailed(); 85 request.finish(); 86 } 87 mPendingRequests = null; 88 } 89 } 90 91 @Override // from AbstractRemoteService dump(@onNull String prefix, @NonNull PrintWriter pw)92 public void dump(@NonNull String prefix, @NonNull PrintWriter pw) { 93 super.dump(prefix, pw); 94 95 pw.append(prefix).append("initialCapacity=").append(String.valueOf(mInitialCapacity)) 96 .println(); 97 final int size = mPendingRequests == null ? 0 : mPendingRequests.size(); 98 pw.append(prefix).append("pendingRequests=").append(String.valueOf(size)).println(); 99 } 100 101 @Override // from AbstractRemoteService handlePendingRequestWhileUnBound(@onNull BasePendingRequest<S, I> pendingRequest)102 void handlePendingRequestWhileUnBound(@NonNull BasePendingRequest<S, I> pendingRequest) { 103 if (mPendingRequests == null) { 104 mPendingRequests = new ArrayList<>(mInitialCapacity); 105 } 106 mPendingRequests.add(pendingRequest); 107 if (mVerbose) { 108 Slog.v(mTag, "queued " + mPendingRequests.size() + " requests; last=" + pendingRequest); 109 } 110 } 111 } 112