Home | History | Annotate | Download | only in renderer
      1 /*
      2  * Copyright (C) 2016 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 package com.android.car.cluster.renderer;
     17 
     18 import android.annotation.Nullable;
     19 import android.car.cluster.renderer.NavigationRenderer;
     20 import android.graphics.Bitmap;
     21 import android.os.Handler;
     22 import android.os.Looper;
     23 import android.os.Message;
     24 
     25 /**
     26  * A wrapper over {@link NavigationRenderer} that runs all its methods in the context of provided
     27  * looper. It is guaranteed that all calls will be invoked in order they were called.
     28  */
     29 public class ThreadSafeNavigationRenderer extends NavigationRenderer {
     30 
     31     private final Handler mHandler;
     32 
     33     private final static int MSG_NAV_START = 1;
     34     private final static int MSG_NAV_STOP = 2;
     35     private final static int MSG_NAV_NEXT_TURN = 3;
     36     private final static int MSG_NAV_NEXT_TURN_DISTANCE = 4;
     37 
     38     /** Creates thread-safe {@link NavigationRenderer}. Returns null if renderer == null */
     39     @Nullable
     40     public static NavigationRenderer createFor(Looper looper, NavigationRenderer renderer) {
     41         return renderer == null ? null : new ThreadSafeNavigationRenderer(looper, renderer);
     42     }
     43 
     44     private ThreadSafeNavigationRenderer(Looper looper, NavigationRenderer renderer) {
     45         mHandler = new NavigationRendererHandler(looper, renderer);
     46     }
     47 
     48     @Override
     49     public void onStartNavigation() {
     50         mHandler.sendMessage(mHandler.obtainMessage(MSG_NAV_START));
     51     }
     52 
     53     @Override
     54     public void onStopNavigation() {
     55         mHandler.sendMessage(mHandler.obtainMessage(MSG_NAV_STOP));
     56     }
     57 
     58     @Override
     59     public void onNextTurnChanged(int event, String road, int turnAngle, int turnNumber,
     60             Bitmap image, int turnSide) {
     61         mHandler.sendMessage(mHandler.obtainMessage(MSG_NAV_NEXT_TURN,
     62                 new NextTurn(event, road, turnAngle, turnNumber, image, turnSide)));
     63     }
     64 
     65     @Override
     66     public void onNextTurnDistanceChanged(int distanceMeters, int timeSeconds) {
     67         mHandler.sendMessage(mHandler.obtainMessage(
     68                     MSG_NAV_NEXT_TURN_DISTANCE, distanceMeters, timeSeconds));
     69     }
     70 
     71     private static class NavigationRendererHandler extends RendererHandler<NavigationRenderer> {
     72 
     73         NavigationRendererHandler(Looper looper, NavigationRenderer renderer) {
     74             super(looper, renderer);
     75         }
     76 
     77         @Override
     78         public void handleMessage(Message msg, NavigationRenderer renderer) {
     79 
     80             switch (msg.what) {
     81                 case MSG_NAV_START:
     82                     renderer.onStartNavigation();
     83                     break;
     84                 case MSG_NAV_STOP:
     85                     renderer.onStopNavigation();
     86                     break;
     87                 case MSG_NAV_NEXT_TURN:
     88                     NextTurn nt = (NextTurn) msg.obj;
     89                     renderer.onNextTurnChanged(nt.event, nt.road, nt.turnAngle, nt.turnNumber,
     90                             nt.bitmap, nt.turnSide);
     91                     break;
     92                 case MSG_NAV_NEXT_TURN_DISTANCE:
     93                     renderer.onNextTurnDistanceChanged(msg.arg1, msg.arg2);
     94                     break;
     95                 default:
     96                     throw new IllegalArgumentException("Msg: " + msg.what);
     97             }
     98         }
     99     }
    100 
    101     private static class NextTurn {
    102         private final int event;
    103         private final String road;
    104         private final int turnAngle;
    105         private final int turnNumber;
    106         private final Bitmap bitmap;
    107         private final int turnSide;
    108 
    109         NextTurn(int event, String road, int turnAngle, int turnNumber, Bitmap bitmap,
    110                 int turnSide) {
    111             this.event = event;
    112             this.road = road;
    113             this.turnAngle = turnAngle;
    114             this.turnNumber = turnNumber;
    115             this.bitmap = bitmap;
    116             this.turnSide = turnSide;
    117         }
    118     }
    119 }
    120