1 package com.android.phone;
2 
3 import android.app.ActionBar;
4 import android.content.ContentProvider;
5 import android.content.Intent;
6 import android.database.Cursor;
7 import android.os.Bundle;
8 import android.os.PersistableBundle;
9 import android.os.Process;
10 import android.os.UserHandle;
11 import android.preference.Preference;
12 import android.preference.PreferenceScreen;
13 import android.telephony.CarrierConfigManager;
14 import android.util.Log;
15 import android.view.MenuItem;
16 
17 import com.android.internal.telephony.CallForwardInfo;
18 import com.android.internal.telephony.CommandsInterface;
19 import com.android.internal.telephony.Phone;
20 
21 import java.util.ArrayList;
22 
23 public class GsmUmtsCallForwardOptions extends TimeConsumingPreferenceActivity {
24     private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
25     private static final String LOG_TAG = "GsmUmtsCallForwardOptions";
26 
27     private static final String NUM_PROJECTION[] = {
28         android.provider.ContactsContract.CommonDataKinds.Phone.NUMBER
29     };
30 
31     private static final String BUTTON_CFU_KEY   = "button_cfu_key";
32     private static final String BUTTON_CFB_KEY   = "button_cfb_key";
33     private static final String BUTTON_CFNRY_KEY = "button_cfnry_key";
34     private static final String BUTTON_CFNRC_KEY = "button_cfnrc_key";
35 
36     private static final String KEY_TOGGLE = "toggle";
37     private static final String KEY_STATUS = "status";
38     private static final String KEY_NUMBER = "number";
39     private static final String KEY_ENABLE = "enable";
40 
41     private CallForwardEditPreference mButtonCFU;
42     private CallForwardEditPreference mButtonCFB;
43     private CallForwardEditPreference mButtonCFNRy;
44     private CallForwardEditPreference mButtonCFNRc;
45 
46     private final ArrayList<CallForwardEditPreference> mPreferences =
47             new ArrayList<CallForwardEditPreference> ();
48     private int mInitIndex= 0;
49 
50     private boolean mFirstResume;
51     private Bundle mIcicle;
52     private Phone mPhone;
53     private SubscriptionInfoHelper mSubscriptionInfoHelper;
54     private boolean mReplaceInvalidCFNumbers;
55     private boolean mCallForwardByUssd;
56 
57     @Override
onCreate(Bundle icicle)58     protected void onCreate(Bundle icicle) {
59         super.onCreate(icicle);
60 
61         addPreferencesFromResource(R.xml.callforward_options);
62 
63         mSubscriptionInfoHelper = new SubscriptionInfoHelper(this, getIntent());
64         mSubscriptionInfoHelper.setActionBarTitle(
65                 getActionBar(), getResources(), R.string.call_forwarding_settings_with_label);
66         mPhone = mSubscriptionInfoHelper.getPhone();
67 
68         PersistableBundle b = null;
69         boolean supportCFB = true;
70         boolean supportCFNRc = true;
71         boolean supportCFNRy = true;
72         if (mSubscriptionInfoHelper.hasSubId()) {
73             b = PhoneGlobals.getInstance().getCarrierConfigForSubId(
74                     mSubscriptionInfoHelper.getSubId());
75         } else {
76             b = PhoneGlobals.getInstance().getCarrierConfig();
77         }
78         if (b != null) {
79             mReplaceInvalidCFNumbers = b.getBoolean(
80                     CarrierConfigManager.KEY_CALL_FORWARDING_MAP_NON_NUMBER_TO_VOICEMAIL_BOOL);
81             mCallForwardByUssd = b.getBoolean(
82                     CarrierConfigManager.KEY_USE_CALL_FORWARDING_USSD_BOOL);
83             supportCFB = b.getBoolean(
84                     CarrierConfigManager.KEY_CALL_FORWARDING_WHEN_BUSY_SUPPORTED_BOOL);
85             supportCFNRc = b.getBoolean(
86                     CarrierConfigManager.KEY_CALL_FORWARDING_WHEN_UNREACHABLE_SUPPORTED_BOOL);
87             supportCFNRy = b.getBoolean(
88                     CarrierConfigManager.KEY_CALL_FORWARDING_WHEN_UNANSWERED_SUPPORTED_BOOL);
89         }
90 
91         PreferenceScreen prefSet = getPreferenceScreen();
92         mButtonCFU = (CallForwardEditPreference) prefSet.findPreference(BUTTON_CFU_KEY);
93         mButtonCFB = (CallForwardEditPreference) prefSet.findPreference(BUTTON_CFB_KEY);
94         mButtonCFNRy = (CallForwardEditPreference) prefSet.findPreference(BUTTON_CFNRY_KEY);
95         mButtonCFNRc = (CallForwardEditPreference) prefSet.findPreference(BUTTON_CFNRC_KEY);
96 
97         mButtonCFU.setParentActivity(this, mButtonCFU.reason);
98         mButtonCFB.setParentActivity(this, mButtonCFB.reason);
99         mButtonCFNRy.setParentActivity(this, mButtonCFNRy.reason);
100         mButtonCFNRc.setParentActivity(this, mButtonCFNRc.reason);
101 
102         mPreferences.add(mButtonCFU);
103         layoutCallForwardItem(supportCFB, mButtonCFB, prefSet);
104         layoutCallForwardItem(supportCFNRy, mButtonCFNRy, prefSet);
105         layoutCallForwardItem(supportCFNRc, mButtonCFNRc, prefSet);
106 
107         if (mCallForwardByUssd) {
108             //the call forwarding ussd command's behavior is similar to the call forwarding when
109             //unanswered,so only display the call forwarding when unanswered item.
110             prefSet.removePreference(mButtonCFU);
111             prefSet.removePreference(mButtonCFB);
112             prefSet.removePreference(mButtonCFNRc);
113             mPreferences.remove(mButtonCFU);
114             mPreferences.remove(mButtonCFB);
115             mPreferences.remove(mButtonCFNRc);
116             mButtonCFNRy.setDependency(null);
117         }
118 
119         // we wait to do the initialization until onResume so that the
120         // TimeConsumingPreferenceActivity dialog can display as it
121         // relies on onResume / onPause to maintain its foreground state.
122 
123         mFirstResume = true;
124         mIcicle = icicle;
125 
126         ActionBar actionBar = getActionBar();
127         if (actionBar != null) {
128             // android.R.id.home will be triggered in onOptionsItemSelected()
129             actionBar.setDisplayHomeAsUpEnabled(true);
130         }
131     }
132 
layoutCallForwardItem(boolean support, CallForwardEditPreference preference, PreferenceScreen prefSet)133     private void layoutCallForwardItem(boolean support, CallForwardEditPreference preference,
134             PreferenceScreen prefSet) {
135         if (support) {
136             mPreferences.add(preference);
137         } else {
138             prefSet.removePreference(preference);
139         }
140     }
141 
142     @Override
onResume()143     public void onResume() {
144         super.onResume();
145 
146         if (mFirstResume) {
147             if (mIcicle == null) {
148                 Log.d(LOG_TAG, "start to init ");
149                 CallForwardEditPreference pref = mPreferences.get(mInitIndex);
150                 pref.init(this, mPhone, mReplaceInvalidCFNumbers, mCallForwardByUssd);
151                 pref.startCallForwardOptionsQuery();
152 
153             } else {
154                 mInitIndex = mPreferences.size();
155 
156                 for (CallForwardEditPreference pref : mPreferences) {
157                     Bundle bundle = mIcicle.getParcelable(pref.getKey());
158                     pref.setToggled(bundle.getBoolean(KEY_TOGGLE));
159                     pref.setEnabled(bundle.getBoolean(KEY_ENABLE));
160                     CallForwardInfo cf = new CallForwardInfo();
161                     cf.number = bundle.getString(KEY_NUMBER);
162                     cf.status = bundle.getInt(KEY_STATUS);
163                     pref.init(this, mPhone, mReplaceInvalidCFNumbers, mCallForwardByUssd);
164                     pref.restoreCallForwardInfo(cf);
165                 }
166             }
167             mFirstResume = false;
168             mIcicle = null;
169         }
170     }
171 
172     @Override
onSaveInstanceState(Bundle outState)173     protected void onSaveInstanceState(Bundle outState) {
174         super.onSaveInstanceState(outState);
175 
176         for (CallForwardEditPreference pref : mPreferences) {
177             Bundle bundle = new Bundle();
178             bundle.putBoolean(KEY_TOGGLE, pref.isToggled());
179             bundle.putBoolean(KEY_ENABLE, pref.isEnabled());
180             if (pref.callForwardInfo != null) {
181                 bundle.putString(KEY_NUMBER, pref.callForwardInfo.number);
182                 bundle.putInt(KEY_STATUS, pref.callForwardInfo.status);
183             }
184             outState.putParcelable(pref.getKey(), bundle);
185         }
186     }
187 
188     @Override
onFinished(Preference preference, boolean reading)189     public void onFinished(Preference preference, boolean reading) {
190         if (mInitIndex < mPreferences.size()-1 && !isFinishing()) {
191             mInitIndex++;
192             CallForwardEditPreference pref = mPreferences.get(mInitIndex);
193             pref.init(this, mPhone, mReplaceInvalidCFNumbers, mCallForwardByUssd);
194             pref.startCallForwardOptionsQuery();
195         }
196 
197         super.onFinished(preference, reading);
198     }
199 
200     @Override
onActivityResult(int requestCode, int resultCode, Intent data)201     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
202         Log.d(LOG_TAG, "onActivityResult: done");
203         if (resultCode != RESULT_OK) {
204             Log.d(LOG_TAG, "onActivityResult: contact picker result not OK.");
205             return;
206         }
207         Cursor cursor = null;
208         try {
209             // check if the URI returned by the user belongs to the user
210             final int currentUser = UserHandle.getUserId(Process.myUid());
211             if (currentUser
212                     != ContentProvider.getUserIdFromUri(data.getData(), currentUser)) {
213 
214                 Log.w(LOG_TAG, "onActivityResult: Contact data of different user, "
215                         + "cannot access");
216                 return;
217             }
218             cursor = getContentResolver().query(data.getData(),
219                 NUM_PROJECTION, null, null, null);
220             if ((cursor == null) || (!cursor.moveToFirst())) {
221                 Log.d(LOG_TAG, "onActivityResult: bad contact data, no results found.");
222                 return;
223             }
224 
225             switch (requestCode) {
226                 case CommandsInterface.CF_REASON_UNCONDITIONAL:
227                     mButtonCFU.onPickActivityResult(cursor.getString(0));
228                     break;
229                 case CommandsInterface.CF_REASON_BUSY:
230                     mButtonCFB.onPickActivityResult(cursor.getString(0));
231                     break;
232                 case CommandsInterface.CF_REASON_NO_REPLY:
233                     mButtonCFNRy.onPickActivityResult(cursor.getString(0));
234                     break;
235                 case CommandsInterface.CF_REASON_NOT_REACHABLE:
236                     mButtonCFNRc.onPickActivityResult(cursor.getString(0));
237                     break;
238                 default:
239                     // TODO: may need exception here.
240             }
241         } finally {
242             if (cursor != null) {
243                 cursor.close();
244             }
245         }
246     }
247 
248     @Override
onOptionsItemSelected(MenuItem item)249     public boolean onOptionsItemSelected(MenuItem item) {
250         final int itemId = item.getItemId();
251         if (itemId == android.R.id.home) {  // See ActionBar#setDisplayHomeAsUpEnabled()
252             CallFeaturesSetting.goUpToTopLevelSetting(this, mSubscriptionInfoHelper);
253             return true;
254         }
255         return super.onOptionsItemSelected(item);
256     }
257 }
258