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