• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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.car.settings.datetime;
18 
19 import android.app.timedetector.ManualTimeSuggestion;
20 import android.app.timedetector.TimeDetector;
21 import android.car.drivingstate.CarUxRestrictions;
22 import android.content.Intent;
23 import android.os.Bundle;
24 import android.text.format.DateFormat;
25 import android.view.ViewGroup;
26 import android.widget.NumberPicker;
27 import android.widget.TimePicker;
28 
29 import androidx.annotation.LayoutRes;
30 import androidx.annotation.StringRes;
31 
32 import com.android.car.settings.R;
33 import com.android.car.settings.common.BaseFragment;
34 import com.android.car.settings.common.rotary.DirectManipulationHandler;
35 import com.android.car.settings.common.rotary.DirectManipulationState;
36 import com.android.car.settings.common.rotary.NumberPickerNudgeHandler;
37 import com.android.car.settings.common.rotary.NumberPickerRotationHandler;
38 import com.android.car.settings.common.rotary.NumberPickerUtils;
39 import com.android.car.ui.toolbar.MenuItem;
40 
41 import java.util.ArrayList;
42 import java.util.Calendar;
43 import java.util.Collections;
44 import java.util.List;
45 
46 /**
47  * Sets the system time.
48  */
49 public class TimePickerFragment extends BaseFragment {
50     private static final int MILLIS_IN_SECOND = 1000;
51 
52     private DirectManipulationState mDirectManipulationMode;
53     private TimePicker mTimePicker;
54     private List<NumberPicker> mNumberPickers;
55     private MenuItem mOkButton;
56 
57     @Override
getToolbarMenuItems()58     public List<MenuItem> getToolbarMenuItems() {
59         return Collections.singletonList(mOkButton);
60     }
61 
62     @Override
onCreate(Bundle savedInstanceState)63     public void onCreate(Bundle savedInstanceState) {
64         super.onCreate(savedInstanceState);
65 
66         mOkButton = new MenuItem.Builder(getContext())
67                 .setTitle(android.R.string.ok)
68                 .setOnClickListener(i -> {
69                     Calendar c = Calendar.getInstance();
70                     c.set(Calendar.HOUR_OF_DAY, mTimePicker.getHour());
71                     c.set(Calendar.MINUTE, mTimePicker.getMinute());
72                     c.set(Calendar.SECOND, 0);
73                     c.set(Calendar.MILLISECOND, 0);
74                     long when = Math.max(c.getTimeInMillis(), DatetimeSettingsFragment.MIN_DATE);
75                     if (when / MILLIS_IN_SECOND < Integer.MAX_VALUE) {
76                         TimeDetector timeDetector =
77                                 getContext().getSystemService(TimeDetector.class);
78                         ManualTimeSuggestion manualTimeSuggestion =
79                                 TimeDetector.createManualTimeSuggestion(when, "Settings: Set time");
80                         timeDetector.suggestManualTime(manualTimeSuggestion);
81                         getContext().sendBroadcast(new Intent(Intent.ACTION_TIME_CHANGED));
82                     }
83                     getFragmentHost().goBack();
84                 })
85                 .build();
86     }
87 
88     @Override
89     @LayoutRes
getLayoutId()90     protected int getLayoutId() {
91         return R.layout.time_picker;
92     }
93 
94     @Override
95     @StringRes
getTitleId()96     protected int getTitleId() {
97         return R.string.time_picker_title;
98     }
99 
100     @Override
onActivityCreated(Bundle savedInstanceState)101     public void onActivityCreated(Bundle savedInstanceState) {
102         super.onActivityCreated(savedInstanceState);
103 
104         mDirectManipulationMode = new DirectManipulationState();
105         mTimePicker = getView().findViewById(R.id.time_picker);
106         mTimePicker.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
107         mTimePicker.setIs24HourView(is24Hour());
108         mNumberPickers = new ArrayList<>();
109         NumberPickerUtils.getNumberPickerDescendants(mNumberPickers, mTimePicker);
110 
111         DirectManipulationHandler.setDirectManipulationHandler(mTimePicker,
112                 new DirectManipulationHandler.Builder(mDirectManipulationMode)
113                         // Use no-op nudge handler, since we never stay on this view in direct
114                         // manipulation mode.
115                         .setNudgeHandler((v, keyCode, event) -> true)
116                         .setCenterButtonHandler(inDirectManipulationMode -> {
117                             if (inDirectManipulationMode) {
118                                 return true;
119                             }
120 
121                             NumberPicker picker = mNumberPickers.get(0);
122                             if (picker != null) {
123                                 picker.requestFocus();
124                             }
125                             return true;
126                         })
127                         .setBackHandler(inDirectManipulationMode -> {
128                             // Only handle back if we weren't previously in direct manipulation
129                             // mode.
130                             if (!inDirectManipulationMode) {
131                                 onBackPressed();
132                             }
133                             return true;
134                         })
135                         .build());
136 
137         DirectManipulationHandler numberPickerListener =
138                 new DirectManipulationHandler.Builder(mDirectManipulationMode)
139                         .setNudgeHandler(new NumberPickerNudgeHandler())
140                         .setCenterButtonHandler(inDirectManipulationMode -> {
141                             if (!inDirectManipulationMode) {
142                                 return true;
143                             }
144 
145                             mTimePicker.requestFocus();
146                             return true;
147                         })
148                         .setBackHandler(inDirectManipulationMode -> {
149                             mTimePicker.requestFocus();
150                             return true;
151                         })
152                         .setRotationHandler(new NumberPickerRotationHandler())
153                         .build();
154 
155         for (int i = 0; i < mNumberPickers.size(); i++) {
156             DirectManipulationHandler.setDirectManipulationHandler(mNumberPickers.get(i),
157                     numberPickerListener);
158         }
159     }
160 
161     @Override
onUxRestrictionsChanged(CarUxRestrictions restrictionInfo)162     public void onUxRestrictionsChanged(CarUxRestrictions restrictionInfo) {
163         if (canBeShown(restrictionInfo)) {
164             return;
165         }
166         if (mDirectManipulationMode != null && mDirectManipulationMode.isActive()) {
167             mDirectManipulationMode.disable();
168         }
169     }
170 
171     @Override
onDestroy()172     public void onDestroy() {
173         DirectManipulationHandler.setDirectManipulationHandler(mTimePicker, /* handler= */ null);
174         for (int i = 0; i < mNumberPickers.size(); i++) {
175             DirectManipulationHandler.setDirectManipulationHandler(mNumberPickers.get(i),
176                     /* handler= */ null);
177         }
178 
179         super.onDestroy();
180     }
181 
is24Hour()182     private boolean is24Hour() {
183         return DateFormat.is24HourFormat(getContext());
184     }
185 }
186