Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6c21dd47 authored by calvinpan's avatar calvinpan
Browse files

[Smart forwarding] Add UI for Smart Forwarding

Bug: 170178144
Test: By manual
1. Test turn on/turn off flow
2. Test enter phone number flow

Change-Id: I98be6f307f78b61020a15f72a3d4bf04089ead66
parent e077e39a
Loading
Loading
Loading
Loading
+102 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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.settings.sim.smartForwarding;

import static com.android.settings.sim.smartForwarding.MDNHandlerHeaderFragment.KEY_SLOT0_PHONE_NUMBER;
import static com.android.settings.sim.smartForwarding.MDNHandlerHeaderFragment.KEY_SLOT1_PHONE_NUMBER;

import android.app.AlertDialog;
import android.app.settings.SettingsEnums;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;

import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;

import com.android.settings.R;
import com.android.settingslib.core.instrumentation.Instrumentable;

public class MDNHandlerFragment extends Fragment implements Instrumentable {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.xml.smart_forwarding_mdn_handler, container, false);
        getActivity().getActionBar().setTitle(
                getResources().getString(R.string.smart_forwarding_input_mdn_title));

        Button processBtn = view.findViewById(R.id.process);
        processBtn.setOnClickListener((View v)-> {
            pressButtonOnClick();
        });

        Button cancelBtn = view.findViewById(R.id.cancel);
        cancelBtn.setOnClickListener((View v)-> {
            switchToMainFragment(true);
        });
        return view;
    }

    private void pressButtonOnClick() {
        // Get the phone number from the UI
        MDNHandlerHeaderFragment fragment = (MDNHandlerHeaderFragment) this
                .getChildFragmentManager()
                .findFragmentById(R.id.fragment_settings);

        String slot0Number = "";
        String slot1Number = "";
        if (fragment != null) {
            slot0Number = fragment.findPreference(KEY_SLOT0_PHONE_NUMBER)
                    .getSummary().toString();
            slot1Number = fragment.findPreference(KEY_SLOT1_PHONE_NUMBER)
                    .getSummary().toString();
        }
        final String[] phoneNumber = {slot1Number, slot0Number};

        // If phone number is empty, popup an alert dialog
        if(TextUtils.isEmpty(phoneNumber[0])
                || TextUtils.isEmpty(phoneNumber[1])) {
            new AlertDialog.Builder(getActivity())
                    .setTitle(R.string.smart_forwarding_failed_title)
                    .setMessage(R.string.smart_forwarding_missing_mdn_text)
                    .setPositiveButton(
                            R.string.smart_forwarding_missing_alert_dialog_text,
                            (dialog, which) -> { dialog.dismiss(); })
                    .create()
                    .show();
        } else {
            switchToMainFragment(false);
            ((SmartForwardingActivity)getActivity()).enableSmartForwarding(phoneNumber);
        }
    }

    private void switchToMainFragment(boolean turnoffSwitch) {
        FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
        fragmentManager.beginTransaction()
                .replace(R.id.content_frame, new SmartForwardingFragment(turnoffSwitch))
                .commit();
    }

    @Override
    public int getMetricsCategory() {
        return SettingsEnums.MOBILE_NETWORK;
    }
}
+78 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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.settings.sim.smartForwarding;

import static com.android.settings.sim.smartForwarding.SmartForwardingUtils.getPhoneNumber;

import android.app.settings.SettingsEnums;
import android.os.Bundle;
import android.text.InputType;
import android.widget.EditText;

import androidx.annotation.NonNull;
import androidx.preference.EditTextPreference;
import androidx.preference.EditTextPreference.OnBindEditTextListener;
import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;

import com.android.settings.R;
import com.android.settingslib.core.instrumentation.Instrumentable;

public class MDNHandlerHeaderFragment extends PreferenceFragmentCompat
        implements Preference.OnPreferenceChangeListener, OnBindEditTextListener, Instrumentable {

    public static final String KEY_SLOT0_PHONE_NUMBER = "slot0_phone_number";
    public static final String KEY_SLOT1_PHONE_NUMBER = "slot1_phone_number";

    public MDNHandlerHeaderFragment() {}

    @Override
    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
        setPreferencesFromResource(R.xml.smart_forwarding_mdn_handler_header, rootKey);

        EditTextPreference slot0EditText = findPreference(KEY_SLOT0_PHONE_NUMBER);
        slot0EditText.setOnBindEditTextListener(this);
        slot0EditText.setOnPreferenceChangeListener(this);
        String slot0PhoneNumber = getPhoneNumber(getContext(), 0);
        slot0EditText.setSummary(slot0PhoneNumber);
        slot0EditText.setText(slot0PhoneNumber);

        EditTextPreference slot1EditText = findPreference(KEY_SLOT1_PHONE_NUMBER);
        slot1EditText.setOnPreferenceChangeListener(this);
        slot1EditText.setOnBindEditTextListener(this);
        String slot1PhoneNumber = getPhoneNumber(getContext(), 1);
        slot1EditText.setSummary(slot1PhoneNumber);
        slot1EditText.setText(slot1PhoneNumber);
    }

    @Override
    public boolean onPreferenceChange(Preference preference, Object newValue) {
        preference.setSummary(newValue.toString());
        return true;
    }

    @Override
    public void onBindEditText(@NonNull EditText editText) {
        editText.setInputType(InputType.TYPE_CLASS_PHONE);
        editText.setSingleLine(true);
    }

    @Override
    public int getMetricsCategory() {
        return SettingsEnums.MOBILE_NETWORK;
    }
}
+169 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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.settings.sim.smartForwarding;

import static com.android.settings.sim.smartForwarding.EnableSmartForwardingTask.FeatureResult;
import static com.android.settings.sim.smartForwarding.SmartForwardingUtils.TAG;
import static com.android.settings.sim.smartForwarding.SmartForwardingUtils.backupPrevStatus;
import static com.android.settings.sim.smartForwarding.SmartForwardingUtils.clearAllBackupData;
import static com.android.settings.sim.smartForwarding.SmartForwardingUtils.getAllSlotCallForwardingStatus;
import static com.android.settings.sim.smartForwarding.SmartForwardingUtils.getAllSlotCallWaitingStatus;

import android.app.ActionBar;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.telephony.CallForwardingInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.View;
import android.widget.Toolbar;

import androidx.core.content.ContextCompat;

import com.android.settings.R;
import com.android.settings.core.SettingsBaseActivity;

import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;

import java.util.concurrent.Executors;

public class SmartForwardingActivity extends SettingsBaseActivity {
    final ListeningExecutorService service =
            MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor());

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        final Toolbar toolbar = findViewById(R.id.action_bar);
        toolbar.setVisibility(View.VISIBLE);
        setActionBar(toolbar);

        final ActionBar actionBar = getActionBar();
        if (actionBar != null) {
            actionBar.setDisplayHomeAsUpEnabled(true);
        }

        getSupportFragmentManager()
                .beginTransaction()
                .replace(R.id.content_frame, new SmartForwardingFragment())
                .commit();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
    }

    public void enableSmartForwarding(String[] phoneNumber) {
        // Pop-up ongoing dialog
        ProgressDialog dialog = new ProgressDialog(this);
        dialog.setTitle(R.string.smart_forwarding_ongoing_title);
        dialog.setIndeterminate(true);
        dialog.setMessage(getText(R.string.smart_forwarding_ongoing_text));
        dialog.setCancelable(false);
        dialog.show();

        // Enable feature
        ListenableFuture<FeatureResult> enableTask =
                service.submit(new EnableSmartForwardingTask(this, phoneNumber));
        Futures.addCallback(enableTask, new FutureCallback<FeatureResult>() {
            @Override
            public void onSuccess(FeatureResult result) {
                Log.e(TAG, "Enable Feature result: " + result.getResult());
                if (result.getResult()) {
                    backupPrevStatus(SmartForwardingActivity.this, result.getSlotUTData());

                    // Turn on switch preference
                    SmartForwardingFragment fragment =
                            (SmartForwardingFragment) getSupportFragmentManager()
                                    .findFragmentById(R.id.content_frame);
                    if (fragment != null) {
                        fragment.turnOnSwitchPreference();
                    }
                } else {
                    onError(result);
                }
                dialog.dismiss();
            }

            @Override
            public void onFailure(Throwable t) {
                Log.e(TAG, "Enable Feature exception", t);
                dialog.dismiss();

                // Pop-up error dialog
                AlertDialog mDialog = new AlertDialog.Builder(SmartForwardingActivity.this)
                        .setTitle(R.string.smart_forwarding_failed_title)
                        .setMessage(R.string.smart_forwarding_failed_text)
                        .setPositiveButton(
                                R.string.smart_forwarding_missing_alert_dialog_text,
                                (dialog, which) -> { dialog.dismiss(); })
                        .create();
                mDialog.show();
            }
        }, ContextCompat.getMainExecutor(this));
    }

    public void disableSmartForwarding() {
        TelephonyManager tm = getSystemService(TelephonyManager.class);
        SubscriptionManager sm = getSystemService(SubscriptionManager.class);

        boolean[] callWaitingStatus = getAllSlotCallWaitingStatus(this, sm, tm);
        CallForwardingInfo[] callForwardingInfo = getAllSlotCallForwardingStatus(this, sm, tm);

        // Disable feature
        ListenableFuture disableTask = service.submit(new DisableSmartForwardingTask(
                tm, callWaitingStatus, callForwardingInfo));
        Futures.addCallback(disableTask, new FutureCallback() {
            @Override
            public void onSuccess(Object result) {
                clearAllBackupData(SmartForwardingActivity.this, sm, tm);
            }

            @Override
            public void onFailure(Throwable t) {
                Log.e(TAG, "Disable Feature exception" + t);
            }
        }, ContextCompat.getMainExecutor(this));
    }

    public void onError(FeatureResult result) {
        int errorMsg;
        if (result.getReason() == FeatureResult.FailedReason.SIM_NOT_ACTIVE) {
            errorMsg = R.string.smart_forwarding_failed_not_activated_text;
        } else {
            errorMsg = R.string.smart_forwarding_failed_text;
        }

        // Pop-up error dialog
        AlertDialog mDialog = new AlertDialog.Builder(SmartForwardingActivity.this)
                .setTitle(R.string.smart_forwarding_failed_title)
                .setMessage(errorMsg)
                .setPositiveButton(
                        R.string.smart_forwarding_missing_alert_dialog_text,
                        (dialog, which) -> { dialog.dismiss(); })
                .create();
        mDialog.show();
    }
}
 No newline at end of file
+104 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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.settings.sim.smartForwarding;

import static com.android.settings.sim.smartForwarding.SmartForwardingUtils.TAG;
import static com.android.settings.sim.smartForwarding.SmartForwardingUtils.getPhoneNumber;

import android.app.settings.SettingsEnums;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;

import androidx.fragment.app.FragmentManager;
import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.SwitchPreference;

import com.android.settings.R;
import com.android.settingslib.core.instrumentation.Instrumentable;

public class SmartForwardingFragment extends PreferenceFragmentCompat
        implements Preference.OnPreferenceChangeListener, Instrumentable {

    private static final String KEY_SMART_FORWARDING_SWITCH = "smart_forwarding_switch";
    private boolean turnOffSwitch;

    public SmartForwardingFragment() { }

    public SmartForwardingFragment(boolean turnOffSwitch) {
        this.turnOffSwitch = turnOffSwitch;
    }

    @Override
    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
        setPreferencesFromResource(R.xml.smart_forwarding_switch, rootKey);

        String title = getResources().getString(R.string.smart_forwarding_title);
        getActivity().getActionBar().setTitle(title);

        SwitchPreference smartForwardingSwitch = findPreference(KEY_SMART_FORWARDING_SWITCH);
        if (turnOffSwitch) {
            smartForwardingSwitch.setChecked(false);
        }
        smartForwardingSwitch.setOnPreferenceChangeListener(this);
    }

    @Override
    public boolean onPreferenceChange(Preference preference, Object newValue) {
        boolean value = (boolean) newValue;

        Log.d(TAG, "onPreferenceChange. Update value to " + value);

        if (value) {
            String slot0PhoneNumber = getPhoneNumber(getContext(), 0);
            String slot1PhoneNumber = getPhoneNumber(getContext(), 1);

            String[] phoneNumber = new String[]{slot1PhoneNumber, slot0PhoneNumber};

            if (TextUtils.isEmpty(slot0PhoneNumber) || TextUtils.isEmpty(slot1PhoneNumber)) {
                Log.d(TAG, "Slot 0 or Slot 1 phone number missing.");
                switchToMDNFragment();
            } else {
                ((SmartForwardingActivity) getActivity()).enableSmartForwarding(phoneNumber);
            }
            return false;
        } else {
            ((SmartForwardingActivity) getActivity()).disableSmartForwarding();
        }

        return true;
    }


    private void switchToMDNFragment() {
        FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
        fragmentManager.beginTransaction()
                .replace(R.id.content_frame, new MDNHandlerFragment())
                .commit();
    }

    public void turnOnSwitchPreference() {
        SwitchPreference smartForwardingSwitch = findPreference(KEY_SMART_FORWARDING_SWITCH);
        smartForwardingSwitch.setChecked(true);
    }

    @Override
    public int getMetricsCategory() {
        return SettingsEnums.MOBILE_NETWORK;
    }
}