• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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.incallui.telecomeventui;
18 
19 import android.app.AlertDialog;
20 import android.app.Dialog;
21 import android.content.Context;
22 import android.content.SharedPreferences;
23 import android.os.Bundle;
24 import android.support.annotation.NonNull;
25 import android.support.annotation.VisibleForTesting;
26 import android.support.v4.app.DialogFragment;
27 import android.support.v4.os.UserManagerCompat;
28 import android.view.View;
29 import android.widget.CheckBox;
30 import com.android.dialer.common.Assert;
31 import com.android.dialer.common.FragmentUtils;
32 import com.android.dialer.common.LogUtil;
33 import com.android.dialer.storage.StorageComponent;
34 import com.android.incallui.call.CallList;
35 import com.android.incallui.call.DialerCall;
36 
37 /**
38  * Dialog that may be shown when users place an outgoing call to an international number while on
39  * Wifi.
40  *
41  * <p>The android.telephony.event.EVENT_NOTIFY_INTERNATIONAL_CALL_ON_WFC event is sent when users
42  * attempt to place a call under these circumstances.
43  */
44 public class InternationalCallOnWifiDialogFragment extends DialogFragment {
45 
46   /**
47    * Returns {@code true} if an {@link InternationalCallOnWifiDialogFragment} should be shown.
48    *
49    * <p>Attempting to show an InternationalCallOnWifiDialogFragment when this method returns {@code
50    * false} will result in an {@link IllegalStateException}.
51    */
shouldShow(@onNull Context context)52   public static boolean shouldShow(@NonNull Context context) {
53     if (!UserManagerCompat.isUserUnlocked(context)) {
54       LogUtil.i("InternationalCallOnWifiDialogFragment.shouldShow", "user locked, returning false");
55       return false;
56     }
57 
58     SharedPreferences preferences = StorageComponent.get(context).unencryptedSharedPrefs();
59     boolean shouldShow = preferences.getBoolean(ALWAYS_SHOW_WARNING_PREFERENCE_KEY, true);
60 
61     LogUtil.i("InternationalCallOnWifiDialogFragment.shouldShow", "result: %b", shouldShow);
62     return shouldShow;
63   }
64 
65   /**
66    * Returns a new instance of {@link InternationalCallOnWifiDialogFragment} with the given
67    * callback.
68    *
69    * <p>Prefer this method over the default constructor.
70    */
newInstance(@onNull String callId)71   public static InternationalCallOnWifiDialogFragment newInstance(@NonNull String callId) {
72     InternationalCallOnWifiDialogFragment fragment = new InternationalCallOnWifiDialogFragment();
73     Bundle args = new Bundle();
74     args.putString(ARG_CALL_ID, Assert.isNotNull(callId));
75     fragment.setArguments(args);
76     return fragment;
77   }
78 
79   /**
80    * Key to the preference used to determine if the user wants to see {@link
81    * InternationalCallOnWifiDialogFragment InternationalCallOnWifiDialogFragments}.
82    */
83   @VisibleForTesting
84   public static final String ALWAYS_SHOW_WARNING_PREFERENCE_KEY =
85       "ALWAYS_SHOW_INTERNATIONAL_CALL_ON_WIFI_WARNING";
86 
87   /** Key in the arguments bundle for call id. */
88   private static final String ARG_CALL_ID = "call_id";
89 
90   @NonNull
91   @Override
onCreateDialog(Bundle bundle)92   public Dialog onCreateDialog(Bundle bundle) {
93     super.onCreateDialog(bundle);
94     LogUtil.enterBlock("InternationalCallOnWifiDialogFragment.onCreateDialog");
95 
96     if (!InternationalCallOnWifiDialogFragment.shouldShow(getActivity())) {
97       throw new IllegalStateException(
98           "shouldShow indicated InternationalCallOnWifiDialogFragment should not have showed");
99     }
100 
101     View dialogView =
102         View.inflate(getActivity(), R.layout.frag_international_call_on_wifi_dialog, null);
103 
104     CheckBox alwaysWarn = dialogView.findViewById(R.id.always_warn);
105 
106     SharedPreferences preferences = StorageComponent.get(getActivity()).unencryptedSharedPrefs();
107     // The default is set to false in this case to ensure that the first time the dialog opens,
108     // the checkbox is unchecked.
109     alwaysWarn.setChecked(preferences.getBoolean(ALWAYS_SHOW_WARNING_PREFERENCE_KEY, false));
110 
111     AlertDialog alertDialog =
112         new AlertDialog.Builder(getActivity())
113             .setCancelable(false)
114             .setView(dialogView)
115             .setPositiveButton(
116                 android.R.string.ok,
117                 (dialog, which) -> onPositiveButtonClick(preferences, alwaysWarn.isChecked()))
118             .setNegativeButton(
119                 android.R.string.cancel,
120                 (dialog, which) -> onNegativeButtonClick(preferences, alwaysWarn.isChecked()))
121             .create();
122 
123     alertDialog.setCanceledOnTouchOutside(false);
124     return alertDialog;
125   }
126 
onPositiveButtonClick(@onNull SharedPreferences preferences, boolean alwaysWarn)127   private void onPositiveButtonClick(@NonNull SharedPreferences preferences, boolean alwaysWarn) {
128     LogUtil.i(
129         "InternationalCallOnWifiDialogFragment.onPositiveButtonClick",
130         "alwaysWarn: %b",
131         alwaysWarn);
132     preferences.edit().putBoolean(ALWAYS_SHOW_WARNING_PREFERENCE_KEY, alwaysWarn).apply();
133 
134     // Neither callback nor callId are null in normal circumstances. See comments on callback
135     continueCall(getArguments().getString(ARG_CALL_ID));
136   }
137 
onNegativeButtonClick(@onNull SharedPreferences preferences, boolean alwaysWarn)138   private void onNegativeButtonClick(@NonNull SharedPreferences preferences, boolean alwaysWarn) {
139     LogUtil.i(
140         "InternationalCallOnWifiDialogFragment.onNegativeButtonClick",
141         "alwaysWarn: %b",
142         alwaysWarn);
143     preferences.edit().putBoolean(ALWAYS_SHOW_WARNING_PREFERENCE_KEY, alwaysWarn).apply();
144 
145     // Neither callback nor callId are null in normal circumstances. See comments on callback
146     cancelCall(getArguments().getString(ARG_CALL_ID));
147   }
148 
continueCall(@onNull String callId)149   private void continueCall(@NonNull String callId) {
150     LogUtil.i(
151         "InternationalCallOnWifiDialogFragment.continueCall",
152         "Continuing call with ID: %s",
153         callId);
154     InternationalCallOnWifiDialogActivity activity =
155         FragmentUtils.getParent(this, InternationalCallOnWifiDialogActivity.class);
156     if (activity != null) {
157       activity.finish();
158     }
159   }
160 
cancelCall(@onNull String callId)161   private void cancelCall(@NonNull String callId) {
162     DialerCall call = CallList.getInstance().getCallById(callId);
163     if (call == null) {
164       LogUtil.i(
165           "InternationalCallOnWifiDialogFragment.cancelCall",
166           "Call destroyed before the dialog is closed");
167     } else {
168       LogUtil.i(
169           "InternationalCallOnWifiDialogFragment.cancelCall",
170           "Disconnecting international call on WiFi");
171       call.disconnect();
172     }
173     InternationalCallOnWifiDialogActivity activity =
174         FragmentUtils.getParent(this, InternationalCallOnWifiDialogActivity.class);
175     if (activity != null) {
176       activity.finish();
177     }
178   }
179 }
180