/* * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License */ package com.android.incallui.telecomeventui; import android.app.AlertDialog; import android.app.Dialog; import android.content.Context; import android.content.SharedPreferences; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.VisibleForTesting; import android.support.v4.app.DialogFragment; import android.support.v4.os.UserManagerCompat; import android.view.View; import android.widget.CheckBox; import com.android.dialer.common.Assert; import com.android.dialer.common.FragmentUtils; import com.android.dialer.common.LogUtil; import com.android.dialer.storage.StorageComponent; import com.android.incallui.call.CallList; import com.android.incallui.call.DialerCall; /** * Dialog that may be shown when users place an outgoing call to an international number while on * Wifi. * *

The android.telephony.event.EVENT_NOTIFY_INTERNATIONAL_CALL_ON_WFC event is sent when users * attempt to place a call under these circumstances. */ public class InternationalCallOnWifiDialogFragment extends DialogFragment { /** * Returns {@code true} if an {@link InternationalCallOnWifiDialogFragment} should be shown. * *

Attempting to show an InternationalCallOnWifiDialogFragment when this method returns {@code * false} will result in an {@link IllegalStateException}. */ public static boolean shouldShow(@NonNull Context context) { if (!UserManagerCompat.isUserUnlocked(context)) { LogUtil.i("InternationalCallOnWifiDialogFragment.shouldShow", "user locked, returning false"); return false; } SharedPreferences preferences = StorageComponent.get(context).unencryptedSharedPrefs(); boolean shouldShow = preferences.getBoolean(ALWAYS_SHOW_WARNING_PREFERENCE_KEY, true); LogUtil.i("InternationalCallOnWifiDialogFragment.shouldShow", "result: %b", shouldShow); return shouldShow; } /** * Returns a new instance of {@link InternationalCallOnWifiDialogFragment} with the given * callback. * *

Prefer this method over the default constructor. */ public static InternationalCallOnWifiDialogFragment newInstance(@NonNull String callId) { InternationalCallOnWifiDialogFragment fragment = new InternationalCallOnWifiDialogFragment(); Bundle args = new Bundle(); args.putString(ARG_CALL_ID, Assert.isNotNull(callId)); fragment.setArguments(args); return fragment; } /** * Key to the preference used to determine if the user wants to see {@link * InternationalCallOnWifiDialogFragment InternationalCallOnWifiDialogFragments}. */ @VisibleForTesting public static final String ALWAYS_SHOW_WARNING_PREFERENCE_KEY = "ALWAYS_SHOW_INTERNATIONAL_CALL_ON_WIFI_WARNING"; /** Key in the arguments bundle for call id. */ private static final String ARG_CALL_ID = "call_id"; @NonNull @Override public Dialog onCreateDialog(Bundle bundle) { super.onCreateDialog(bundle); LogUtil.enterBlock("InternationalCallOnWifiDialogFragment.onCreateDialog"); if (!InternationalCallOnWifiDialogFragment.shouldShow(getActivity())) { throw new IllegalStateException( "shouldShow indicated InternationalCallOnWifiDialogFragment should not have showed"); } View dialogView = View.inflate(getActivity(), R.layout.frag_international_call_on_wifi_dialog, null); CheckBox alwaysWarn = dialogView.findViewById(R.id.always_warn); SharedPreferences preferences = StorageComponent.get(getActivity()).unencryptedSharedPrefs(); // The default is set to false in this case to ensure that the first time the dialog opens, // the checkbox is unchecked. alwaysWarn.setChecked(preferences.getBoolean(ALWAYS_SHOW_WARNING_PREFERENCE_KEY, false)); AlertDialog alertDialog = new AlertDialog.Builder(getActivity()) .setCancelable(false) .setView(dialogView) .setPositiveButton( android.R.string.ok, (dialog, which) -> onPositiveButtonClick(preferences, alwaysWarn.isChecked())) .setNegativeButton( android.R.string.cancel, (dialog, which) -> onNegativeButtonClick(preferences, alwaysWarn.isChecked())) .create(); alertDialog.setCanceledOnTouchOutside(false); return alertDialog; } private void onPositiveButtonClick(@NonNull SharedPreferences preferences, boolean alwaysWarn) { LogUtil.i( "InternationalCallOnWifiDialogFragment.onPositiveButtonClick", "alwaysWarn: %b", alwaysWarn); preferences.edit().putBoolean(ALWAYS_SHOW_WARNING_PREFERENCE_KEY, alwaysWarn).apply(); // Neither callback nor callId are null in normal circumstances. See comments on callback continueCall(getArguments().getString(ARG_CALL_ID)); } private void onNegativeButtonClick(@NonNull SharedPreferences preferences, boolean alwaysWarn) { LogUtil.i( "InternationalCallOnWifiDialogFragment.onNegativeButtonClick", "alwaysWarn: %b", alwaysWarn); preferences.edit().putBoolean(ALWAYS_SHOW_WARNING_PREFERENCE_KEY, alwaysWarn).apply(); // Neither callback nor callId are null in normal circumstances. See comments on callback cancelCall(getArguments().getString(ARG_CALL_ID)); } private void continueCall(@NonNull String callId) { LogUtil.i( "InternationalCallOnWifiDialogFragment.continueCall", "Continuing call with ID: %s", callId); InternationalCallOnWifiDialogActivity activity = FragmentUtils.getParent(this, InternationalCallOnWifiDialogActivity.class); if (activity != null) { activity.finish(); } } private void cancelCall(@NonNull String callId) { DialerCall call = CallList.getInstance().getCallById(callId); if (call == null) { LogUtil.i( "InternationalCallOnWifiDialogFragment.cancelCall", "Call destroyed before the dialog is closed"); } else { LogUtil.i( "InternationalCallOnWifiDialogFragment.cancelCall", "Disconnecting international call on WiFi"); call.disconnect(); } InternationalCallOnWifiDialogActivity activity = FragmentUtils.getParent(this, InternationalCallOnWifiDialogActivity.class); if (activity != null) { activity.finish(); } } }