1 /*
2  * Copyright (C) 2015 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.tv.settings.name;
18 
19 import android.app.Activity;
20 import android.content.res.Resources;
21 import android.graphics.Color;
22 import android.os.Build;
23 import android.os.Bundle;
24 import android.view.LayoutInflater;
25 import android.view.View;
26 import android.view.ViewGroup;
27 
28 import androidx.annotation.NonNull;
29 import androidx.leanback.app.GuidedStepSupportFragment;
30 import androidx.leanback.widget.GuidanceStylist;
31 import androidx.leanback.widget.GuidedAction;
32 import androidx.leanback.widget.GuidedActionsStylist;
33 
34 import com.android.settingslib.dream.DreamBackend;
35 import com.android.tv.settings.R;
36 import com.android.tv.settings.name.setup.DeviceNameFlowStartActivity;
37 import com.android.tv.settings.overlay.FlavorUtils;
38 import com.android.tv.settings.util.GuidedActionsAlignUtil;
39 
40 import java.util.ArrayList;
41 import java.util.Arrays;
42 import java.util.List;
43 
44 /**
45  * Fragment responsible for showing the device names list.
46  */
47 public class DeviceNameSetFragment extends GuidedStepSupportFragment {
48     private ArrayList<String> mDeviceNames = new ArrayList<>();
49 
newInstance()50     public static DeviceNameSetFragment newInstance() {
51         return new DeviceNameSetFragment();
52     }
53 
54     @Override
onCreateGuidanceStylist()55     public GuidanceStylist onCreateGuidanceStylist() {
56         return GuidedActionsAlignUtil.createGuidanceStylist();
57     }
58 
59     @Override
onCreateActionsStylist()60     public GuidedActionsStylist onCreateActionsStylist() {
61         return GuidedActionsAlignUtil.createGuidedActionsStylist();
62     }
63 
64     @Override
onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)65     public View onCreateView(LayoutInflater inflater, ViewGroup container,
66             Bundle savedInstanceState) {
67         View view = super.onCreateView(inflater, container, savedInstanceState);
68         View guidanceView = GuidedActionsAlignUtil.createView(view, this);
69 
70         if (FlavorUtils.isTwoPanel(getContext())) {
71             guidanceView.setBackgroundColor(
72                     getResources().getColor(R.color.tp_preference_panel_background_color));
73         }
74         return guidanceView;
75     }
76 
77     @NonNull
78     @Override
onCreateGuidance(Bundle savedInstanceState)79     public GuidanceStylist.Guidance onCreateGuidance(Bundle savedInstanceState) {
80         return new GuidanceStylist.Guidance(
81                 getString(R.string.select_device_name_title, Build.MODEL),
82                 getString(R.string.select_device_name_description),
83                 null,
84                 null);
85     }
86 
87     @Override
onCreateActions(@onNull List<GuidedAction> actions, Bundle savedInstanceState)88     public void onCreateActions(@NonNull List<GuidedAction> actions, Bundle savedInstanceState) {
89         mDeviceNames.add(Build.MODEL);
90         mDeviceNames.addAll(Arrays.asList(getResources().getStringArray(R.array.rooms)));
91         // The strings added above are static names that should always be shown.
92         String currentDeviceName = DeviceManager.getDeviceName(getActivity());
93         if (currentDeviceName == null) {
94             currentDeviceName = Build.MODEL;
95         }
96         // Ideally we don't want to have identical entries. (e.g., if a device was named
97         // "Android TV", then "Android TV" (from static names) will be pre-selected/highlighted
98         // instead of being added to top of the list.
99         // However, since "Enter Custom Name..." is not considered as an static name, if someone
100         // name his/her device to be "Enter Custom Name..." (same to the title of action to
101         // customize device name), this name will still show at top of list just like any other
102         // "normal" names, co-existing with the action button at bottom.
103         if (mDeviceNames.indexOf(currentDeviceName) == -1) {
104             mDeviceNames.add(0, currentDeviceName);
105         }
106 
107         final int length = mDeviceNames.size();
108         for (int i = 0; i < length; i++) {
109             actions.add(new GuidedAction.Builder()
110                     .title(mDeviceNames.get(i))
111                     .id(i)
112                     .multilineDescription(true)
113                     .build());
114         }
115         actions.add(new GuidedAction.Builder()
116                 .title(getString(R.string.custom_room))
117                 .id(mDeviceNames.size())
118                 .multilineDescription(true)
119                 .build());
120         super.onCreateActions(actions, savedInstanceState);
121     }
122 
123     @Override
onResume()124     public void onResume() {
125         super.onResume();
126         int currentNamePosition = mDeviceNames.indexOf(DeviceManager.getDeviceName(getActivity()));
127         if (currentNamePosition != -1) {
128             setSelectedActionPosition(currentNamePosition);
129         }
130     }
131 
132     @Override
onGuidedActionClicked(GuidedAction action)133     public void onGuidedActionClicked(GuidedAction action) {
134         final long id = action.getId();
135         if (id < 0 || id > mDeviceNames.size()) {
136             throw new IllegalStateException("Unknown action ID");
137         } else if (id < mDeviceNames.size()) {
138             DeviceManager.setDeviceName(getActivity(), mDeviceNames.get((int) id));
139 
140             // Set the flag for the appropriate exit animation for setup.
141             if (getActivity() instanceof DeviceNameFlowStartActivity) {
142                 ((DeviceNameFlowStartActivity) getActivity()).setResultOk(true);
143             }
144             DeviceNameSuggestionStatus.getInstance(
145                     getActivity().getApplicationContext()).setFinished();
146             getActivity().setResult(Activity.RESULT_OK);
147             getActivity().finish();
148         } else if (id == mDeviceNames.size()) {
149             GuidedStepSupportFragment.add(
150                     getFragmentManager(), DeviceNameSetCustomFragment.newInstance());
151         }
152     }
153 
154     // Overriding this method removes the unpreferable exit transition animation of this fragment,
155     // which is currently only applied before showing DeviceNameSetCustomFragment.
156     // Be sure not to remove this method or leave its body empty as it is also used on Settings
157     // (not during Setup) and we need its default enter transition animation in that case.
158     @Override
onProvideFragmentTransitions()159     protected void onProvideFragmentTransitions() {
160         super.onProvideFragmentTransitions();
161         setExitTransition(null);
162     }
163 }
164