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 17 package com.android.car; 18 19 import android.car.hardware.CarSensorManager; 20 import android.os.IBinder; 21 22 import java.util.LinkedList; 23 24 /** 25 * This class wraps a set of listeners of a given type of event, grouped by event-transmission rate. 26 * This is logic that is common to different services that need to receive and rebroadcast events. 27 * @param <ClientType> The type of event listener. 28 */ 29 public class Listeners<ClientType extends com.android.car.Listeners.IListener> { 30 public interface IListener extends IBinder.DeathRecipient { release()31 void release(); 32 } 33 34 public static class ClientWithRate<ClientType extends IListener> { 35 private final ClientType mClient; 36 /** rate requested from client */ 37 private int mRate; 38 ClientWithRate(ClientType client, int rate)39 ClientWithRate(ClientType client, int rate) { 40 mClient = client; 41 mRate = rate; 42 } 43 44 @Override equals(Object o)45 public boolean equals(Object o) { 46 //TODO(egranata): is this truly necessary? 47 return (o instanceof ClientWithRate) && mClient == ((ClientWithRate) o).mClient; 48 } 49 50 @Override hashCode()51 public int hashCode() { 52 return mClient.hashCode(); 53 } 54 getRate()55 int getRate() { 56 return mRate; 57 } 58 setRate(int rate)59 void setRate(int rate) { 60 mRate = rate; 61 } 62 getClient()63 ClientType getClient() { 64 return mClient; 65 } 66 } 67 68 private final LinkedList<ClientWithRate<ClientType>> mClients = new LinkedList<>(); 69 /** rate sent to car */ 70 private int mRate; 71 Listeners(int rate)72 Listeners(int rate) { 73 mRate = rate; 74 } 75 getRate()76 int getRate() { 77 return mRate; 78 } 79 setRate(int rate)80 void setRate(int rate) { 81 mRate = rate; 82 } 83 84 /** update rate from existing clients and return true if rate is changed. */ updateRate()85 boolean updateRate() { 86 //TODO(egranata): we might need to support other rate ranges 87 int fastestRate = CarSensorManager.SENSOR_RATE_NORMAL; 88 for (ClientWithRate<ClientType> clientWithRate: mClients) { 89 int clientRate = clientWithRate.getRate(); 90 if (clientRate < fastestRate) { 91 fastestRate = clientRate; 92 } 93 } 94 if (mRate != fastestRate) { 95 mRate = fastestRate; 96 return true; 97 } 98 return false; 99 } 100 addClientWithRate(ClientWithRate<ClientType> clientWithRate)101 void addClientWithRate(ClientWithRate<ClientType> clientWithRate) { 102 mClients.add(clientWithRate); 103 } 104 removeClientWithRate(ClientWithRate<ClientType> clientWithRate)105 void removeClientWithRate(ClientWithRate<ClientType> clientWithRate) { 106 mClients.remove(clientWithRate); 107 } 108 getNumberOfClients()109 int getNumberOfClients() { 110 return mClients.size(); 111 } 112 getClients()113 Iterable<ClientWithRate<ClientType>> getClients() { 114 return mClients; 115 } 116 findClientWithRate(ClientType client)117 ClientWithRate<ClientType> findClientWithRate(ClientType client) { 118 for (ClientWithRate<ClientType> clientWithRate: mClients) { 119 if (clientWithRate.getClient() == client) { 120 return clientWithRate; 121 } 122 } 123 return null; 124 } 125 release()126 void release() { 127 for (ClientWithRate<ClientType> clientWithRate: mClients) { 128 clientWithRate.getClient().release(); 129 } 130 mClients.clear(); 131 } 132 } 133