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