Home | History | Annotate | Download | only in car
      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;
     17 
     18 import android.os.Handler;
     19 import android.os.Message;
     20 import android.util.Log;
     21 
     22 import com.android.internal.annotations.GuardedBy;
     23 import com.android.internal.annotations.VisibleForTesting;
     24 
     25 import java.lang.ref.WeakReference;
     26 
     27 /**
     28 * An wrapper class that can be backed by a real DeviceIdleController or a mocked one.
     29 */
     30 public abstract class DeviceIdleControllerWrapper {
     31     private static final String TAG = "Garage_DeviceIdleWrapper";
     32 
     33     private static final int MSG_REPORT_ACTIVE = 1;
     34 
     35     @VisibleForTesting
     36     protected WeakReference<DeviceMaintenanceActivityListener> mListener;
     37 
     38     public interface DeviceMaintenanceActivityListener {
     39         public void onMaintenanceActivityChanged(boolean active);
     40     }
     41     private final Object mLock = new Object();
     42     @GuardedBy("mLock")
     43     private boolean mActive;
     44 
     45     private Handler mHandler = new IdleControllerHandler();
     46 
     47     private class IdleControllerHandler extends Handler {
     48         @Override
     49         public void handleMessage(Message msg) {
     50             switch (msg.what) {
     51                 case MSG_REPORT_ACTIVE:
     52                     boolean active  = msg.arg1 == 1;
     53                     if (mListener.get() != null) {
     54                         mListener.get().onMaintenanceActivityChanged(active);
     55                     }
     56                     break;
     57             }
     58         }
     59     }
     60 
     61     public boolean startTracking(DeviceMaintenanceActivityListener listener) {
     62         synchronized (mLock) {
     63             mListener = new WeakReference<DeviceMaintenanceActivityListener>(listener);
     64             mActive = startLocked();
     65             return mActive;
     66         }
     67     }
     68 
     69     protected abstract boolean startLocked();
     70 
     71     public abstract void stopTracking();
     72 
     73     @VisibleForTesting
     74     protected void reportActiveLocked(final boolean active) {
     75         // post to a handler instead of calling the callback directly to avoid potential deadlock.
     76         mHandler.sendMessage(mHandler.obtainMessage(MSG_REPORT_ACTIVE, active ? 1 : 0, 0));
     77     }
     78 
     79     @VisibleForTesting
     80     protected void setMaintenanceActivity(final boolean active) {
     81         synchronized (mLock) {
     82             if (mActive == active) {
     83                 return;
     84             }
     85             mActive = active;
     86 
     87             if (mListener.get() == null) {
     88                 // do cleanup if the listener has gone and did not call release.
     89                 stopTracking();
     90                 return;
     91             }
     92             reportActiveLocked(active);
     93         }
     94     }
     95 }
     96