1 /*
2  * Copyright (C) 2018 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.systemui.doze;
18 
19 import android.hardware.display.AmbientDisplayConfiguration;
20 import android.os.UserHandle;
21 import android.util.Log;
22 
23 import com.android.systemui.dock.DockManager;
24 import com.android.systemui.doze.DozeMachine.State;
25 import com.android.systemui.doze.dagger.DozeScope;
26 
27 import java.io.PrintWriter;
28 
29 import javax.inject.Inject;
30 
31 /**
32  * Handles dock events for ambient state changes.
33  */
34 @DozeScope
35 public class DozeDockHandler implements DozeMachine.Part {
36 
37     private static final String TAG = "DozeDockHandler";
38     private static final boolean DEBUG = DozeService.DEBUG;
39 
40     private final AmbientDisplayConfiguration mConfig;
41     private DozeMachine mMachine;
42     private final DockManager mDockManager;
43     private final DockEventListener mDockEventListener;
44 
45     private int mDockState = DockManager.STATE_NONE;
46 
47     @Inject
DozeDockHandler(AmbientDisplayConfiguration config, DockManager dockManager)48     DozeDockHandler(AmbientDisplayConfiguration config, DockManager dockManager) {
49         mConfig = config;
50         mDockManager = dockManager;
51         mDockEventListener = new DockEventListener();
52     }
53 
54     @Override
setDozeMachine(DozeMachine dozeMachine)55     public void setDozeMachine(DozeMachine dozeMachine) {
56         mMachine = dozeMachine;
57     }
58 
59     @Override
transitionTo(DozeMachine.State oldState, DozeMachine.State newState)60     public void transitionTo(DozeMachine.State oldState, DozeMachine.State newState) {
61         switch (newState) {
62             case INITIALIZED:
63                 mDockEventListener.register();
64                 break;
65             case FINISH:
66                 mDockEventListener.unregister();
67                 break;
68             default:
69                 // no-op
70         }
71     }
72 
73     @Override
dump(PrintWriter pw)74     public void dump(PrintWriter pw) {
75         pw.println("DozeDockHandler:");
76         pw.println(" dockState=" + mDockState);
77     }
78 
79     private class DockEventListener implements DockManager.DockEventListener {
80         private boolean mRegistered;
81 
82         @Override
onEvent(int dockState)83         public void onEvent(int dockState) {
84             if (DEBUG) Log.d(TAG, "dock event = " + dockState);
85 
86             // Only act upon state changes, otherwise we might overwrite other transitions,
87             // like proximity sensor initialization.
88             if (mDockState == dockState) {
89                 return;
90             }
91 
92             mDockState = dockState;
93             if (isPulsing()) {
94                 return;
95             }
96 
97             DozeMachine.State nextState;
98             switch (mDockState) {
99                 case DockManager.STATE_DOCKED:
100                     nextState = State.DOZE_AOD_DOCKED;
101                     break;
102                 case DockManager.STATE_NONE:
103                     nextState = mConfig.alwaysOnEnabled(UserHandle.USER_CURRENT) ? State.DOZE_AOD
104                             : State.DOZE;
105                     break;
106                 case DockManager.STATE_DOCKED_HIDE:
107                     nextState = State.DOZE;
108                     break;
109                 default:
110                     return;
111             }
112             mMachine.requestState(nextState);
113         }
114 
isPulsing()115         private boolean isPulsing() {
116             DozeMachine.State state = mMachine.getState();
117             return state == State.DOZE_REQUEST_PULSE || state == State.DOZE_PULSING
118                     || state == State.DOZE_PULSING_BRIGHT;
119         }
120 
register()121         void register() {
122             if (mRegistered) {
123                 return;
124             }
125             if (mDockManager != null) {
126                 mDockManager.addListener(this);
127             }
128             mRegistered = true;
129         }
130 
unregister()131         void unregister() {
132             if (!mRegistered) {
133                 return;
134             }
135             if (mDockManager != null) {
136                 mDockManager.removeListener(this);
137             }
138             mRegistered = false;
139         }
140     }
141 }
142