Home | History | Annotate | Download | only in car
      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  The type of event listener.
     27  */
     28 public class Listeners<ClientType extends com.android.car.Listeners.IListener> {
     29     public interface IListener extends IBinder.DeathRecipient {
     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 
     38         ClientWithRate(ClientType client, int rate) {
     39             mClient = client;
     40             mRate = rate;
     41         }
     42 
     43         @Override
     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
     54         public int hashCode() {
     55             return mClient.hashCode();
     56         }
     57 
     58         int getRate() {
     59             return mRate;
     60         }
     61 
     62         void setRate(int rate) {
     63             mRate = rate;
     64         }
     65 
     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 
     75     Listeners(int rate) {
     76         mRate = rate;
     77     }
     78 
     79     int getRate() {
     80         return mRate;
     81     }
     82 
     83     void setRate(int rate) {
     84         mRate = rate;
     85     }
     86 
     87     /** update rate from existing clients and return true if rate is changed. */
     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 
    104     void addClientWithRate(ClientWithRate<ClientType> clientWithRate) {
    105         mClients.add(clientWithRate);
    106     }
    107 
    108     void removeClientWithRate(ClientWithRate<ClientType> clientWithRate) {
    109         mClients.remove(clientWithRate);
    110     }
    111 
    112     int getNumberOfClients() {
    113         return mClients.size();
    114     }
    115 
    116     Iterable<ClientWithRate<ClientType>> getClients() {
    117         return mClients;
    118     }
    119 
    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 
    129     void release() {
    130         for (ClientWithRate<ClientType> clientWithRate: mClients) {
    131             clientWithRate.getClient().release();
    132         }
    133         mClients.clear();
    134     }
    135 }
    136