1 /*
2  * Copyright (C) 2018 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.settings.deviceinfo.aboutphone;
18 
19 import android.app.Activity;
20 import android.app.settings.SettingsEnums;
21 import android.content.Context;
22 import android.content.Intent;
23 import android.content.pm.UserInfo;
24 import android.os.Bundle;
25 import android.os.UserManager;
26 import android.view.View;
27 
28 import com.android.settings.R;
29 import com.android.settings.Utils;
30 import com.android.settings.dashboard.DashboardFragment;
31 import com.android.settings.deviceinfo.BluetoothAddressPreferenceController;
32 import com.android.settings.deviceinfo.BuildNumberPreferenceController;
33 import com.android.settings.deviceinfo.DeviceNamePreferenceController;
34 import com.android.settings.deviceinfo.FccEquipmentIdPreferenceController;
35 import com.android.settings.deviceinfo.FeedbackPreferenceController;
36 import com.android.settings.deviceinfo.IpAddressPreferenceController;
37 import com.android.settings.deviceinfo.ManualPreferenceController;
38 import com.android.settings.deviceinfo.RegulatoryInfoPreferenceController;
39 import com.android.settings.deviceinfo.SafetyInfoPreferenceController;
40 import com.android.settings.deviceinfo.UptimePreferenceController;
41 import com.android.settings.deviceinfo.WifiMacAddressPreferenceController;
42 import com.android.settings.deviceinfo.imei.ImeiInfoPreferenceController;
43 import com.android.settings.deviceinfo.simstatus.EidStatus;
44 import com.android.settings.deviceinfo.simstatus.SimEidPreferenceController;
45 import com.android.settings.deviceinfo.simstatus.SimStatusPreferenceController;
46 import com.android.settings.deviceinfo.simstatus.SlotSimStatus;
47 import com.android.settings.search.BaseSearchIndexProvider;
48 import com.android.settings.widget.EntityHeaderController;
49 import com.android.settingslib.core.AbstractPreferenceController;
50 import com.android.settingslib.core.lifecycle.Lifecycle;
51 import com.android.settingslib.search.SearchIndexable;
52 import com.android.settingslib.widget.LayoutPreference;
53 
54 import java.util.ArrayList;
55 import java.util.List;
56 import java.util.concurrent.ExecutorService;
57 import java.util.concurrent.Executors;
58 import java.util.function.Consumer;
59 
60 @SearchIndexable
61 public class MyDeviceInfoFragment extends DashboardFragment
62         implements DeviceNamePreferenceController.DeviceNamePreferenceHost {
63 
64     private static final String LOG_TAG = "MyDeviceInfoFragment";
65     private static final String KEY_EID_INFO = "eid_info";
66     private static final String KEY_MY_DEVICE_INFO_HEADER = "my_device_info_header";
67 
68     private BuildNumberPreferenceController mBuildNumberPreferenceController;
69 
70     @Override
getMetricsCategory()71     public int getMetricsCategory() {
72         return SettingsEnums.DEVICEINFO;
73     }
74 
75     @Override
getHelpResource()76     public int getHelpResource() {
77         return R.string.help_uri_about;
78     }
79 
80     @Override
onAttach(Context context)81     public void onAttach(Context context) {
82         super.onAttach(context);
83         use(DeviceNamePreferenceController.class).setHost(this /* parent */);
84         mBuildNumberPreferenceController = use(BuildNumberPreferenceController.class);
85         mBuildNumberPreferenceController.setHost(this /* parent */);
86     }
87 
88     @Override
onStart()89     public void onStart() {
90         super.onStart();
91         initHeader();
92     }
93 
94     @Override
getLogTag()95     protected String getLogTag() {
96         return LOG_TAG;
97     }
98 
99     @Override
getPreferenceScreenResId()100     protected int getPreferenceScreenResId() {
101         return R.xml.my_device_info;
102     }
103 
104     @Override
createPreferenceControllers(Context context)105     protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
106         return buildPreferenceControllers(context, this /* fragment */, getSettingsLifecycle());
107     }
108 
buildPreferenceControllers( Context context, MyDeviceInfoFragment fragment, Lifecycle lifecycle)109     private static List<AbstractPreferenceController> buildPreferenceControllers(
110             Context context, MyDeviceInfoFragment fragment, Lifecycle lifecycle) {
111         final List<AbstractPreferenceController> controllers = new ArrayList<>();
112 
113         final ExecutorService executor = (fragment == null) ? null :
114                 Executors.newSingleThreadExecutor();
115         androidx.lifecycle.Lifecycle lifecycleObject = (fragment == null) ? null :
116                 fragment.getLifecycle();
117         final SlotSimStatus slotSimStatus = new SlotSimStatus(context, executor, lifecycleObject);
118 
119         controllers.add(new IpAddressPreferenceController(context, lifecycle));
120         controllers.add(new WifiMacAddressPreferenceController(context, lifecycle));
121         controllers.add(new BluetoothAddressPreferenceController(context, lifecycle));
122         controllers.add(new RegulatoryInfoPreferenceController(context));
123         controllers.add(new SafetyInfoPreferenceController(context));
124         controllers.add(new ManualPreferenceController(context));
125         controllers.add(new FeedbackPreferenceController(fragment, context));
126         controllers.add(new FccEquipmentIdPreferenceController(context));
127         controllers.add(new UptimePreferenceController(context, lifecycle));
128 
129         Consumer<String> imeiInfoList = imeiKey -> {
130             ImeiInfoPreferenceController imeiRecord =
131                     new ImeiInfoPreferenceController(context, imeiKey);
132             imeiRecord.init(fragment, slotSimStatus);
133             controllers.add(imeiRecord);
134         };
135 
136         if (fragment != null) {
137             imeiInfoList.accept(ImeiInfoPreferenceController.DEFAULT_KEY);
138         }
139 
140         for (int slotIndex = 0; slotIndex < slotSimStatus.size(); slotIndex ++) {
141             SimStatusPreferenceController slotRecord =
142                     new SimStatusPreferenceController(context,
143                     slotSimStatus.getPreferenceKey(slotIndex));
144             slotRecord.init(fragment, slotSimStatus);
145             controllers.add(slotRecord);
146 
147             if (fragment != null) {
148                 imeiInfoList.accept(ImeiInfoPreferenceController.DEFAULT_KEY + (1 + slotIndex));
149             }
150         }
151 
152         EidStatus eidStatus = new EidStatus(slotSimStatus, context, executor);
153         SimEidPreferenceController simEid = new SimEidPreferenceController(context, KEY_EID_INFO);
154         simEid.init(slotSimStatus, eidStatus);
155         controllers.add(simEid);
156 
157         if (executor != null) {
158             executor.shutdown();
159         }
160         return controllers;
161     }
162 
163     @Override
onActivityResult(int requestCode, int resultCode, Intent data)164     public void onActivityResult(int requestCode, int resultCode, Intent data) {
165         if (mBuildNumberPreferenceController.onActivityResult(requestCode, resultCode, data)) {
166             return;
167         }
168         super.onActivityResult(requestCode, resultCode, data);
169     }
170 
initHeader()171     private void initHeader() {
172         // TODO: Migrate into its own controller.
173         final LayoutPreference headerPreference =
174                 getPreferenceScreen().findPreference(KEY_MY_DEVICE_INFO_HEADER);
175         final boolean shouldDisplayHeader = getContext().getResources().getBoolean(
176                 R.bool.config_show_device_header_in_device_info);
177         headerPreference.setVisible(shouldDisplayHeader);
178         if (!shouldDisplayHeader) {
179             return;
180         }
181         final View headerView = headerPreference.findViewById(R.id.entity_header);
182         final Activity context = getActivity();
183         final Bundle bundle = getArguments();
184         final EntityHeaderController controller = EntityHeaderController
185                 .newInstance(context, this, headerView)
186                 .setButtonActions(EntityHeaderController.ActionType.ACTION_NONE,
187                         EntityHeaderController.ActionType.ACTION_NONE);
188 
189         // TODO: There may be an avatar setting action we can use here.
190         final int iconId = bundle.getInt("icon_id", 0);
191         if (iconId == 0) {
192             final UserManager userManager = (UserManager) getActivity().getSystemService(
193                     Context.USER_SERVICE);
194             final UserInfo info = Utils.getExistingUser(userManager,
195                     android.os.Process.myUserHandle());
196             controller.setLabel(info.name);
197             controller.setIcon(
198                     com.android.settingslib.Utils.getUserIcon(getActivity(), userManager, info));
199         }
200 
201         controller.done(true /* rebindActions */);
202     }
203 
204     @Override
showDeviceNameWarningDialog(String deviceName)205     public void showDeviceNameWarningDialog(String deviceName) {
206         DeviceNameWarningDialog.show(this);
207     }
208 
onSetDeviceNameConfirm(boolean confirm)209     public void onSetDeviceNameConfirm(boolean confirm) {
210         final DeviceNamePreferenceController controller = use(DeviceNamePreferenceController.class);
211         controller.updateDeviceName(confirm);
212     }
213 
214     /**
215      * For Search.
216      */
217     public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
218             new BaseSearchIndexProvider(R.xml.my_device_info) {
219 
220                 @Override
221                 public List<AbstractPreferenceController> createPreferenceControllers(
222                         Context context) {
223                     return buildPreferenceControllers(context, null /* fragment */,
224                             null /* lifecycle */);
225                 }
226             };
227 }
228