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