1 /* 2 * Copyright (C) 2015 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 android.car; 18 19 import static android.car.CarLibLog.TAG_CAR; 20 21 import android.annotation.Nullable; 22 import android.app.Activity; 23 import android.car.annotation.AddedInOrBefore; 24 import android.content.Context; 25 import android.os.Handler; 26 import android.os.RemoteException; 27 import android.util.Dumpable; 28 import android.util.DumpableContainer; 29 import android.util.Log; 30 31 import java.util.function.Supplier; 32 33 /** 34 * Common base class for Car*Manager 35 * @hide 36 */ 37 public abstract class CarManagerBase { 38 39 private static final boolean DEBUG = Log.isLoggable(TAG_CAR, Log.DEBUG); 40 41 @AddedInOrBefore(majorVersion = 33) 42 protected final Car mCar; 43 CarManagerBase(Car car)44 public CarManagerBase(Car car) { 45 mCar = car; 46 } 47 48 @AddedInOrBefore(majorVersion = 33) getContext()49 protected Context getContext() { 50 return mCar.getContext(); 51 } 52 53 @AddedInOrBefore(majorVersion = 33) getEventHandler()54 protected Handler getEventHandler() { 55 return mCar.getEventHandler(); 56 } 57 58 @AddedInOrBefore(majorVersion = 33) handleRemoteExceptionFromCarService(RemoteException e, T returnValue)59 protected <T> T handleRemoteExceptionFromCarService(RemoteException e, T returnValue) { 60 return mCar.handleRemoteExceptionFromCarService(e, returnValue); 61 } 62 63 @AddedInOrBefore(majorVersion = 33) handleRemoteExceptionFromCarService(RemoteException e)64 protected void handleRemoteExceptionFromCarService(RemoteException e) { 65 mCar.handleRemoteExceptionFromCarService(e); 66 } 67 68 /** 69 * Handles runtime and remote exception from CarService. 70 */ 71 @AddedInOrBefore(majorVersion = 33) handleExceptionFromCarService(Exception e, T returnValue)72 protected <T> T handleExceptionFromCarService(Exception e, T returnValue) { 73 if (e instanceof RemoteException) { 74 return handleRemoteExceptionFromCarService((RemoteException) e, returnValue); 75 } 76 77 if (e instanceof RuntimeException) { 78 Log.w(TAG_CAR, "Car service threw Runtime Exception.", e); 79 return returnValue; 80 } 81 82 // exception should be either runtime or remote exception 83 Log.wtf(TAG_CAR, "Car service threw Exception.", e); 84 85 return returnValue; 86 } 87 88 /** 89 * Handle disconnection of car service (=crash). As car service has crashed already, this call 90 * should only clean up any listeners / callbacks passed from client. Clearing object passed 91 * to car service is not necessary as car service has crashed. Note that Car*Manager will not 92 * work any more as all binders are invalid. Client should re-create all Car*Managers when 93 * car service is restarted. 94 */ 95 @AddedInOrBefore(majorVersion = 33) onCarDisconnected()96 protected abstract void onCarDisconnected(); 97 98 /** 99 * Adds a {@link Dumpable} to a "compatible" container (i.e., an object that extends 100 * {@link DumpableContainer}, {@code Activity}, etc...). 101 * 102 * @return supplied dumpable, or {@code null} if {@code container} is not compatible. 103 */ 104 @Nullable 105 @AddedInOrBefore(majorVersion = 33) addDumpable(Object container, Supplier<T> dumpableSupplier)106 protected <T extends Dumpable> T addDumpable(Object container, Supplier<T> dumpableSupplier) { 107 if (container instanceof Activity) { 108 T dumpable = dumpableSupplier.get(); 109 if (DEBUG) { 110 Log.d(TAG_CAR, "Adding " + dumpable.getDumpableName() + " to actvity " + container); 111 } 112 ((Activity) container).addDumpable(dumpable); 113 return dumpable; 114 } 115 if (container instanceof DumpableContainer) { 116 T dumpable = dumpableSupplier.get(); 117 if (DEBUG) { 118 Log.d(TAG_CAR, "Adding " + dumpable.getDumpableName() + " to DumpableContainer " 119 + container); 120 } 121 ((DumpableContainer) container).addDumpable(dumpable); 122 return dumpable; 123 } 124 Log.v(TAG_CAR, "NOT adding dumpable to object (" + container 125 + ") that doesn't implement addDumpable"); 126 return null; 127 } 128 } 129