1 /* 2 * Copyright (C) 2021 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.settings.common; 18 19 import android.car.Car; 20 import android.car.hardware.power.CarPowerManager; 21 import android.car.hardware.power.CarPowerPolicy; 22 import android.car.hardware.power.CarPowerPolicyFilter; 23 import android.content.Context; 24 25 import androidx.annotation.NonNull; 26 import androidx.annotation.Nullable; 27 28 import java.util.concurrent.Executor; 29 30 /** 31 * Listens to power policy change and executes the registered handler. 32 * 33 * <p>{@link android.car.Car} instance and {@link android.car.hardware.power.CarPowerManager} 34 * instances are managed internally, so the callers doesn't have to care about creating/destroying 35 * them. 36 */ 37 public final class PowerPolicyListener { 38 39 private static final Logger LOG = new Logger(PowerPolicyListener.class); 40 41 private final Executor mExecutor; 42 private final PolicyChangeHandler mPolicyChangeHandler; 43 private final CarPowerManager.CarPowerPolicyListener mPolicyListener = 44 new CarPowerManager.CarPowerPolicyListener() { 45 @Override 46 public void onPolicyChanged(@NonNull CarPowerPolicy policy) { 47 mPolicyChangeHandler.handlePolicyChange(policy.isComponentEnabled(mComponent)); 48 } 49 }; 50 @Nullable private Car mCar; 51 @Nullable private CarPowerManager mCarPowerManager; 52 private int mComponent; 53 54 /** 55 * Handlers which is called when the given component's power state is changed by power policy. 56 */ 57 public interface PolicyChangeHandler { 58 /** Called when a power policy changes around the given component */ handlePolicyChange(boolean isOn)59 void handlePolicyChange(boolean isOn); 60 } 61 PowerPolicyListener(Context context, int component, PolicyChangeHandler handler)62 public PowerPolicyListener(Context context, int component, PolicyChangeHandler handler) { 63 mComponent = component; 64 mPolicyChangeHandler = handler; 65 mExecutor = context.getMainExecutor(); 66 Car.createCar(context, null, Car.CAR_WAIT_TIMEOUT_WAIT_FOREVER, 67 (car, ready) -> { 68 if (ready) { 69 LOG.d("Connected to the Car Service"); 70 mCar = car; 71 CarPowerPolicyFilter filter = new CarPowerPolicyFilter.Builder() 72 .setComponents(component).build(); 73 mCarPowerManager = (CarPowerManager) mCar.getCarManager(Car.POWER_SERVICE); 74 if (mCarPowerManager != null) { 75 mCarPowerManager.addPowerPolicyListener(mExecutor, filter, 76 mPolicyListener); 77 } 78 } else { 79 LOG.d("Disconnected from the Car Service"); 80 mCar = null; 81 mCarPowerManager = null; 82 } 83 }); 84 } 85 86 /** 87 * Unregisters a power policy listener from {@link android.car.hardware.power.CarPowerManager} 88 * and disconnects from {@link android.car.Car}. 89 */ release()90 public void release() { 91 if (mCarPowerManager != null) { 92 mCarPowerManager.removePowerPolicyListener(mPolicyListener); 93 } 94 try { 95 if (mCar != null) { 96 mCar.disconnect(); 97 } 98 } catch (IllegalStateException e) { 99 // Do nothing. 100 LOG.w("release(): cannot disconnect from Car"); 101 } 102 } 103 104 /** 105 * Executes the registered handler with the current power policy. 106 */ handleCurrentPolicy()107 public void handleCurrentPolicy() { 108 if (mCarPowerManager == null) { 109 LOG.w("CarPowerManager is not available"); 110 return; 111 } 112 CarPowerPolicy policy = mCarPowerManager.getCurrentPowerPolicy(); 113 if (policy != null) { 114 mPolicyChangeHandler.handlePolicyChange(policy.isComponentEnabled(mComponent)); 115 } 116 } 117 118 /** 119 * Gets the registered {@link PolicyChangeHandler}. 120 */ getPolicyChangeHandler()121 public PolicyChangeHandler getPolicyChangeHandler() { 122 return mPolicyChangeHandler; 123 } 124 } 125