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