Initial checkin of AOSP Messaging app.
b/23110861 Change-Id: I9aa980d7569247d6b2ca78f5dcb4502e1eaadb8a
This commit is contained in:
@@ -0,0 +1,406 @@
|
||||
/*
|
||||
* Copyright (C) 2015 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.messaging.ui.appsettings;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Dialog;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.UserManager;
|
||||
import android.preference.Preference;
|
||||
import android.preference.PreferenceFragment;
|
||||
import android.preference.PreferenceGroup;
|
||||
import android.preference.PreferenceScreen;
|
||||
import android.provider.Telephony;
|
||||
import android.support.v4.app.NavUtils;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.android.messaging.R;
|
||||
import com.android.messaging.datamodel.data.ParticipantData;
|
||||
import com.android.messaging.sms.ApnDatabase;
|
||||
import com.android.messaging.sms.BugleApnSettingsLoader;
|
||||
import com.android.messaging.ui.BugleActionBarActivity;
|
||||
import com.android.messaging.ui.UIIntents;
|
||||
import com.android.messaging.util.OsUtil;
|
||||
import com.android.messaging.util.PhoneUtils;
|
||||
|
||||
public class ApnSettingsActivity extends BugleActionBarActivity {
|
||||
private static final int DIALOG_RESTORE_DEFAULTAPN = 1001;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
// Display the fragment as the main content.
|
||||
final ApnSettingsFragment fragment = new ApnSettingsFragment();
|
||||
fragment.setSubId(getIntent().getIntExtra(UIIntents.UI_INTENT_EXTRA_SUB_ID,
|
||||
ParticipantData.DEFAULT_SELF_SUB_ID));
|
||||
getFragmentManager().beginTransaction()
|
||||
.replace(android.R.id.content, fragment)
|
||||
.commit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(final MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case android.R.id.home:
|
||||
NavUtils.navigateUpFromSameTask(this);
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Dialog onCreateDialog(int id) {
|
||||
if (id == DIALOG_RESTORE_DEFAULTAPN) {
|
||||
ProgressDialog dialog = new ProgressDialog(this);
|
||||
dialog.setMessage(getResources().getString(R.string.restore_default_apn));
|
||||
dialog.setCancelable(false);
|
||||
return dialog;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static class ApnSettingsFragment extends PreferenceFragment implements
|
||||
Preference.OnPreferenceChangeListener {
|
||||
public static final String EXTRA_POSITION = "position";
|
||||
|
||||
public static final String APN_ID = "apn_id";
|
||||
|
||||
private static final String[] APN_PROJECTION = {
|
||||
Telephony.Carriers._ID, // 0
|
||||
Telephony.Carriers.NAME, // 1
|
||||
Telephony.Carriers.APN, // 2
|
||||
Telephony.Carriers.TYPE // 3
|
||||
};
|
||||
private static final int ID_INDEX = 0;
|
||||
private static final int NAME_INDEX = 1;
|
||||
private static final int APN_INDEX = 2;
|
||||
private static final int TYPES_INDEX = 3;
|
||||
|
||||
private static final int MENU_NEW = Menu.FIRST;
|
||||
private static final int MENU_RESTORE = Menu.FIRST + 1;
|
||||
|
||||
private static final int EVENT_RESTORE_DEFAULTAPN_START = 1;
|
||||
private static final int EVENT_RESTORE_DEFAULTAPN_COMPLETE = 2;
|
||||
|
||||
private static boolean mRestoreDefaultApnMode;
|
||||
|
||||
private RestoreApnUiHandler mRestoreApnUiHandler;
|
||||
private RestoreApnProcessHandler mRestoreApnProcessHandler;
|
||||
private HandlerThread mRestoreDefaultApnThread;
|
||||
|
||||
private String mSelectedKey;
|
||||
|
||||
private static final ContentValues sCurrentNullMap;
|
||||
private static final ContentValues sCurrentSetMap;
|
||||
|
||||
private UserManager mUm;
|
||||
|
||||
private boolean mUnavailable;
|
||||
private int mSubId;
|
||||
|
||||
static {
|
||||
sCurrentNullMap = new ContentValues(1);
|
||||
sCurrentNullMap.putNull(Telephony.Carriers.CURRENT);
|
||||
|
||||
sCurrentSetMap = new ContentValues(1);
|
||||
sCurrentSetMap.put(Telephony.Carriers.CURRENT, "2"); // 2 for user-selected APN,
|
||||
// 1 for Bugle-selected APN
|
||||
}
|
||||
|
||||
private SQLiteDatabase mDatabase;
|
||||
|
||||
public void setSubId(final int subId) {
|
||||
mSubId = subId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle icicle) {
|
||||
super.onCreate(icicle);
|
||||
|
||||
mDatabase = ApnDatabase.getApnDatabase().getWritableDatabase();
|
||||
|
||||
if (OsUtil.isAtLeastL()) {
|
||||
mUm = (UserManager) getActivity().getSystemService(Context.USER_SERVICE);
|
||||
if (!mUm.hasUserRestriction(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)) {
|
||||
setHasOptionsMenu(true);
|
||||
}
|
||||
} else {
|
||||
setHasOptionsMenu(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
|
||||
final ListView lv = (ListView) getView().findViewById(android.R.id.list);
|
||||
TextView empty = (TextView) getView().findViewById(android.R.id.empty);
|
||||
if (empty != null) {
|
||||
empty.setText(R.string.apn_settings_not_available);
|
||||
lv.setEmptyView(empty);
|
||||
}
|
||||
|
||||
if (OsUtil.isAtLeastL() &&
|
||||
mUm.hasUserRestriction(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)) {
|
||||
mUnavailable = true;
|
||||
setPreferenceScreen(getPreferenceManager().createPreferenceScreen(getActivity()));
|
||||
return;
|
||||
}
|
||||
|
||||
addPreferencesFromResource(R.xml.apn_settings);
|
||||
|
||||
lv.setItemsCanFocus(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
|
||||
if (mUnavailable) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mRestoreDefaultApnMode) {
|
||||
fillList();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
|
||||
if (mUnavailable) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
|
||||
if (mRestoreDefaultApnThread != null) {
|
||||
mRestoreDefaultApnThread.quit();
|
||||
}
|
||||
}
|
||||
|
||||
private void fillList() {
|
||||
final String mccMnc = PhoneUtils.getMccMncString(PhoneUtils.get(mSubId).getMccMnc());
|
||||
|
||||
new AsyncTask<Void, Void, Cursor>() {
|
||||
@Override
|
||||
protected Cursor doInBackground(Void... params) {
|
||||
String selection = Telephony.Carriers.NUMERIC + " =?";
|
||||
String[] selectionArgs = new String[]{ mccMnc };
|
||||
final Cursor cursor = mDatabase.query(ApnDatabase.APN_TABLE, APN_PROJECTION,
|
||||
selection, selectionArgs, null, null, null, null);
|
||||
return cursor;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Cursor cursor) {
|
||||
if (cursor != null) {
|
||||
try {
|
||||
PreferenceGroup apnList = (PreferenceGroup)
|
||||
findPreference(getString(R.string.apn_list_pref_key));
|
||||
apnList.removeAll();
|
||||
|
||||
mSelectedKey = BugleApnSettingsLoader.getFirstTryApn(mDatabase, mccMnc);
|
||||
while (cursor.moveToNext()) {
|
||||
String name = cursor.getString(NAME_INDEX);
|
||||
String apn = cursor.getString(APN_INDEX);
|
||||
String key = cursor.getString(ID_INDEX);
|
||||
String type = cursor.getString(TYPES_INDEX);
|
||||
|
||||
if (BugleApnSettingsLoader.isValidApnType(type,
|
||||
BugleApnSettingsLoader.APN_TYPE_MMS)) {
|
||||
ApnPreference pref = new ApnPreference(getActivity());
|
||||
pref.setKey(key);
|
||||
pref.setTitle(name);
|
||||
pref.setSummary(apn);
|
||||
pref.setPersistent(false);
|
||||
pref.setOnPreferenceChangeListener(ApnSettingsFragment.this);
|
||||
pref.setSelectable(true);
|
||||
|
||||
// Turn on the radio button for the currently selected APN. If
|
||||
// there is no selected APN, don't select an APN.
|
||||
if ((mSelectedKey != null && mSelectedKey.equals(key))) {
|
||||
pref.setChecked();
|
||||
}
|
||||
apnList.addPreference(pref);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}.execute((Void) null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
if (!mUnavailable) {
|
||||
menu.add(0, MENU_NEW, 0,
|
||||
getResources().getString(R.string.menu_new_apn))
|
||||
.setIcon(R.drawable.ic_add_gray)
|
||||
.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
|
||||
menu.add(0, MENU_RESTORE, 0,
|
||||
getResources().getString(R.string.menu_restore_default_apn))
|
||||
.setIcon(android.R.drawable.ic_menu_upload);
|
||||
}
|
||||
|
||||
super.onCreateOptionsMenu(menu, inflater);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case MENU_NEW:
|
||||
addNewApn();
|
||||
return true;
|
||||
|
||||
case MENU_RESTORE:
|
||||
restoreDefaultApn();
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
private void addNewApn() {
|
||||
startActivity(UIIntents.get().getApnEditorIntent(getActivity(), null, mSubId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
|
||||
Preference preference) {
|
||||
startActivity(
|
||||
UIIntents.get().getApnEditorIntent(getActivity(), preference.getKey(), mSubId));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
if (newValue instanceof String) {
|
||||
setSelectedApnKey((String) newValue);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// current=2 means user selected APN
|
||||
private static final String UPDATE_SELECTION = Telephony.Carriers.CURRENT + " =?";
|
||||
private static final String[] UPDATE_SELECTION_ARGS = new String[] { "2" };
|
||||
private void setSelectedApnKey(final String key) {
|
||||
mSelectedKey = key;
|
||||
|
||||
// Make database changes not on the UI thread
|
||||
new AsyncTask<Void, Void, Void>() {
|
||||
@Override
|
||||
protected Void doInBackground(Void... params) {
|
||||
// null out the previous "current=2" APN
|
||||
mDatabase.update(ApnDatabase.APN_TABLE, sCurrentNullMap,
|
||||
UPDATE_SELECTION, UPDATE_SELECTION_ARGS);
|
||||
|
||||
// set the new "current" APN (2)
|
||||
String selection = Telephony.Carriers._ID + " =?";
|
||||
String[] selectionArgs = new String[]{ key };
|
||||
|
||||
mDatabase.update(ApnDatabase.APN_TABLE, sCurrentSetMap,
|
||||
selection, selectionArgs);
|
||||
return null;
|
||||
}
|
||||
}.execute((Void) null);
|
||||
}
|
||||
|
||||
private boolean restoreDefaultApn() {
|
||||
getActivity().showDialog(DIALOG_RESTORE_DEFAULTAPN);
|
||||
mRestoreDefaultApnMode = true;
|
||||
|
||||
if (mRestoreApnUiHandler == null) {
|
||||
mRestoreApnUiHandler = new RestoreApnUiHandler();
|
||||
}
|
||||
|
||||
if (mRestoreApnProcessHandler == null ||
|
||||
mRestoreDefaultApnThread == null) {
|
||||
mRestoreDefaultApnThread = new HandlerThread(
|
||||
"Restore default APN Handler: Process Thread");
|
||||
mRestoreDefaultApnThread.start();
|
||||
mRestoreApnProcessHandler = new RestoreApnProcessHandler(
|
||||
mRestoreDefaultApnThread.getLooper(), mRestoreApnUiHandler);
|
||||
}
|
||||
|
||||
mRestoreApnProcessHandler.sendEmptyMessage(EVENT_RESTORE_DEFAULTAPN_START);
|
||||
return true;
|
||||
}
|
||||
|
||||
private class RestoreApnUiHandler extends Handler {
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
switch (msg.what) {
|
||||
case EVENT_RESTORE_DEFAULTAPN_COMPLETE:
|
||||
fillList();
|
||||
getPreferenceScreen().setEnabled(true);
|
||||
mRestoreDefaultApnMode = false;
|
||||
final Activity activity = getActivity();
|
||||
activity.dismissDialog(DIALOG_RESTORE_DEFAULTAPN);
|
||||
Toast.makeText(activity, getResources().getString(
|
||||
R.string.restore_default_apn_completed), Toast.LENGTH_LONG)
|
||||
.show();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class RestoreApnProcessHandler extends Handler {
|
||||
private Handler mCachedRestoreApnUiHandler;
|
||||
|
||||
public RestoreApnProcessHandler(Looper looper, Handler restoreApnUiHandler) {
|
||||
super(looper);
|
||||
this.mCachedRestoreApnUiHandler = restoreApnUiHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
switch (msg.what) {
|
||||
case EVENT_RESTORE_DEFAULTAPN_START:
|
||||
ApnDatabase.forceBuildAndLoadApnTables();
|
||||
mCachedRestoreApnUiHandler.sendEmptyMessage(
|
||||
EVENT_RESTORE_DEFAULTAPN_COMPLETE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user