1/*
2 * Copyright (C) 2017 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
17package com.android.frameworks.coretests.binderproxycountingtestapp;
18
19import android.app.Service;
20import android.content.BroadcastReceiver;
21import android.content.ComponentName;
22import android.content.Context;
23import android.content.Intent;
24import android.content.IntentFilter;
25import android.content.ServiceConnection;
26import android.os.IBinder;
27import android.os.RemoteException;
28import android.util.Log;
29
30import com.android.frameworks.coretests.aidl.IBinderProxyCountingService;
31import com.android.frameworks.coretests.aidl.IBpcTestAppCmdService;
32import com.android.frameworks.coretests.aidl.ITestRemoteCallback;
33
34import java.util.ArrayList;
35import java.util.concurrent.CountDownLatch;
36import java.util.concurrent.TimeUnit;
37
38public class BpcTestAppCmdService extends Service {
39    private static final String TAG = BpcTestAppCmdService.class.getSimpleName();
40
41    private static final String TEST_SERVICE_PKG =
42            "com.android.frameworks.coretests.binderproxycountingtestservice";
43    private static final String TEST_SERVICE_CLASS =
44            TEST_SERVICE_PKG + ".BinderProxyCountingService";
45    private static final int BIND_SERVICE_TIMEOUT_SEC = 5;
46
47    private static ServiceConnection mServiceConnection;
48    private static IBinderProxyCountingService mBpcService;
49
50    private IBpcTestAppCmdService.Stub mBinder = new IBpcTestAppCmdService.Stub() {
51
52        private ArrayList<BroadcastReceiver> mBrList = new ArrayList();
53        private ArrayList<ITestRemoteCallback> mTrcList = new ArrayList();
54
55        @Override
56        public void createSystemBinders(int count) {
57            int i = 0;
58            while (i++ < count) {
59                BroadcastReceiver br = new BroadcastReceiver() {
60                    @Override
61                    public void onReceive(Context context, Intent intent) {
62
63                    }
64                };
65                IntentFilter filt = new IntentFilter(Intent.ACTION_POWER_DISCONNECTED);
66                synchronized (mBrList) {
67                    mBrList.add(br);
68                }
69                registerReceiver(br, filt);
70            }
71        }
72
73        @Override
74        public void releaseSystemBinders(int count) {
75            int i = 0;
76            while (i++ < count) {
77                BroadcastReceiver br;
78                synchronized (mBrList) {
79                    br = mBrList.remove(0);
80                }
81                unregisterReceiver(br);
82            }
83        }
84
85        @Override
86        public void createTestBinders(int count) {
87            int i = 0;
88            while (i++ < count) {
89                ITestRemoteCallback cb = new ITestRemoteCallback.Stub() {};
90                synchronized (mTrcList) {
91                    mTrcList.add(cb);
92                }
93                try {
94                    mBpcService.registerCallback(cb);
95                } catch (RemoteException e) {
96                    Log.e(TAG, "RemoteException caught! " + e);
97                }
98            }
99        }
100
101        @Override
102        public void releaseTestBinders(int count) {
103            int i = 0;
104            while (i++ < count) {
105
106                ITestRemoteCallback cb;
107                synchronized (mTrcList) {
108                    cb = mTrcList.remove(0);
109                }
110                try {
111                    mBpcService.unregisterCallback(cb);
112                } catch (RemoteException e) {
113                    Log.e(TAG, "RemoteException caught! " + e);
114                }
115            }
116        }
117
118        @Override
119        public void releaseAllBinders() {
120            synchronized (mBrList) {
121                while (mBrList.size() > 0) {
122                    unregisterReceiver(mBrList.remove(0));
123                }
124            }
125            synchronized (mTrcList) {
126                while (mTrcList.size() > 0) {
127                    try {
128                        mBpcService.unregisterCallback(mTrcList.remove(0));
129                    } catch (RemoteException e) {
130                        Log.e(TAG, "RemoteException caught! " + e);
131                    }
132                }
133            }
134        }
135
136        @Override
137        public String bindToTestService() {
138            try {
139                final CountDownLatch bindLatch = new CountDownLatch(1);
140                mServiceConnection = new ServiceConnection() {
141                    @Override
142                    public void onServiceConnected(ComponentName name, IBinder service) {
143                        Log.i(TAG, "Service connected");
144                        mBpcService = IBinderProxyCountingService.Stub.asInterface(service);
145                        bindLatch.countDown();
146                    }
147
148                    @Override
149                    public void onServiceDisconnected(ComponentName name) {
150                        Log.i(TAG, "Service disconnected");
151                    }
152                };
153                final Intent intent = new Intent()
154                        .setComponent(new ComponentName(TEST_SERVICE_PKG, TEST_SERVICE_CLASS));
155                bindService(intent, mServiceConnection,
156                        Context.BIND_AUTO_CREATE
157                                | Context.BIND_ALLOW_OOM_MANAGEMENT
158                                | Context.BIND_NOT_FOREGROUND);
159                if (!bindLatch.await(BIND_SERVICE_TIMEOUT_SEC, TimeUnit.SECONDS)) {
160                    throw new RuntimeException("Failed to bind to " + TEST_SERVICE_CLASS);
161                }
162            } catch (Exception e) {
163                unbindFromTestService();
164                Log.e(TAG, e.toString());
165                return e.toString();
166            }
167            return null;
168        }
169
170        @Override
171        public void unbindFromTestService() {
172            if (mBpcService != null) {
173                unbindService(mServiceConnection);
174            }
175        }
176    };
177
178    @Override
179    public IBinder onBind(Intent intent) {
180        return mBinder;
181    }
182}