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