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 if (o instanceof ClientWithRate && 48 mClient == ((ClientWithRate) o).mClient) { 49 return true; 50 } 51 return false; 52 } 53 54 @Override hashCode()55 public int hashCode() { 56 return mClient.hashCode(); 57 } 58 getRate()59 int getRate() { 60 return mRate; 61 } 62 setRate(int rate)63 void setRate(int rate) { 64 mRate = rate; 65 } 66 getClient()67 ClientType getClient() { 68 return mClient; 69 } 70 } 71 72 private final LinkedList<ClientWithRate<ClientType>> mClients = new LinkedList<>(); 73 /** rate sent to car */ 74 private int mRate; 75 Listeners(int rate)76 Listeners(int rate) { 77 mRate = rate; 78 } 79 getRate()80 int getRate() { 81 return mRate; 82 } 83 setRate(int rate)84 void setRate(int rate) { 85 mRate = rate; 86 } 87 88 /** update rate from existing clients and return true if rate is changed. */ updateRate()89 boolean updateRate() { 90 //TODO(egranata): we might need to support other rate ranges 91 int fastestRate = CarSensorManager.SENSOR_RATE_NORMAL; 92 for (ClientWithRate<ClientType> clientWithRate: mClients) { 93 int clientRate = clientWithRate.getRate(); 94 if (clientRate < fastestRate) { 95 fastestRate = clientRate; 96 } 97 } 98 if (mRate != fastestRate) { 99 mRate = fastestRate; 100 return true; 101 } 102 return false; 103 } 104 addClientWithRate(ClientWithRate<ClientType> clientWithRate)105 void addClientWithRate(ClientWithRate<ClientType> clientWithRate) { 106 mClients.add(clientWithRate); 107 } 108 removeClientWithRate(ClientWithRate<ClientType> clientWithRate)109 void removeClientWithRate(ClientWithRate<ClientType> clientWithRate) { 110 mClients.remove(clientWithRate); 111 } 112 getNumberOfClients()113 int getNumberOfClients() { 114 return mClients.size(); 115 } 116 getClients()117 Iterable<ClientWithRate<ClientType>> getClients() { 118 return mClients; 119 } 120 findClientWithRate(ClientType client)121 ClientWithRate<ClientType> findClientWithRate(ClientType client) { 122 for (ClientWithRate<ClientType> clientWithRate: mClients) { 123 if (clientWithRate.getClient() == client) { 124 return clientWithRate; 125 } 126 } 127 return null; 128 } 129 release()130 void release() { 131 for (ClientWithRate<ClientType> clientWithRate: mClients) { 132 clientWithRate.getClient().release(); 133 } 134 mClients.clear(); 135 } 136 } 137