DozeFactory.java revision 4fb1f519787bb20a724370e7f98df3276f6a315a
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
17package com.android.systemui.doze;
18
19import android.app.AlarmManager;
20import android.app.Application;
21import android.app.PendingIntent;
22import android.content.Context;
23import android.hardware.SensorManager;
24import android.os.Handler;
25import android.os.PowerManager;
26import android.os.SystemClock;
27
28import com.android.internal.hardware.AmbientDisplayConfiguration;
29import com.android.systemui.SystemUIApplication;
30import com.android.systemui.plugins.doze.DozeProvider;
31import com.android.systemui.statusbar.phone.DozeParameters;
32
33public class DozeFactory {
34
35    private final DozeProvider mDozePlugin;
36
37    public DozeFactory(DozeProvider plugin) {
38        mDozePlugin = plugin;
39    }
40
41    /** Creates a DozeMachine with its parts for {@code dozeService}. */
42    public DozeMachine assembleMachine(DozeService dozeService) {
43        Context context = dozeService;
44        SensorManager sensorManager = context.getSystemService(SensorManager.class);
45        PowerManager powerManager = context.getSystemService(PowerManager.class);
46        AlarmManager alarmManager = context.getSystemService(AlarmManager.class);
47
48        DozeHost host = getHost(dozeService);
49        AmbientDisplayConfiguration config = new AmbientDisplayConfiguration(context);
50        DozeParameters params = new DozeParameters(context);
51        Handler handler = new Handler();
52        DozeFactory.WakeLock wakeLock = new DozeFactory.WakeLock(powerManager.newWakeLock(
53                PowerManager.PARTIAL_WAKE_LOCK, "Doze"));
54
55        DozeMachine machine = new DozeMachine(dozeService, params, wakeLock);
56        machine.setParts(new DozeMachine.Part[]{
57                createDozeTriggers(context, sensorManager, host, config, params, handler, wakeLock,
58                        machine),
59                createDozeUi(context, host, wakeLock, machine, handler, alarmManager),
60        });
61
62        return machine;
63    }
64
65    private DozeTriggers createDozeTriggers(Context context, SensorManager sensorManager,
66            DozeHost host, AmbientDisplayConfiguration config, DozeParameters params,
67            Handler handler, WakeLock wakeLock, DozeMachine machine) {
68        boolean allowPulseTriggers = mDozePlugin == null || mDozePlugin.allowDefaultPulseTriggers();
69        return new DozeTriggers(context, machine, host, config, params,
70                sensorManager, handler, wakeLock, allowPulseTriggers);
71    }
72
73    private DozeMachine.Part createDozeUi(Context context, DozeHost host, WakeLock wakeLock,
74            DozeMachine machine, Handler handler, AlarmManager alarmManager) {
75        if (mDozePlugin != null) {
76            DozeProvider.DozeUi dozeUi = mDozePlugin.provideDozeUi(context,
77                    pluginMachine(context, machine, host),
78                    wakeLock);
79            return (oldState, newState) -> {
80                dozeUi.transitionTo(pluginState(oldState),
81                        pluginState(newState));
82            };
83        } else {
84            return new DozeUi(context, alarmManager, machine, wakeLock, host, handler);
85        }
86    }
87
88    private DozeProvider.DozeMachine pluginMachine(Context context, DozeMachine machine,
89            DozeHost host) {
90        return new DozeProvider.DozeMachine() {
91            @Override
92            public void requestState(DozeProvider.DozeState state) {
93                if (state == DozeProvider.DozeState.WAKE_UP) {
94                    machine.wakeUp();
95                    return;
96                }
97                machine.requestState(implState(state));
98            }
99
100            @Override
101            public void requestSendIntent(PendingIntent intent) {
102                host.startPendingIntentDismissingKeyguard(intent);
103            }
104        };
105    }
106
107    private DozeMachine.State implState(DozeProvider.DozeState s) {
108        switch (s) {
109            case UNINITIALIZED:
110                return DozeMachine.State.UNINITIALIZED;
111            case INITIALIZED:
112                return DozeMachine.State.INITIALIZED;
113            case DOZE:
114                return DozeMachine.State.DOZE;
115            case DOZE_AOD:
116                return DozeMachine.State.DOZE_AOD;
117            case DOZE_REQUEST_PULSE:
118                return DozeMachine.State.DOZE_REQUEST_PULSE;
119            case DOZE_PULSING:
120                return DozeMachine.State.DOZE_PULSING;
121            case DOZE_PULSE_DONE:
122                return DozeMachine.State.DOZE_PULSE_DONE;
123            case FINISH:
124                return DozeMachine.State.FINISH;
125            default:
126                throw new IllegalArgumentException("Unknown state: " + s);
127        }
128    }
129
130    private DozeProvider.DozeState pluginState(DozeMachine.State s) {
131        switch (s) {
132            case UNINITIALIZED:
133                return DozeProvider.DozeState.UNINITIALIZED;
134            case INITIALIZED:
135                return DozeProvider.DozeState.INITIALIZED;
136            case DOZE:
137                return DozeProvider.DozeState.DOZE;
138            case DOZE_AOD:
139                return DozeProvider.DozeState.DOZE_AOD;
140            case DOZE_REQUEST_PULSE:
141                return DozeProvider.DozeState.DOZE_REQUEST_PULSE;
142            case DOZE_PULSING:
143                return DozeProvider.DozeState.DOZE_PULSING;
144            case DOZE_PULSE_DONE:
145                return DozeProvider.DozeState.DOZE_PULSE_DONE;
146            case FINISH:
147                return DozeProvider.DozeState.FINISH;
148            default:
149                throw new IllegalArgumentException("Unknown state: " + s);
150        }
151    }
152
153    public static DozeHost getHost(DozeService service) {
154        Application appCandidate = service.getApplication();
155        final SystemUIApplication app = (SystemUIApplication) appCandidate;
156        return app.getComponent(DozeHost.class);
157    }
158
159    /** A wrapper around {@link PowerManager.WakeLock} for testability. */
160    public static class WakeLock implements DozeProvider.WakeLock {
161        private final PowerManager.WakeLock mInner;
162
163        public WakeLock(PowerManager.WakeLock inner) {
164            mInner = inner;
165        }
166
167        /** @see PowerManager.WakeLock#acquire() */
168        public void acquire() {
169            mInner.acquire();
170        }
171
172        /** @see PowerManager.WakeLock#release() */
173        public void release() {
174            mInner.release();
175        }
176
177        /** @see PowerManager.WakeLock#wrap(Runnable) */
178        public Runnable wrap(Runnable runnable) {
179            return mInner.wrap(runnable);
180        }
181    }
182}
183