• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.settings.wifi.calling;
18 
19 import android.app.settings.SettingsEnums;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.os.Bundle;
23 import android.provider.Settings;
24 import android.telephony.SubscriptionInfo;
25 import android.telephony.SubscriptionManager;
26 import android.util.Log;
27 import android.view.LayoutInflater;
28 import android.view.View;
29 import android.view.ViewGroup;
30 
31 import androidx.annotation.VisibleForTesting;
32 import androidx.fragment.app.Fragment;
33 import androidx.fragment.app.FragmentActivity;
34 import androidx.fragment.app.FragmentManager;
35 import androidx.fragment.app.FragmentPagerAdapter;
36 
37 import com.android.internal.util.CollectionUtils;
38 import com.android.settings.R;
39 import com.android.settings.core.InstrumentedFragment;
40 import com.android.settings.network.ActiveSubscriptionsListener;
41 import com.android.settings.network.SubscriptionUtil;
42 import com.android.settings.network.ims.WifiCallingQueryImsState;
43 import com.android.settings.search.actionbar.SearchMenuController;
44 import com.android.settings.support.actionbar.HelpResourceProvider;
45 import com.android.settings.widget.RtlCompatibleViewPager;
46 import com.android.settings.widget.SlidingTabLayout;
47 
48 import java.util.ArrayList;
49 import java.util.Arrays;
50 import java.util.Collections;
51 import java.util.List;
52 
53 /**
54  * "Wi-Fi Calling settings" screen. This is the container fragment which holds
55  * {@link WifiCallingSettingsForSub} fragments.
56  */
57 public class WifiCallingSettings extends InstrumentedFragment implements HelpResourceProvider {
58     private static final String TAG = "WifiCallingSettings";
59     private int mConstructionSubId;
60     private List<SubscriptionInfo> mSil;
61     private ActiveSubscriptionsListener mSubscriptionChangeListener;
62     private static final int [] EMPTY_SUB_ID_LIST = new int[0];
63 
64     //UI objects
65     private RtlCompatibleViewPager mViewPager;
66     private WifiCallingViewPagerAdapter mPagerAdapter;
67     private SlidingTabLayout mTabLayout;
68 
69     private final class InternalViewPagerListener implements
70             RtlCompatibleViewPager.OnPageChangeListener {
71         @Override
onPageScrolled(int position, float positionOffset, int positionOffsetPixels)72         public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
73             // Do nothing.
74         }
75 
76         @Override
onPageSelected(int position)77         public void onPageSelected(int position) {
78             updateTitleForCurrentSub();
79         }
80 
81         @Override
onPageScrollStateChanged(int state)82         public void onPageScrollStateChanged(int state) {
83             // Do nothing.
84         }
85     }
86 
87     @Override
getMetricsCategory()88     public int getMetricsCategory() {
89         return SettingsEnums.WIFI_CALLING;
90     }
91 
92     @Override
onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)93     public View onCreateView(LayoutInflater inflater, ViewGroup container,
94             Bundle savedInstanceState) {
95         final View view = inflater.inflate(R.layout.wifi_calling_settings_tabs, container, false);
96 
97         mTabLayout = view.findViewById(R.id.sliding_tabs);
98         mViewPager = (RtlCompatibleViewPager) view.findViewById(R.id.view_pager);
99 
100         mPagerAdapter = new WifiCallingViewPagerAdapter(getChildFragmentManager(), mViewPager);
101         mViewPager.setAdapter(mPagerAdapter);
102         mViewPager.addOnPageChangeListener(new InternalViewPagerListener());
103         maybeSetViewForSubId();
104         return view;
105     }
106 
getConstructionSubId(Bundle bundle)107     private int getConstructionSubId(Bundle bundle) {
108         int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
109 
110         Intent intent = getActivity().getIntent();
111         if (intent != null) {
112             subId = intent.getIntExtra(Settings.EXTRA_SUB_ID,
113                     SubscriptionManager.INVALID_SUBSCRIPTION_ID);
114         }
115         if ((subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) && (bundle != null)) {
116             subId = bundle.getInt(Settings.EXTRA_SUB_ID,
117                     SubscriptionManager.INVALID_SUBSCRIPTION_ID);
118         }
119         return subId;
120     }
121 
maybeSetViewForSubId()122     private void maybeSetViewForSubId() {
123         if (mSil == null) {
124             return;
125         }
126         int subId = mConstructionSubId;
127         if (SubscriptionManager.isValidSubscriptionId(subId)) {
128             for (SubscriptionInfo subInfo : mSil) {
129                 if (subId == subInfo.getSubscriptionId()) {
130                     mViewPager.setCurrentItem(mSil.indexOf(subInfo));
131                     break;
132                 }
133             }
134         }
135     }
136 
137     @Override
onCreate(Bundle icicle)138     public void onCreate(Bundle icicle) {
139         mConstructionSubId = getConstructionSubId(icicle);
140         super.onCreate(icicle);
141         Log.d(TAG, "SubId=" + mConstructionSubId);
142 
143         if (mConstructionSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
144             // Only config Wfc if it's enabled by platform.
145             mSubscriptionChangeListener = getSubscriptionChangeListener(getContext());
146         }
147         mSil = updateSubList();
148     }
149 
150     @Override
onStart()151     public void onStart() {
152         super.onStart();
153 
154         if (mSil != null && mSil.size() > 1) {
155             mTabLayout.setViewPager(mViewPager);
156         } else {
157             mTabLayout.setVisibility(View.GONE);
158         }
159 
160         updateTitleForCurrentSub();
161 
162         if (mSubscriptionChangeListener != null) {
163             mSubscriptionChangeListener.start();
164         }
165     }
166 
167     @Override
onStop()168     public void onStop() {
169         if (mSubscriptionChangeListener != null) {
170             mSubscriptionChangeListener.stop();
171         }
172 
173         super.onStop();
174     }
175 
176     @Override
onSaveInstanceState(Bundle outState)177     public void onSaveInstanceState(Bundle outState) {
178         super.onSaveInstanceState(outState);
179         // keep subscription ID for recreation
180         outState.putInt(Settings.EXTRA_SUB_ID, mConstructionSubId);
181     }
182 
183     @Override
getHelpResource()184     public int getHelpResource() {
185         return R.string.help_uri_wifi_calling;
186     }
187 
188     @VisibleForTesting
189     final class WifiCallingViewPagerAdapter extends FragmentPagerAdapter {
190         private final RtlCompatibleViewPager mViewPager;
191 
WifiCallingViewPagerAdapter(FragmentManager fragmentManager, RtlCompatibleViewPager viewPager)192         public WifiCallingViewPagerAdapter(FragmentManager fragmentManager,
193                 RtlCompatibleViewPager viewPager) {
194             super(fragmentManager);
195             mViewPager = viewPager;
196         }
197 
198         @Override
getPageTitle(int position)199         public CharSequence getPageTitle(int position) {
200             return String.valueOf(SubscriptionUtil.getUniqueSubscriptionDisplayName(
201                     mSil.get(position), getContext()));
202         }
203 
204         @Override
getItem(int position)205         public Fragment getItem(int position) {
206             int subId = mSil.get(position).getSubscriptionId();
207             Log.d(TAG, "Adapter getItem " + position + " for subId=" + subId);
208             final Bundle args = new Bundle();
209             args.putBoolean(SearchMenuController.NEED_SEARCH_ICON_IN_ACTION_BAR, false);
210             args.putInt(WifiCallingSettingsForSub.FRAGMENT_BUNDLE_SUBID, subId);
211             final WifiCallingSettingsForSub fragment = new WifiCallingSettingsForSub();
212             fragment.setArguments(args);
213 
214             return fragment;
215         }
216 
217         @Override
instantiateItem(ViewGroup container, int position)218         public Object instantiateItem(ViewGroup container, int position) {
219             Log.d(TAG, "Adapter instantiateItem " + position);
220             return super.instantiateItem(container,
221                     mViewPager.getRtlAwareIndex(position));
222         }
223 
224         @Override
getCount()225         public int getCount() {
226             if (mSil == null) {
227                 Log.d(TAG, "Adapter getCount null mSil ");
228                 return 0;
229             } else {
230                 Log.d(TAG, "Adapter getCount " + mSil.size());
231                 return mSil.size();
232             }
233         }
234     }
235 
236     @VisibleForTesting
getSelectableSubscriptions(Context context)237     protected List<SubscriptionInfo> getSelectableSubscriptions(Context context) {
238         return SubscriptionUtil.getSelectableSubscriptionInfoList(context);
239     }
240 
updateSubList()241     private List<SubscriptionInfo> updateSubList() {
242         List<SubscriptionInfo> subInfoList = getSelectableSubscriptions(getContext());
243 
244         if (subInfoList == null) {
245             return Collections.emptyList();
246         }
247         List<SubscriptionInfo> selectedList = new ArrayList<SubscriptionInfo>();
248         for (SubscriptionInfo subInfo : subInfoList) {
249             int subId = subInfo.getSubscriptionId();
250             try {
251                 if (queryImsState(subId).isWifiCallingProvisioned()) {
252                     selectedList.add(subInfo);
253                 }
254             } catch (Exception exception) {}
255         }
256         return selectedList;
257     }
258 
updateTitleForCurrentSub()259     private void updateTitleForCurrentSub() {
260         if (CollectionUtils.size(mSil) > 1) {
261             final int subId = mSil.get(mViewPager.getCurrentItem()).getSubscriptionId();
262             final String title = SubscriptionManager.getResourcesForSubId(getContext(), subId)
263                     .getString(R.string.wifi_calling_settings_title);
264             getActivity().getActionBar().setTitle(title);
265         }
266     }
267 
268     @VisibleForTesting
queryImsState(int subId)269     protected WifiCallingQueryImsState queryImsState(int subId) {
270         return new WifiCallingQueryImsState(getContext(), subId);
271     }
272 
273     @VisibleForTesting
getSubscriptionChangeListener(Context context)274     protected ActiveSubscriptionsListener getSubscriptionChangeListener(Context context) {
275         return new ActiveSubscriptionsListener(context.getMainLooper(), context) {
276             public void onChanged() {
277                 onSubscriptionChange(context);
278             }
279         };
280     }
281 
282     protected void onSubscriptionChange(Context context) {
283         if (mSubscriptionChangeListener == null) {
284             return;
285         }
286         int [] previousSubIdList = subscriptionIdList(mSil);
287         List<SubscriptionInfo> updateList = updateSubList();
288         int [] currentSubIdList = subscriptionIdList(updateList);
289 
290         if (currentSubIdList.length > 0) {
291             // only keep fragment when any provisioned subscription is available
292             if (previousSubIdList.length == 0) {
293                 // initial loading of list
294                 mSil = updateList;
295                 return;
296             }
297             if (previousSubIdList.length == currentSubIdList.length) {
298                 // same number of subscriptions
299                 if ( (!containsSubId(previousSubIdList, mConstructionSubId))
300                         // original request not yet appears in list
301                         || containsSubId(currentSubIdList, mConstructionSubId) )
302                         // original request appears in list
303                 {
304                     mSil = updateList;
305                     return;
306                 }
307             }
308         }
309         Log.d(TAG, "Closed subId=" + mConstructionSubId
310                 + " due to subscription change: " + Arrays.toString(previousSubIdList)
311                 + " -> " + Arrays.toString(currentSubIdList));
312 
313         // close this fragment when no provisioned subscriptions available
314         if (mSubscriptionChangeListener != null) {
315             mSubscriptionChangeListener.stop();
316             mSubscriptionChangeListener = null;
317         }
318 
319         // close this fragment
320         finish();
321     }
322 
323     protected void finish() {
324         FragmentActivity activity = getActivity();
325         if (activity == null) return;
326         if (getFragmentManager().getBackStackEntryCount() > 0) {
327             getFragmentManager().popBackStack();
328         } else {
329             activity.finish();
330         }
331     }
332 
333     protected int [] subscriptionIdList(List<SubscriptionInfo> subInfoList) {
334         return (subInfoList == null) ? EMPTY_SUB_ID_LIST :
335                 subInfoList.stream().mapToInt(subInfo -> (subInfo == null) ?
336                 SubscriptionManager.INVALID_SUBSCRIPTION_ID : subInfo.getSubscriptionId())
337                 .toArray();
338     }
339 
340     protected boolean containsSubId(int [] subIdArray, int subIdLookUp) {
341         return Arrays.stream(subIdArray).anyMatch(subId -> (subId == subIdLookUp));
342     }
343 }
344