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