blob: ed6424cb4a305c932f1062969b2aba2da7cdce1c [file] [log] [blame]
Neil Fullerb5579072018-05-30 14:35:24 +01001/*
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
17package com.android.server.timedetector;
18
Neil Fuller4773b9d2018-06-08 18:44:49 +010019import android.annotation.NonNull;
20import android.annotation.Nullable;
21import android.app.timedetector.ITimeDetectorService;
Neil Fuller3aedd492019-11-23 11:33:57 +000022import android.app.timedetector.ManualTimeSuggestion;
Neil Fuller4ab8a192019-12-16 16:54:06 +000023import android.app.timedetector.NetworkTimeSuggestion;
Neil Fullerc0d59e32020-02-04 14:30:06 +000024import android.app.timedetector.TelephonyTimeSuggestion;
Neil Fuller4980bbc2018-06-12 21:06:20 +010025import android.content.ContentResolver;
Neil Fuller4773b9d2018-06-08 18:44:49 +010026import android.content.Context;
Neil Fuller4980bbc2018-06-12 21:06:20 +010027import android.database.ContentObserver;
Neil Fuller40cf2952019-11-28 09:47:30 +000028import android.os.Handler;
Neil Fuller4980bbc2018-06-12 21:06:20 +010029import android.provider.Settings;
Neil Fuller4773b9d2018-06-08 18:44:49 +010030
31import com.android.internal.annotations.VisibleForTesting;
Neil Fullerb5579072018-05-30 14:35:24 +010032import com.android.internal.util.DumpUtils;
Neil Fuller4980bbc2018-06-12 21:06:20 +010033import com.android.server.FgThread;
Neil Fullerb5579072018-05-30 14:35:24 +010034import com.android.server.SystemService;
35
Neil Fullerb5579072018-05-30 14:35:24 +010036import java.io.FileDescriptor;
37import java.io.PrintWriter;
Neil Fuller4773b9d2018-06-08 18:44:49 +010038import java.util.Objects;
Neil Fullerb5579072018-05-30 14:35:24 +010039
Neil Fullercce4dcd2020-02-04 15:51:58 +000040/**
41 * The implementation of ITimeDetectorService.aidl.
42 */
Neil Fullerb5579072018-05-30 14:35:24 +010043public final class TimeDetectorService extends ITimeDetectorService.Stub {
Neil Fuller40cf2952019-11-28 09:47:30 +000044 private static final String TAG = "TimeDetectorService";
Neil Fullerb5579072018-05-30 14:35:24 +010045
46 public static class Lifecycle extends SystemService {
47
Neil Fuller4980bbc2018-06-12 21:06:20 +010048 public Lifecycle(@NonNull Context context) {
Neil Fullerb5579072018-05-30 14:35:24 +010049 super(context);
50 }
51
52 @Override
53 public void onStart() {
54 TimeDetectorService service = TimeDetectorService.create(getContext());
55
56 // Publish the binder service so it can be accessed from other (appropriately
57 // permissioned) processes.
58 publishBinderService(Context.TIME_DETECTOR_SERVICE, service);
59 }
60 }
61
Neil Fuller40cf2952019-11-28 09:47:30 +000062 @NonNull private final Handler mHandler;
Neil Fuller4980bbc2018-06-12 21:06:20 +010063 @NonNull private final Context mContext;
Neil Fuller4980bbc2018-06-12 21:06:20 +010064 @NonNull private final TimeDetectorStrategy mTimeDetectorStrategy;
65
66 private static TimeDetectorService create(@NonNull Context context) {
Neil Fuller19b4e5a2019-12-09 16:55:28 +000067 TimeDetectorStrategy timeDetectorStrategy = new TimeDetectorStrategyImpl();
Neil Fuller40cf2952019-11-28 09:47:30 +000068 TimeDetectorStrategyCallbackImpl callback = new TimeDetectorStrategyCallbackImpl(context);
Neil Fuller19b4e5a2019-12-09 16:55:28 +000069 timeDetectorStrategy.initialize(callback);
Neil Fuller4980bbc2018-06-12 21:06:20 +010070
Neil Fuller40cf2952019-11-28 09:47:30 +000071 Handler handler = FgThread.getHandler();
Neil Fuller4980bbc2018-06-12 21:06:20 +010072 TimeDetectorService timeDetectorService =
Neil Fuller19b4e5a2019-12-09 16:55:28 +000073 new TimeDetectorService(context, handler, timeDetectorStrategy);
Neil Fuller4980bbc2018-06-12 21:06:20 +010074
75 // Wire up event listening.
76 ContentResolver contentResolver = context.getContentResolver();
77 contentResolver.registerContentObserver(
78 Settings.Global.getUriFor(Settings.Global.AUTO_TIME), true,
Neil Fuller40cf2952019-11-28 09:47:30 +000079 new ContentObserver(handler) {
Neil Fuller4980bbc2018-06-12 21:06:20 +010080 public void onChange(boolean selfChange) {
Neil Fullercce4dcd2020-02-04 15:51:58 +000081 timeDetectorService.handleAutoTimeDetectionChanged();
Neil Fuller4980bbc2018-06-12 21:06:20 +010082 }
83 });
84
85 return timeDetectorService;
Neil Fullerb5579072018-05-30 14:35:24 +010086 }
87
Neil Fuller4773b9d2018-06-08 18:44:49 +010088 @VisibleForTesting
Neil Fuller40cf2952019-11-28 09:47:30 +000089 public TimeDetectorService(@NonNull Context context, @NonNull Handler handler,
Neil Fuller19b4e5a2019-12-09 16:55:28 +000090 @NonNull TimeDetectorStrategy timeDetectorStrategy) {
Neil Fuller4773b9d2018-06-08 18:44:49 +010091 mContext = Objects.requireNonNull(context);
Neil Fuller40cf2952019-11-28 09:47:30 +000092 mHandler = Objects.requireNonNull(handler);
Neil Fuller4773b9d2018-06-08 18:44:49 +010093 mTimeDetectorStrategy = Objects.requireNonNull(timeDetectorStrategy);
Neil Fullerb5579072018-05-30 14:35:24 +010094 }
95
96 @Override
Neil Fullerc0d59e32020-02-04 14:30:06 +000097 public void suggestTelephonyTime(@NonNull TelephonyTimeSuggestion timeSignal) {
98 enforceSuggestTelephonyTimePermission();
Neil Fuller4980bbc2018-06-12 21:06:20 +010099 Objects.requireNonNull(timeSignal);
Neil Fuller185a29a2018-06-13 16:56:38 +0100100
Neil Fullerc0d59e32020-02-04 14:30:06 +0000101 mHandler.post(() -> mTimeDetectorStrategy.suggestTelephonyTime(timeSignal));
Neil Fuller4980bbc2018-06-12 21:06:20 +0100102 }
103
Neil Fuller3aedd492019-11-23 11:33:57 +0000104 @Override
105 public void suggestManualTime(@NonNull ManualTimeSuggestion timeSignal) {
106 enforceSuggestManualTimePermission();
107 Objects.requireNonNull(timeSignal);
108
Neil Fuller40cf2952019-11-28 09:47:30 +0000109 mHandler.post(() -> mTimeDetectorStrategy.suggestManualTime(timeSignal));
Neil Fuller3aedd492019-11-23 11:33:57 +0000110 }
111
Neil Fuller4ab8a192019-12-16 16:54:06 +0000112 @Override
113 public void suggestNetworkTime(@NonNull NetworkTimeSuggestion timeSignal) {
114 enforceSuggestNetworkTimePermission();
115 Objects.requireNonNull(timeSignal);
116
117 mHandler.post(() -> mTimeDetectorStrategy.suggestNetworkTime(timeSignal));
118 }
119
Neil Fullercce4dcd2020-02-04 15:51:58 +0000120 /** Internal method for handling the auto time setting being changed. */
Neil Fuller4980bbc2018-06-12 21:06:20 +0100121 @VisibleForTesting
Neil Fullercce4dcd2020-02-04 15:51:58 +0000122 public void handleAutoTimeDetectionChanged() {
Neil Fuller40cf2952019-11-28 09:47:30 +0000123 mHandler.post(mTimeDetectorStrategy::handleAutoTimeDetectionChanged);
Neil Fullerb5579072018-05-30 14:35:24 +0100124 }
125
126 @Override
Neil Fuller4773b9d2018-06-08 18:44:49 +0100127 protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw,
128 @Nullable String[] args) {
Neil Fullerb5579072018-05-30 14:35:24 +0100129 if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
130
Neil Fuller40cf2952019-11-28 09:47:30 +0000131 mTimeDetectorStrategy.dump(pw, args);
Neil Fuller4773b9d2018-06-08 18:44:49 +0100132 }
133
Neil Fullerc0d59e32020-02-04 14:30:06 +0000134 private void enforceSuggestTelephonyTimePermission() {
Neil Fuller09e8b7d2019-11-21 13:11:04 +0000135 mContext.enforceCallingPermission(
Neil Fullerc0d59e32020-02-04 14:30:06 +0000136 android.Manifest.permission.SUGGEST_TELEPHONY_TIME_AND_ZONE,
137 "suggest telephony time and time zone");
Neil Fullerb5579072018-05-30 14:35:24 +0100138 }
Neil Fuller3aedd492019-11-23 11:33:57 +0000139
140 private void enforceSuggestManualTimePermission() {
Neil Fuller09e8b7d2019-11-21 13:11:04 +0000141 mContext.enforceCallingOrSelfPermission(
142 android.Manifest.permission.SUGGEST_MANUAL_TIME_AND_ZONE,
143 "suggest manual time and time zone");
Neil Fuller3aedd492019-11-23 11:33:57 +0000144 }
Neil Fuller4ab8a192019-12-16 16:54:06 +0000145
146 private void enforceSuggestNetworkTimePermission() {
147 mContext.enforceCallingOrSelfPermission(
148 android.Manifest.permission.SET_TIME,
149 "set time");
150 }
Neil Fuller3aedd492019-11-23 11:33:57 +0000151}