• 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 
40 import java.util.ArrayList;
41 import java.util.Calendar;
42 import java.util.List;
43 
44 /**
45  * Sets the system time.
46  */
47 public class TimePickerFragment extends BaseFragment {
48     private static final int MILLIS_IN_SECOND = 1000;
49 
50     private DirectManipulationState mDirectManipulationMode;
51     private TimePicker mTimePicker;
52     private List<NumberPicker> mNumberPickers;
53 
54     @Override
onStop()55     public void onStop() {
56         super.onStop();
57         Calendar c = Calendar.getInstance();
58         c.set(Calendar.HOUR_OF_DAY, mTimePicker.getHour());
59         c.set(Calendar.MINUTE, mTimePicker.getMinute());
60         c.set(Calendar.SECOND, 0);
61         c.set(Calendar.MILLISECOND, 0);
62         long when = Math.max(c.getTimeInMillis(), DatetimeSettingsFragment.MIN_DATE);
63         if (when / MILLIS_IN_SECOND < Integer.MAX_VALUE) {
64             TimeDetector timeDetector =
65                     getContext().getSystemService(TimeDetector.class);
66             ManualTimeSuggestion manualTimeSuggestion =
67                     TimeDetector.createManualTimeSuggestion(when, "Settings: Set time");
68             timeDetector.suggestManualTime(manualTimeSuggestion);
69             getContext().sendBroadcast(new Intent(Intent.ACTION_TIME_CHANGED));
70         }
71     }
72 
73     @Override
74     @LayoutRes
getLayoutId()75     protected int getLayoutId() {
76         return R.layout.time_picker;
77     }
78 
79     @Override
80     @StringRes
getTitleId()81     protected int getTitleId() {
82         return R.string.time_picker_title;
83     }
84 
85     @Override
onActivityCreated(Bundle savedInstanceState)86     public void onActivityCreated(Bundle savedInstanceState) {
87         super.onActivityCreated(savedInstanceState);
88 
89         mDirectManipulationMode = new DirectManipulationState();
90         mTimePicker = getView().findViewById(R.id.time_picker);
91         mTimePicker.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
92         mTimePicker.setIs24HourView(is24Hour());
93         mNumberPickers = new ArrayList<>();
94         NumberPickerUtils.getNumberPickerDescendants(mNumberPickers, mTimePicker);
95 
96         DirectManipulationHandler.setDirectManipulationHandler(mTimePicker,
97                 new DirectManipulationHandler.Builder(mDirectManipulationMode)
98                         // Use no-op nudge handler, since we never stay on this view in direct
99                         // manipulation mode.
100                         .setNudgeHandler((v, keyCode, event) -> true)
101                         .setCenterButtonHandler(inDirectManipulationMode -> {
102                             if (inDirectManipulationMode) {
103                                 return true;
104                             }
105 
106                             NumberPicker picker = mNumberPickers.get(0);
107                             if (picker != null) {
108                                 picker.requestFocus();
109                             }
110                             return true;
111                         })
112                         .setBackHandler(inDirectManipulationMode -> {
113                             // Only handle back if we weren't previously in direct manipulation
114                             // mode.
115                             if (!inDirectManipulationMode) {
116                                 onBackPressed();
117                             }
118                             return true;
119                         })
120                         .build());
121 
122         DirectManipulationHandler numberPickerListener =
123                 new DirectManipulationHandler.Builder(mDirectManipulationMode)
124                         .setNudgeHandler(new NumberPickerNudgeHandler())
125                         .setCenterButtonHandler(inDirectManipulationMode -> {
126                             if (!inDirectManipulationMode) {
127                                 return true;
128                             }
129 
130                             mTimePicker.requestFocus();
131                             return true;
132                         })
133                         .setBackHandler(inDirectManipulationMode -> {
134                             mTimePicker.requestFocus();
135                             return true;
136                         })
137                         .setRotationHandler(new NumberPickerRotationHandler())
138                         .build();
139 
140         for (int i = 0; i < mNumberPickers.size(); i++) {
141             DirectManipulationHandler.setDirectManipulationHandler(mNumberPickers.get(i),
142                     numberPickerListener);
143         }
144     }
145 
146     @Override
onUxRestrictionsChanged(CarUxRestrictions restrictionInfo)147     public void onUxRestrictionsChanged(CarUxRestrictions restrictionInfo) {
148         if (canBeShown(restrictionInfo)) {
149             return;
150         }
151         if (mDirectManipulationMode != null && mDirectManipulationMode.isActive()) {
152             mDirectManipulationMode.disable();
153         }
154     }
155 
156     @Override
onDestroy()157     public void onDestroy() {
158         DirectManipulationHandler.setDirectManipulationHandler(mTimePicker, /* handler= */ null);
159         for (int i = 0; i < mNumberPickers.size(); i++) {
160             DirectManipulationHandler.setDirectManipulationHandler(mNumberPickers.get(i),
161                     /* handler= */ null);
162         }
163 
164         super.onDestroy();
165     }
166 
is24Hour()167     private boolean is24Hour() {
168         return DateFormat.is24HourFormat(getContext());
169     }
170 }
171