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