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