Home | History | Annotate | Download | only in util
      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.messaging.util;
     18 
     19 import android.app.Activity;
     20 import android.app.Fragment;
     21 import android.content.ActivityNotFoundException;
     22 import android.content.Intent;
     23 import android.view.View;
     24 
     25 import com.android.messaging.R;
     26 import com.android.messaging.ui.SnackBar;
     27 import com.android.messaging.ui.UIIntents;
     28 
     29 public class ChangeDefaultSmsAppHelper {
     30     private Runnable mRunAfterMadeDefault;
     31     private ChangeSmsAppSettingRunnable mChangeSmsAppSettingRunnable;
     32 
     33     private static final int REQUEST_SET_DEFAULT_SMS_APP = 1;
     34 
     35     /**
     36      * When there's some condition that prevents an operation, such as sending a message,
     37      * call warnOfMissingActionConditions to put up a toast and allow the user to repair
     38      * that condition.
     39      * @param sending - true if we're called during a sending operation
     40      * @param runAfterMadeDefault - a runnable to run after the user responds
     41      *                  positively to the condition prompt and resolves the condition. It is
     42      *                  preferable to specify the value in {@link #handleChangeDefaultSmsResult}
     43      *                  as that handles the case where the process gets restarted.
     44      *                  If null, the user will be shown a generic toast message.
     45      * @param composeView - compose view that may have the keyboard opened and focused
     46      * @param rootView - if non-null, use this to attach a snackBar
     47      * @param activity - calling activity
     48      * @param fragment - calling fragment, may be null if called directly from an activity
     49      */
     50     public void warnOfMissingActionConditions(final boolean sending,
     51             final Runnable runAfterMadeDefault,
     52             final View composeView, final View rootView,
     53             final Activity activity, final Fragment fragment) {
     54         final PhoneUtils phoneUtils = PhoneUtils.getDefault();
     55         final boolean isSmsCapable = phoneUtils.isSmsCapable();
     56         final boolean hasPreferredSmsSim = phoneUtils.getHasPreferredSmsSim();
     57         final boolean isDefaultSmsApp = phoneUtils.isDefaultSmsApp();
     58 
     59         // Supports SMS?
     60         if (!isSmsCapable) {
     61             UiUtils.showToast(R.string.sms_disabled);
     62 
     63         // Has a preferred sim?
     64         } else if (!hasPreferredSmsSim) {
     65             UiUtils.showToast(R.string.no_preferred_sim_selected);
     66 
     67         // Is the default sms app?
     68         } else if (!isDefaultSmsApp) {
     69             mChangeSmsAppSettingRunnable = new ChangeSmsAppSettingRunnable(activity, fragment);
     70             promptToChangeDefaultSmsApp(sending, runAfterMadeDefault,
     71                     composeView, rootView, activity);
     72         }
     73 
     74         LogUtil.w(LogUtil.BUGLE_TAG, "Unsatisfied action condition: "
     75                 + "isSmsCapable=" + isSmsCapable + ", "
     76                 + "hasPreferredSmsSim=" + hasPreferredSmsSim + ", "
     77                 + "isDefaultSmsApp=" + isDefaultSmsApp);
     78     }
     79 
     80     private void promptToChangeDefaultSmsApp(final boolean sending,
     81             final Runnable runAfterMadeDefault,
     82             final View composeView, final View rootView,
     83             final Activity activity) {
     84         if (composeView != null) {
     85             // Avoid bug in system which puts soft keyboard over dialog after orientation change
     86             ImeUtil.hideSoftInput(activity, composeView);
     87         }
     88         mRunAfterMadeDefault = runAfterMadeDefault;
     89 
     90         if (rootView == null) {
     91             // Immediately open the system "Change default SMS app?" dialog setting.
     92             mChangeSmsAppSettingRunnable.run();
     93         } else {
     94             UiUtils.showSnackBarWithCustomAction(activity,
     95                     rootView,
     96                     activity.getString(sending ? R.string.requires_default_sms_app_to_send :
     97                         R.string.requires_default_sms_app),
     98                         SnackBar.Action.createCustomAction(mChangeSmsAppSettingRunnable,
     99                                 activity.getString(R.string.requires_default_sms_change_button)),
    100                                 null /* interactions */,
    101                                 SnackBar.Placement.above(composeView));
    102         }
    103     }
    104 
    105     private class ChangeSmsAppSettingRunnable implements Runnable {
    106         private final Activity mActivity;
    107         private final Fragment mFragment;
    108 
    109         public ChangeSmsAppSettingRunnable(final Activity activity, final Fragment fragment) {
    110             mActivity = activity;
    111             mFragment = fragment;
    112         }
    113 
    114         @Override
    115         public void run() {
    116             try {
    117                 final Intent intent = UIIntents.get().getChangeDefaultSmsAppIntent(mActivity);
    118                 if (mFragment != null) {
    119                     mFragment.startActivityForResult(intent, REQUEST_SET_DEFAULT_SMS_APP);
    120                 } else {
    121                     mActivity.startActivityForResult(intent, REQUEST_SET_DEFAULT_SMS_APP);
    122                 }
    123             } catch (final ActivityNotFoundException ex) {
    124                 // We shouldn't get here, but the monkey on JB MR0 can trigger it.
    125                 LogUtil.w(LogUtil.BUGLE_TAG, "Couldn't find activity:", ex);
    126                 UiUtils.showToastAtBottom(R.string.activity_not_found_message);
    127             }
    128         }
    129     }
    130 
    131     public void handleChangeDefaultSmsResult(
    132             final int requestCode,
    133             final int resultCode,
    134             Runnable runAfterMadeDefault) {
    135         Assert.isTrue(mRunAfterMadeDefault == null || runAfterMadeDefault == null);
    136         if (runAfterMadeDefault == null) {
    137             runAfterMadeDefault = mRunAfterMadeDefault;
    138         }
    139 
    140         if (requestCode == REQUEST_SET_DEFAULT_SMS_APP) {
    141             if (resultCode == Activity.RESULT_OK) {
    142                 // mRunAfterMadeDefault can be null if it was set only in
    143                 // promptToChangeDefaultSmsApp, and the process subsequently restarted when the
    144                 // user momentarily switched to another app. In that case, we'll simply show a
    145                 // generic toast since we do not know what the runnable was supposed to do.
    146                 if  (runAfterMadeDefault != null) {
    147                     runAfterMadeDefault.run();
    148                 } else {
    149                     UiUtils.showToast(R.string.toast_after_setting_default_sms_app);
    150                 }
    151             }
    152             mRunAfterMadeDefault = null;    // don't want to accidentally run it again
    153         }
    154     }
    155 }
    156 
    157 
    158