Home | History | Annotate | Download | only in settings
      1 /*
      2  * Copyright (C) 2008 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.settings;
     18 
     19 import android.app.Activity;
     20 import android.app.Dialog;
     21 import android.app.ProgressDialog;
     22 import android.content.BroadcastReceiver;
     23 import android.content.ContentResolver;
     24 import android.content.ContentUris;
     25 import android.content.ContentValues;
     26 import android.content.Context;
     27 import android.content.Intent;
     28 import android.content.IntentFilter;
     29 import android.database.Cursor;
     30 import android.net.Uri;
     31 import android.os.Bundle;
     32 import android.os.Handler;
     33 import android.os.HandlerThread;
     34 import android.os.Looper;
     35 import android.os.Message;
     36 import android.os.UserManager;
     37 import android.preference.Preference;
     38 import android.preference.PreferenceActivity;
     39 import android.preference.PreferenceGroup;
     40 import android.preference.PreferenceScreen;
     41 import android.provider.Telephony;
     42 import android.util.Log;
     43 import android.view.LayoutInflater;
     44 import android.view.Menu;
     45 import android.view.MenuInflater;
     46 import android.view.MenuItem;
     47 import android.view.View;
     48 import android.widget.TextView;
     49 import android.widget.Toast;
     50 
     51 import com.android.internal.telephony.Phone;
     52 import com.android.internal.telephony.PhoneConstants;
     53 import com.android.internal.telephony.TelephonyIntents;
     54 import com.android.internal.telephony.TelephonyProperties;
     55 
     56 import java.util.ArrayList;
     57 
     58 public class ApnSettings extends SettingsPreferenceFragment implements
     59         Preference.OnPreferenceChangeListener {
     60     static final String TAG = "ApnSettings";
     61 
     62     public static final String EXTRA_POSITION = "position";
     63     public static final String RESTORE_CARRIERS_URI =
     64         "content://telephony/carriers/restore";
     65     public static final String PREFERRED_APN_URI =
     66         "content://telephony/carriers/preferapn";
     67 
     68     public static final String APN_ID = "apn_id";
     69 
     70     private static final int ID_INDEX = 0;
     71     private static final int NAME_INDEX = 1;
     72     private static final int APN_INDEX = 2;
     73     private static final int TYPES_INDEX = 3;
     74 
     75     private static final int MENU_NEW = Menu.FIRST;
     76     private static final int MENU_RESTORE = Menu.FIRST + 1;
     77 
     78     private static final int EVENT_RESTORE_DEFAULTAPN_START = 1;
     79     private static final int EVENT_RESTORE_DEFAULTAPN_COMPLETE = 2;
     80 
     81     private static final int DIALOG_RESTORE_DEFAULTAPN = 1001;
     82 
     83     private static final Uri DEFAULTAPN_URI = Uri.parse(RESTORE_CARRIERS_URI);
     84     private static final Uri PREFERAPN_URI = Uri.parse(PREFERRED_APN_URI);
     85 
     86     private static boolean mRestoreDefaultApnMode;
     87 
     88     private RestoreApnUiHandler mRestoreApnUiHandler;
     89     private RestoreApnProcessHandler mRestoreApnProcessHandler;
     90     private HandlerThread mRestoreDefaultApnThread;
     91 
     92     private UserManager mUm;
     93 
     94     private String mSelectedKey;
     95 
     96     private IntentFilter mMobileStateFilter;
     97 
     98     private boolean mUnavailable;
     99 
    100     private final BroadcastReceiver mMobileStateReceiver = new BroadcastReceiver() {
    101         @Override
    102         public void onReceive(Context context, Intent intent) {
    103             if (intent.getAction().equals(
    104                     TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED)) {
    105                 PhoneConstants.DataState state = getMobileDataState(intent);
    106                 switch (state) {
    107                 case CONNECTED:
    108                     if (!mRestoreDefaultApnMode) {
    109                         fillList();
    110                     } else {
    111                         showDialog(DIALOG_RESTORE_DEFAULTAPN);
    112                     }
    113                     break;
    114                 }
    115             }
    116         }
    117     };
    118 
    119     private static PhoneConstants.DataState getMobileDataState(Intent intent) {
    120         String str = intent.getStringExtra(PhoneConstants.STATE_KEY);
    121         if (str != null) {
    122             return Enum.valueOf(PhoneConstants.DataState.class, str);
    123         } else {
    124             return PhoneConstants.DataState.DISCONNECTED;
    125         }
    126     }
    127 
    128     @Override
    129     public void onCreate(Bundle icicle) {
    130         super.onCreate(icicle);
    131 
    132         mUm = (UserManager) getSystemService(Context.USER_SERVICE);
    133 
    134         mMobileStateFilter = new IntentFilter(
    135                 TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
    136 
    137         if (!mUm.hasUserRestriction(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)) {
    138             setHasOptionsMenu(true);
    139         }
    140     }
    141 
    142     @Override
    143     public void onActivityCreated(Bundle savedInstanceState) {
    144         super.onActivityCreated(savedInstanceState);
    145 
    146         TextView empty = (TextView) getView().findViewById(android.R.id.empty);
    147         if (empty != null) {
    148             empty.setText(R.string.apn_settings_not_available);
    149             getListView().setEmptyView(empty);
    150         }
    151 
    152         if (mUm.hasUserRestriction(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)) {
    153             mUnavailable = true;
    154             setPreferenceScreen(new PreferenceScreen(getActivity(), null));
    155             return;
    156         }
    157 
    158         addPreferencesFromResource(R.xml.apn_settings);
    159 
    160         getListView().setItemsCanFocus(true);
    161     }
    162 
    163     @Override
    164     public void onResume() {
    165         super.onResume();
    166 
    167         if (mUnavailable) {
    168             return;
    169         }
    170 
    171         getActivity().registerReceiver(mMobileStateReceiver, mMobileStateFilter);
    172 
    173         if (!mRestoreDefaultApnMode) {
    174             fillList();
    175         }
    176     }
    177 
    178     @Override
    179     public void onPause() {
    180         super.onPause();
    181 
    182         if (mUnavailable) {
    183             return;
    184         }
    185 
    186         getActivity().unregisterReceiver(mMobileStateReceiver);
    187     }
    188 
    189     @Override
    190     public void onDestroy() {
    191         super.onDestroy();
    192 
    193         if (mRestoreDefaultApnThread != null) {
    194             mRestoreDefaultApnThread.quit();
    195         }
    196     }
    197 
    198     private void fillList() {
    199         String where = "numeric=\""
    200             + android.os.SystemProperties.get(TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC, "")
    201             + "\"";
    202 
    203         Cursor cursor = getContentResolver().query(Telephony.Carriers.CONTENT_URI, new String[] {
    204                 "_id", "name", "apn", "type"}, where, null,
    205                 Telephony.Carriers.DEFAULT_SORT_ORDER);
    206 
    207         if (cursor != null) {
    208             PreferenceGroup apnList = (PreferenceGroup) findPreference("apn_list");
    209             apnList.removeAll();
    210 
    211             ArrayList<Preference> mmsApnList = new ArrayList<Preference>();
    212 
    213             mSelectedKey = getSelectedApnKey();
    214             cursor.moveToFirst();
    215             while (!cursor.isAfterLast()) {
    216                 String name = cursor.getString(NAME_INDEX);
    217                 String apn = cursor.getString(APN_INDEX);
    218                 String key = cursor.getString(ID_INDEX);
    219                 String type = cursor.getString(TYPES_INDEX);
    220 
    221                 ApnPreference pref = new ApnPreference(getActivity());
    222 
    223                 pref.setKey(key);
    224                 pref.setTitle(name);
    225                 pref.setSummary(apn);
    226                 pref.setPersistent(false);
    227                 pref.setOnPreferenceChangeListener(this);
    228 
    229                 boolean selectable = ((type == null) || !type.equals("mms"));
    230                 pref.setSelectable(selectable);
    231                 if (selectable) {
    232                     if ((mSelectedKey != null) && mSelectedKey.equals(key)) {
    233                         pref.setChecked();
    234                     }
    235                     apnList.addPreference(pref);
    236                 } else {
    237                     mmsApnList.add(pref);
    238                 }
    239                 cursor.moveToNext();
    240             }
    241             cursor.close();
    242 
    243             for (Preference preference : mmsApnList) {
    244                 apnList.addPreference(preference);
    245             }
    246         }
    247     }
    248 
    249     @Override
    250     public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    251         if (!mUnavailable) {
    252             menu.add(0, MENU_NEW, 0,
    253                     getResources().getString(R.string.menu_new))
    254                     .setIcon(android.R.drawable.ic_menu_add)
    255                     .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
    256             menu.add(0, MENU_RESTORE, 0,
    257                     getResources().getString(R.string.menu_restore))
    258                     .setIcon(android.R.drawable.ic_menu_upload);
    259         }
    260 
    261         super.onCreateOptionsMenu(menu, inflater);
    262     }
    263 
    264     @Override
    265     public boolean onOptionsItemSelected(MenuItem item) {
    266         switch (item.getItemId()) {
    267         case MENU_NEW:
    268             addNewApn();
    269             return true;
    270 
    271         case MENU_RESTORE:
    272             restoreDefaultApn();
    273             return true;
    274         }
    275         return super.onOptionsItemSelected(item);
    276     }
    277 
    278     private void addNewApn() {
    279         startActivity(new Intent(Intent.ACTION_INSERT, Telephony.Carriers.CONTENT_URI));
    280     }
    281 
    282     @Override
    283     public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
    284         int pos = Integer.parseInt(preference.getKey());
    285         Uri url = ContentUris.withAppendedId(Telephony.Carriers.CONTENT_URI, pos);
    286         startActivity(new Intent(Intent.ACTION_EDIT, url));
    287         return true;
    288     }
    289 
    290     public boolean onPreferenceChange(Preference preference, Object newValue) {
    291         Log.d(TAG, "onPreferenceChange(): Preference - " + preference
    292                 + ", newValue - " + newValue + ", newValue type - "
    293                 + newValue.getClass());
    294         if (newValue instanceof String) {
    295             setSelectedApnKey((String) newValue);
    296         }
    297 
    298         return true;
    299     }
    300 
    301     private void setSelectedApnKey(String key) {
    302         mSelectedKey = key;
    303         ContentResolver resolver = getContentResolver();
    304 
    305         ContentValues values = new ContentValues();
    306         values.put(APN_ID, mSelectedKey);
    307         resolver.update(PREFERAPN_URI, values, null, null);
    308     }
    309 
    310     private String getSelectedApnKey() {
    311         String key = null;
    312 
    313         Cursor cursor = getContentResolver().query(PREFERAPN_URI, new String[] {"_id"},
    314                 null, null, Telephony.Carriers.DEFAULT_SORT_ORDER);
    315         if (cursor.getCount() > 0) {
    316             cursor.moveToFirst();
    317             key = cursor.getString(ID_INDEX);
    318         }
    319         cursor.close();
    320         return key;
    321     }
    322 
    323     private boolean restoreDefaultApn() {
    324         showDialog(DIALOG_RESTORE_DEFAULTAPN);
    325         mRestoreDefaultApnMode = true;
    326 
    327         if (mRestoreApnUiHandler == null) {
    328             mRestoreApnUiHandler = new RestoreApnUiHandler();
    329         }
    330 
    331         if (mRestoreApnProcessHandler == null ||
    332             mRestoreDefaultApnThread == null) {
    333             mRestoreDefaultApnThread = new HandlerThread(
    334                     "Restore default APN Handler: Process Thread");
    335             mRestoreDefaultApnThread.start();
    336             mRestoreApnProcessHandler = new RestoreApnProcessHandler(
    337                     mRestoreDefaultApnThread.getLooper(), mRestoreApnUiHandler);
    338         }
    339 
    340         mRestoreApnProcessHandler
    341                 .sendEmptyMessage(EVENT_RESTORE_DEFAULTAPN_START);
    342         return true;
    343     }
    344 
    345     private class RestoreApnUiHandler extends Handler {
    346         @Override
    347         public void handleMessage(Message msg) {
    348             switch (msg.what) {
    349                 case EVENT_RESTORE_DEFAULTAPN_COMPLETE:
    350                     Activity activity = getActivity();
    351                     if (activity == null) {
    352                         mRestoreDefaultApnMode = false;
    353                         return;
    354                     }
    355                     fillList();
    356                     getPreferenceScreen().setEnabled(true);
    357                     mRestoreDefaultApnMode = false;
    358                     removeDialog(DIALOG_RESTORE_DEFAULTAPN);
    359                     Toast.makeText(
    360                         activity,
    361                         getResources().getString(
    362                                 R.string.restore_default_apn_completed),
    363                         Toast.LENGTH_LONG).show();
    364                     break;
    365             }
    366         }
    367     }
    368 
    369     private class RestoreApnProcessHandler extends Handler {
    370         private Handler mRestoreApnUiHandler;
    371 
    372         public RestoreApnProcessHandler(Looper looper, Handler restoreApnUiHandler) {
    373             super(looper);
    374             this.mRestoreApnUiHandler = restoreApnUiHandler;
    375         }
    376 
    377         @Override
    378         public void handleMessage(Message msg) {
    379             switch (msg.what) {
    380                 case EVENT_RESTORE_DEFAULTAPN_START:
    381                     ContentResolver resolver = getContentResolver();
    382                     resolver.delete(DEFAULTAPN_URI, null, null);
    383                     mRestoreApnUiHandler
    384                         .sendEmptyMessage(EVENT_RESTORE_DEFAULTAPN_COMPLETE);
    385                     break;
    386             }
    387         }
    388     }
    389 
    390     @Override
    391     public Dialog onCreateDialog(int id) {
    392         if (id == DIALOG_RESTORE_DEFAULTAPN) {
    393             ProgressDialog dialog = new ProgressDialog(getActivity());
    394             dialog.setMessage(getResources().getString(R.string.restore_default_apn));
    395             dialog.setCancelable(false);
    396             return dialog;
    397         }
    398         return null;
    399     }
    400 }
    401