Messaging: Remove GServices

We don't have an actual implementation returning anything but the
defaults, so apply the defaults directly anywhere we need them

Change-Id: Ic651b4b13977799f2f4d2c702c430798fbff77f8
This commit is contained in:
Michael W
2024-12-26 14:55:12 +01:00
parent 7f22a3eea7
commit a2f67b4f7b
64 changed files with 91 additions and 3763 deletions
@@ -154,11 +154,6 @@ public abstract class UIIntents {
public abstract void launchCreateNewConversationActivity(final Context context,
final MessageData draft);
/**
* Launch debug activity to set MMS config options.
*/
public abstract void launchDebugMmsConfigActivity(final Context context);
/**
* Launch an activity to change settings.
*/
@@ -325,16 +320,6 @@ public abstract class UIIntents {
public abstract PendingIntent getPendingIntentForSecondaryUserNewMessageNotification(
final Context context);
/**
* Get an intent for showing the APN editor.
*/
public abstract Intent getApnEditorIntent(final Context context, final String rowId, int subId);
/**
* Get an intent for showing the APN settings.
*/
public abstract Intent getApnSettingsIntent(final Context context, final int subId);
/**
* Get an intent for showing advanced settings.
*/
@@ -23,7 +23,6 @@ import android.app.role.RoleManager;
import android.appwidget.AppWidgetManager;
import android.content.ActivityNotFoundException;
import android.content.ClipData;
import android.content.ComponentName;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
@@ -34,7 +33,7 @@ import android.os.Bundle;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Intents;
import android.provider.MediaStore;
import android.provider.Telephony;
import androidx.annotation.Nullable;
import androidx.core.app.TaskStackBuilder;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
@@ -50,8 +49,6 @@ import com.android.messaging.datamodel.data.MessagePartData;
import com.android.messaging.datamodel.data.ParticipantData;
import com.android.messaging.receiver.NotificationReceiver;
import com.android.messaging.sms.MmsSmsUtils;
import com.android.messaging.ui.appsettings.ApnEditorActivity;
import com.android.messaging.ui.appsettings.ApnSettingsActivity;
import com.android.messaging.ui.appsettings.ApplicationSettingsActivity;
import com.android.messaging.ui.appsettings.PerSubscriptionSettingsActivity;
import com.android.messaging.ui.appsettings.SettingsActivity;
@@ -62,7 +59,6 @@ import com.android.messaging.ui.conversationlist.ArchivedConversationListActivit
import com.android.messaging.ui.conversationlist.ConversationListActivity;
import com.android.messaging.ui.conversationlist.ForwardMessageActivity;
import com.android.messaging.ui.conversationsettings.PeopleAndOptionsActivity;
import com.android.messaging.ui.debug.DebugMmsConfigActivity;
import com.android.messaging.ui.photoviewer.BuglePhotoViewActivity;
import com.android.messaging.util.Assert;
import com.android.messaging.util.ContentType;
@@ -192,11 +188,6 @@ public class UIIntentsImpl extends UIIntents {
context.startActivity(intent);
}
@Override
public void launchDebugMmsConfigActivity(final Context context) {
context.startActivity(new Intent(context, DebugMmsConfigActivity.class));
}
@Override
public void launchAddContactActivity(final Context context, final String destination) {
final Intent intent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
@@ -449,21 +440,6 @@ public class UIIntentsImpl extends UIIntents {
return getPendingIntentForConversationListActivity(context);
}
@Override
public Intent getApnEditorIntent(final Context context, final String rowId, final int subId) {
final Intent intent = new Intent(context, ApnEditorActivity.class);
intent.putExtra(UI_INTENT_EXTRA_APN_ROW_ID, rowId);
intent.putExtra(UI_INTENT_EXTRA_SUB_ID, subId);
return intent;
}
@Override
public Intent getApnSettingsIntent(final Context context, final int subId) {
final Intent intent = new Intent(context, ApnSettingsActivity.class)
.putExtra(UI_INTENT_EXTRA_SUB_ID, subId);
return intent;
}
@Override
public Intent getAdvancedSettingsIntent(final Context context) {
return getPerSubscriptionSettingsIntent(context, ParticipantData.DEFAULT_SELF_SUB_ID, null);
@@ -1,466 +0,0 @@
/*
* Copyright (C) 2015 The Android Open Source Project
* Copyright (C) 2024 The LineageOS 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.AlertDialog;
import android.app.Dialog;
import android.content.ContentValues;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.EditTextPreference;
import android.preference.Preference;
import android.preference.PreferenceFragment;
import android.provider.Telephony;
import androidx.annotation.NonNull;
import androidx.core.app.NavUtils;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
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.PhoneUtils;
public class ApnEditorActivity extends BugleActionBarActivity {
private static final int ERROR_DIALOG_ID = 0;
private static final String ERROR_MESSAGE_KEY = "error_msg";
private ApnEditorFragment mApnEditorFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
// Display the fragment as the main content.
mApnEditorFragment = new ApnEditorFragment();
mApnEditorFragment.setSubId(getIntent().getIntExtra(UIIntents.UI_INTENT_EXTRA_SUB_ID,
ParticipantData.DEFAULT_SELF_SUB_ID));
getFragmentManager().beginTransaction()
.replace(android.R.id.content, mApnEditorFragment)
.commit();
}
@Override
public boolean onOptionsItemSelected(@NonNull 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, Bundle args) {
if (id == ERROR_DIALOG_ID) {
String msg = args.getString(ERROR_MESSAGE_KEY);
return new AlertDialog.Builder(this)
.setPositiveButton(android.R.string.ok, null)
.setMessage(msg)
.create();
}
return super.onCreateDialog(id);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_BACK: {
if (mApnEditorFragment.validateAndSave(false)) {
finish();
}
return true;
}
}
return super.onKeyDown(keyCode, event);
}
@Override
protected void onPrepareDialog(int id, Dialog dialog, Bundle args) {
super.onPrepareDialog(id, dialog);
if (id == ERROR_DIALOG_ID) {
final String msg = args.getString(ERROR_MESSAGE_KEY);
if (msg != null) {
((AlertDialog) dialog).setMessage(msg);
}
}
}
public static class ApnEditorFragment extends PreferenceFragment implements
SharedPreferences.OnSharedPreferenceChangeListener {
private static final String SAVED_POS = "pos";
private static final int MENU_DELETE = Menu.FIRST;
private static final int MENU_SAVE = Menu.FIRST + 1;
private static final int MENU_CANCEL = Menu.FIRST + 2;
private EditTextPreference mMmsProxy;
private EditTextPreference mMmsPort;
private EditTextPreference mName;
private EditTextPreference mMmsc;
private EditTextPreference mMcc;
private EditTextPreference mMnc;
private static String sNotSet;
private String mCurMnc;
private String mCurMcc;
private Cursor mCursor;
private boolean mNewApn;
private boolean mFirstTime;
private String mCurrentId;
private int mSubId;
/**
* Standard projection for the interesting columns of a normal note.
*/
private static final String[] sProjection = new String[] {
Telephony.Carriers._ID, // 0
Telephony.Carriers.NAME, // 1
Telephony.Carriers.MMSC, // 2
Telephony.Carriers.MCC, // 3
Telephony.Carriers.MNC, // 4
Telephony.Carriers.NUMERIC, // 5
Telephony.Carriers.MMSPROXY, // 6
Telephony.Carriers.MMSPORT, // 7
Telephony.Carriers.TYPE, // 8
};
private static final int ID_INDEX = 0;
private static final int NAME_INDEX = 1;
private static final int MMSC_INDEX = 2;
private static final int MCC_INDEX = 3;
private static final int MNC_INDEX = 4;
private static final int NUMERIC_INDEX = 5;
private static final int MMSPROXY_INDEX = 6;
private static final int MMSPORT_INDEX = 7;
private static final int TYPE_INDEX = 8;
private SQLiteDatabase mDatabase;
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
addPreferencesFromResource(R.xml.apn_editor);
setHasOptionsMenu(true);
sNotSet = getResources().getString(R.string.apn_not_set);
mName = (EditTextPreference) findPreference("apn_name");
mMmsProxy = (EditTextPreference) findPreference("apn_mms_proxy");
mMmsPort = (EditTextPreference) findPreference("apn_mms_port");
mMmsc = (EditTextPreference) findPreference("apn_mmsc");
mMcc = (EditTextPreference) findPreference("apn_mcc");
mMnc = (EditTextPreference) findPreference("apn_mnc");
final Intent intent = getActivity().getIntent();
mFirstTime = savedInstanceState == null;
mCurrentId = intent.getStringExtra(UIIntents.UI_INTENT_EXTRA_APN_ROW_ID);
mNewApn = mCurrentId == null;
mDatabase = ApnDatabase.getApnDatabase().getWritableDatabase();
if (mNewApn) {
fillUi();
} else {
// Do initial query not on the UI thread
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
if (mCurrentId != null) {
String selection = Telephony.Carriers._ID + " =?";
String[] selectionArgs = new String[]{ mCurrentId };
mCursor = mDatabase.query(ApnDatabase.APN_TABLE, sProjection, selection,
selectionArgs, null, null, null, null);
}
return null;
}
@Override
protected void onPostExecute(Void result) {
if (mCursor == null) {
getActivity().finish();
return;
}
mCursor.moveToFirst();
fillUi();
}
}.execute((Void) null);
}
}
@Override
public void onDestroy() {
super.onDestroy();
if (mCursor != null) {
mCursor.close();
mCursor = null;
}
}
@Override
public void onResume() {
super.onResume();
getPreferenceScreen().getSharedPreferences()
.registerOnSharedPreferenceChangeListener(this);
}
@Override
public void onPause() {
getPreferenceScreen().getSharedPreferences()
.unregisterOnSharedPreferenceChangeListener(this);
super.onPause();
}
public void setSubId(final int subId) {
mSubId = subId;
}
private void fillUi() {
if (mNewApn) {
mMcc.setText(null);
mMnc.setText(null);
String numeric = PhoneUtils.get(mSubId).getSimOperatorNumeric();
// MCC is first 3 chars and then in 2 - 3 chars of MNC
if (numeric != null && numeric.length() > 4) {
// Country code
String mcc = numeric.substring(0, 3);
// Network code
String mnc = numeric.substring(3);
// Auto populate MNC and MCC for new entries, based on what SIM reports
mMcc.setText(mcc);
mMnc.setText(mnc);
mCurMnc = mnc;
mCurMcc = mcc;
}
mName.setText(null);
mMmsProxy.setText(null);
mMmsPort.setText(null);
mMmsc.setText(null);
} else if (mFirstTime) {
mFirstTime = false;
// Fill in all the values from the db in both text editor and summary
mName.setText(mCursor.getString(NAME_INDEX));
mMmsProxy.setText(mCursor.getString(MMSPROXY_INDEX));
mMmsPort.setText(mCursor.getString(MMSPORT_INDEX));
mMmsc.setText(mCursor.getString(MMSC_INDEX));
mMcc.setText(mCursor.getString(MCC_INDEX));
mMnc.setText(mCursor.getString(MNC_INDEX));
}
mName.setSummary(checkNull(mName.getText()));
mMmsProxy.setSummary(checkNull(mMmsProxy.getText()));
mMmsPort.setSummary(checkNull(mMmsPort.getText()));
mMmsc.setSummary(checkNull(mMmsc.getText()));
mMcc.setSummary(checkNull(mMcc.getText()));
mMnc.setSummary(checkNull(mMnc.getText()));
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
// If it's a new APN, then cancel will delete the new entry in onPause
if (!mNewApn) {
menu.add(0, MENU_DELETE, 0, R.string.menu_delete_apn)
.setIcon(R.drawable.ic_delete_small_dark);
}
menu.add(0, MENU_SAVE, 0, R.string.menu_save_apn)
.setIcon(android.R.drawable.ic_menu_save);
menu.add(0, MENU_CANCEL, 0, R.string.menu_discard_apn_change)
.setIcon(android.R.drawable.ic_menu_close_clear_cancel);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case MENU_DELETE:
deleteApn();
return true;
case MENU_SAVE:
if (validateAndSave(false)) {
getActivity().finish();
}
return true;
case MENU_CANCEL:
getActivity().finish();
return true;
case android.R.id.home:
getActivity().onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public void onSaveInstanceState(Bundle icicle) {
super.onSaveInstanceState(icicle);
if (validateAndSave(true) && mCursor != null) {
icicle.putInt(SAVED_POS, mCursor.getInt(ID_INDEX));
}
}
/**
* Check the key fields' validity and save if valid.
* @param force save even if the fields are not valid, if the app is
* being suspended
* @return true if the data was saved
*/
private boolean validateAndSave(boolean force) {
final String name = checkNotSet(mName.getText());
final String mcc = checkNotSet(mMcc.getText());
final String mnc = checkNotSet(mMnc.getText());
if (getErrorMsg() != null && !force) {
final Bundle bundle = new Bundle();
bundle.putString(ERROR_MESSAGE_KEY, getErrorMsg());
getActivity().showDialog(ERROR_DIALOG_ID, bundle);
return false;
}
// Make database changes not on the UI thread
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
ContentValues values = new ContentValues();
// Add a placeholder name "Untitled", if the user exits the screen without
// adding a name but entered other information worth keeping.
values.put(Telephony.Carriers.NAME, name.length() < 1 ?
getResources().getString(R.string.untitled_apn) : name);
values.put(Telephony.Carriers.MMSPROXY, checkNotSet(mMmsProxy.getText()));
values.put(Telephony.Carriers.MMSPORT, checkNotSet(mMmsPort.getText()));
values.put(Telephony.Carriers.MMSC, checkNotSet(mMmsc.getText()));
values.put(Telephony.Carriers.TYPE, BugleApnSettingsLoader.APN_TYPE_MMS);
values.put(Telephony.Carriers.MCC, mcc);
values.put(Telephony.Carriers.MNC, mnc);
values.put(Telephony.Carriers.NUMERIC, mcc + mnc);
if (mCurMnc != null && mCurMcc != null) {
if (mCurMnc.equals(mnc) && mCurMcc.equals(mcc)) {
values.put(Telephony.Carriers.CURRENT, 1);
}
}
if (mNewApn) {
mDatabase.insert(ApnDatabase.APN_TABLE, null, values);
} else {
// update the APN
String selection = Telephony.Carriers._ID + " =?";
String[] selectionArgs = new String[]{ mCurrentId };
int updated = mDatabase.update(ApnDatabase.APN_TABLE, values,
selection, selectionArgs);
}
return null;
}
}.execute((Void) null);
return true;
}
private void deleteApn() {
// Make database changes not on the UI thread
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
// delete the APN
String where = Telephony.Carriers._ID + " =?";
String[] whereArgs = new String[]{ mCurrentId };
mDatabase.delete(ApnDatabase.APN_TABLE, where, whereArgs);
return null;
}
}.execute((Void) null);
getActivity().finish();
}
private String checkNull(String value) {
if (value == null || value.length() == 0) {
return sNotSet;
} else {
return value;
}
}
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
Preference pref = findPreference(key);
if (pref != null) {
pref.setSummary(checkNull(sharedPreferences.getString(key, "")));
}
}
private String getErrorMsg() {
String errorMsg = null;
String name = checkNotSet(mName.getText());
String mcc = checkNotSet(mMcc.getText());
String mnc = checkNotSet(mMnc.getText());
if (name.length() < 1) {
errorMsg = getString(R.string.error_apn_name_empty);
} else if (mcc.length() != 3) {
errorMsg = getString(R.string.error_mcc_not3);
} else if ((mnc.length() & 0xFFFE) != 2) {
errorMsg = getString(R.string.error_mnc_not23);
}
return errorMsg;
}
private String checkNotSet(String value) {
if (value == null || value.equals(sNotSet)) {
return "";
} else {
return value;
}
}
}
}
@@ -1,143 +0,0 @@
/*
* 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.content.Context;
import android.preference.Preference;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.CompoundButton;
import android.widget.RadioButton;
import android.widget.RelativeLayout;
import com.android.messaging.R;
import com.android.messaging.datamodel.data.ParticipantData;
import com.android.messaging.ui.UIIntents;
/**
* ApnPreference implements a pref, typically used as a list item, that has a title/summary on
* the left and a radio button on the right.
*
*/
public class ApnPreference extends Preference implements
CompoundButton.OnCheckedChangeListener, OnClickListener {
static final String TAG = "ApnPreference";
public ApnPreference(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public ApnPreference(Context context, AttributeSet attrs) {
this(context, attrs, R.attr.apnPreferenceStyle);
}
public ApnPreference(Context context) {
this(context, null);
}
private static String mSelectedKey = null;
private static CompoundButton mCurrentChecked = null;
private boolean mProtectFromCheckedChange = false;
private boolean mSelectable = true;
private int mSubId = ParticipantData.DEFAULT_SELF_SUB_ID;
@Override
public View getView(View convertView, ViewGroup parent) {
View view = super.getView(convertView, parent);
View widget = view.findViewById(R.id.apn_radiobutton);
if ((widget != null) && widget instanceof RadioButton) {
RadioButton rb = (RadioButton) widget;
if (mSelectable) {
rb.setOnCheckedChangeListener(this);
boolean isChecked = getKey().equals(mSelectedKey);
if (isChecked) {
mCurrentChecked = rb;
mSelectedKey = getKey();
}
mProtectFromCheckedChange = true;
rb.setChecked(isChecked);
mProtectFromCheckedChange = false;
} else {
rb.setVisibility(View.GONE);
}
rb.setContentDescription(getTitle());
}
View textLayout = view.findViewById(R.id.text_layout);
if ((textLayout != null) && textLayout instanceof RelativeLayout) {
textLayout.setOnClickListener(this);
}
return view;
}
public boolean isChecked() {
return getKey().equals(mSelectedKey);
}
public void setChecked() {
mSelectedKey = getKey();
}
public void setSubId(final int subId) {
mSubId = subId;
}
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
Log.i(TAG, "ID: " + getKey() + " :" + isChecked);
if (mProtectFromCheckedChange) {
return;
}
if (isChecked) {
if (mCurrentChecked != null) {
mCurrentChecked.setChecked(false);
}
mCurrentChecked = buttonView;
mSelectedKey = getKey();
callChangeListener(mSelectedKey);
} else {
mCurrentChecked = null;
mSelectedKey = null;
}
buttonView.setContentDescription(getTitle());
}
public void onClick(android.view.View v) {
if ((v != null) && (R.id.text_layout == v.getId())) {
Context context = getContext();
if (context != null) {
context.startActivity(
UIIntents.get().getApnEditorIntent(context, getKey(), mSubId));
}
}
}
public void setSelectable(boolean selectable) {
mSelectable = selectable;
}
public boolean getSelectable() {
return mSelectable;
}
}
@@ -1,402 +0,0 @@
/*
* Copyright (C) 2015 The Android Open Source Project
* Copyright (C) 2024 The LineageOS 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 androidx.annotation.NonNull;
import androidx.core.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.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(@NonNull 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();
mUm = (UserManager) getActivity().getSystemService(Context.USER_SERVICE);
if (!mUm.hasUserRestriction(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)) {
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 (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_white)
.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 static class RestoreApnProcessHandler extends Handler {
private final 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;
}
}
}
}
}
@@ -38,7 +38,6 @@ import com.android.messaging.ui.BugleActionBarActivity;
import com.android.messaging.ui.LicenseActivity;
import com.android.messaging.ui.UIIntents;
import com.android.messaging.util.BuglePrefs;
import com.android.messaging.util.DebugUtils;
import com.android.messaging.util.PhoneUtils;
public class ApplicationSettingsActivity extends BugleActionBarActivity {
@@ -117,12 +116,6 @@ public class ApplicationSettingsActivity extends BugleActionBarActivity {
(SwitchPreference) findPreference(mSwipeRightToDeleteConversationkey);
mIsSmsPreferenceClicked = false;
if (!DebugUtils.isDebugEnabled()) {
final Preference debugCategory = findPreference(getString(
R.string.debug_pref_key));
getPreferenceScreen().removePreference(debugCategory);
}
final PreferenceScreen advancedScreen = (PreferenceScreen) findPreference(
getString(R.string.advanced_pref_key));
final boolean topLevel = getActivity().getIntent().getBooleanExtra(
@@ -138,23 +138,6 @@ public class PerSubscriptionSettingsActivity extends BugleActionBarActivity {
advancedCategory.removePreference(deliveryReportsPref);
}
// Access Point Names (APNs)
final PreferenceScreen apnsScreen =
(PreferenceScreen) findPreference(getString(R.string.sms_apns_key));
if (!MmsManager.shouldUseLegacyMms()
|| (MmsUtils.useSystemApnTable() && !ApnDatabase.doesDatabaseExist())) {
// 1) Remove the ability to edit the local APN prefs if it doesn't use legacy APIs.
// 2) Don't remove the ability to edit the local APN prefs if this device lets us
// access the system APN, but we can't find the MCC/MNC in the APN table and we
// created the local APN table in case the MCC/MNC was in there. In other words,
// if the local APN table exists, let the user edit it.
advancedCategory.removePreference((Preference) apnsScreen);
} else {
apnsScreen.setIntent(UIIntents.get()
.getApnSettingsIntent(getPreferenceScreen().getContext(), mSubId));
}
// We want to disable preferences if we are not the default app, but we do all of the
// above first so that the user sees the correct information on the screen
if (!PhoneUtils.getDefault().isDefaultSmsApp()) {
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2015 The Android Open Source Project
* Copyright (C) 2024 The LineageOS Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,7 +18,6 @@ package com.android.messaging.ui.contact;
import android.content.Context;
import android.database.Cursor;
import android.database.MergeCursor;
import androidx.core.util.Pair;
import android.text.TextUtils;
import android.text.util.Rfc822Token;
@@ -35,8 +35,6 @@ import com.android.ex.chips.RecipientEntry;
import com.android.messaging.R;
import com.android.messaging.util.Assert;
import com.android.messaging.util.Assert.DoesNotRunOnMainThread;
import com.android.messaging.util.BugleGservices;
import com.android.messaging.util.BugleGservicesKeys;
import com.android.messaging.util.ContactRecipientEntryUtils;
import com.android.messaging.util.ContactUtil;
import com.android.messaging.util.PhoneUtils;
@@ -116,40 +114,16 @@ public final class ContactRecipientAdapter extends BaseRecipientAdapter {
@DoesNotRunOnMainThread
private CursorResult getFilteredResultsCursor(final String searchText) {
Assert.isNotMainThread();
if (BugleGservices.get().getBoolean(
BugleGservicesKeys.ALWAYS_AUTOCOMPLETE_EMAIL_ADDRESS,
BugleGservicesKeys.ALWAYS_AUTOCOMPLETE_EMAIL_ADDRESS_DEFAULT)) {
final Cursor personalFilterPhonesCursor = ContactUtil
.filterPhones(getContext(), searchText).performSynchronousQuery();
final Cursor personalFilterEmailsCursor = ContactUtil
.filterEmails(getContext(), searchText).performSynchronousQuery();
final Cursor personalCursor = new MergeCursor(
new Cursor[]{personalFilterEmailsCursor, personalFilterPhonesCursor});
final CursorResult cursorResult =
new CursorResult(personalCursor, false /* sorted */);
// Including enterprise result starting from N.
final Cursor enterpriseFilterPhonesCursor = ContactUtil.filterPhonesEnterprise(
getContext(), searchText).performSynchronousQuery();
final Cursor enterpriseFilterEmailsCursor = ContactUtil.filterEmailsEnterprise(
getContext(), searchText).performSynchronousQuery();
final Cursor enterpriseCursor = new MergeCursor(
new Cursor[]{enterpriseFilterEmailsCursor,
enterpriseFilterPhonesCursor});
cursorResult.enterpriseCursor = enterpriseCursor;
return cursorResult;
} else {
final Cursor personalFilterDestinationCursor = ContactUtil
.filterDestination(getContext(), searchText).performSynchronousQuery();
final CursorResult cursorResult = new CursorResult(personalFilterDestinationCursor,
true);
// Including enterprise result starting from N.
final Cursor enterpriseFilterDestinationCursor = ContactUtil
.filterDestinationEnterprise(getContext(), searchText)
.performSynchronousQuery();
cursorResult.enterpriseCursor = enterpriseFilterDestinationCursor;
return cursorResult;
}
final Cursor personalFilterDestinationCursor = ContactUtil
.filterDestination(getContext(), searchText).performSynchronousQuery();
final CursorResult cursorResult = new CursorResult(personalFilterDestinationCursor,
true);
// Including enterprise result starting from N.
final Cursor enterpriseFilterDestinationCursor = ContactUtil
.filterDestinationEnterprise(getContext(), searchText)
.performSynchronousQuery();
cursorResult.enterpriseCursor = enterpriseFilterDestinationCursor;
return cursorResult;
}
@Override
@@ -37,9 +37,7 @@ import com.android.messaging.sms.MmsUtils;
import com.android.messaging.util.Assert;
import com.android.messaging.util.Assert.DoesNotRunOnMainThread;
import com.android.messaging.util.Dates;
import com.android.messaging.util.DebugUtils;
import com.android.messaging.util.PhoneUtils;
import com.android.messaging.util.SafeAsyncTask;
import java.util.List;
@@ -52,22 +50,8 @@ public class MessageDetailsDialog {
public static void show(final Context context, final ConversationMessageData data,
final ConversationParticipantsData participants, final ParticipantData self) {
if (DebugUtils.isDebugEnabled()) {
new SafeAsyncTask<Void, Void, String>() {
@Override
protected String doInBackgroundTimed(Void... params) {
return getMessageDetails(context, data, participants, self);
}
@Override
protected void onPostExecute(String messageDetails) {
showDialog(context, messageDetails);
}
}.executeOnThreadPool(null, null, null);
} else {
String messageDetails = getMessageDetails(context, data, participants, self);
showDialog(context, messageDetails);
}
String messageDetails = getMessageDetails(context, data, participants, self);
showDialog(context, messageDetails);
}
private static String getMessageDetails(final Context context,
@@ -140,10 +124,6 @@ public class MessageDetailsDialog {
appendSimInfo(res, self, details);
if (DebugUtils.isDebugEnabled()) {
appendDebugInfo(details, data);
}
return details.toString();
}
@@ -206,10 +186,6 @@ public class MessageDetailsDialog {
appendSimInfo(res, self, details);
if (DebugUtils.isDebugEnabled()) {
appendDebugInfo(details, data);
}
return details.toString();
}
@@ -40,9 +40,6 @@ import com.android.messaging.ui.UIIntents;
import com.android.messaging.ui.contact.AddContactsConfirmationDialog;
import com.android.messaging.ui.conversationlist.ConversationListFragment.ConversationListFragmentHost;
import com.android.messaging.ui.conversationlist.MultiSelectActionModeCallback.SelectedConversation;
import com.android.messaging.util.BugleGservices;
import com.android.messaging.util.BugleGservicesKeys;
import com.android.messaging.util.DebugUtils;
import com.android.messaging.util.PhoneUtils;
import com.android.messaging.util.Trace;
import com.android.messaging.util.UiUtils;
@@ -268,10 +265,6 @@ public abstract class AbstractConversationListActivity extends BugleActionBarAc
conversationId);
}
public void onActionBarDebug() {
DebugUtils.showDebugOptions(this);
}
private static class UpdateDestinationBlockedActionSnackBar
implements UpdateDestinationBlockedAction.UpdateDestinationBlockedActionListener {
private final Context mContext;
@@ -21,11 +21,9 @@ import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBar;
import android.view.Menu;
import android.view.MenuItem;
import com.android.messaging.R;
import com.android.messaging.util.DebugUtils;
public class ArchivedConversationListActivity extends AbstractConversationListActivity {
@@ -60,25 +58,8 @@ public class ArchivedConversationListActivity extends AbstractConversationListAc
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
if (super.onCreateOptionsMenu(menu)) {
return true;
}
getMenuInflater().inflate(R.menu.archived_conversation_list_menu, menu);
final MenuItem item = menu.findItem(R.id.action_debug_options);
if (item != null) {
final boolean enableDebugItems = DebugUtils.isDebugEnabled();
item.setVisible(enableDebugItems).setEnabled(enableDebugItems);
}
return true;
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem menuItem) {
public boolean onOptionsItemSelected(MenuItem menuItem) {
switch(menuItem.getItemId()) {
case R.id.action_debug_options:
onActionBarDebug();
return true;
case android.R.id.home:
onActionBarHome();
return true;
@@ -27,7 +27,6 @@ import android.view.MenuItem;
import com.android.messaging.R;
import com.android.messaging.ui.UIIntents;
import com.android.messaging.util.DebugUtils;
import com.android.messaging.util.Trace;
public class ConversationListActivity extends AbstractConversationListActivity {
@@ -77,11 +76,6 @@ public class ConversationListActivity extends AbstractConversationListActivity {
return true;
}
getMenuInflater().inflate(R.menu.conversation_list_fragment_menu, menu);
final MenuItem item = menu.findItem(R.id.action_debug_options);
if (item != null) {
final boolean enableDebugItems = DebugUtils.isDebugEnabled();
item.setVisible(enableDebugItems).setEnabled(enableDebugItems);
}
return true;
}
@@ -94,9 +88,6 @@ public class ConversationListActivity extends AbstractConversationListActivity {
case R.id.action_settings:
onActionBarSettings();
return true;
case R.id.action_debug_options:
onActionBarDebug();
return true;
case R.id.action_show_archived:
onActionBarArchived();
return true;
@@ -1,34 +0,0 @@
/*
* 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.debug;
import android.os.Bundle;
import com.android.messaging.R;
import com.android.messaging.ui.BaseBugleActivity;
/**
* Show list of all MmsConfig key/value pairs and allow editing.
*/
public class DebugMmsConfigActivity extends BaseBugleActivity {
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.debug_mmsconfig_activity);
}
}
@@ -1,150 +0,0 @@
/*
* 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.debug;
import android.app.Fragment;
import android.content.Context;
import android.os.Bundle;
import android.telephony.SubscriptionInfo;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.TextView;
import com.android.messaging.R;
import com.android.messaging.sms.MmsConfig;
import com.android.messaging.ui.debug.DebugMmsConfigItemView.MmsConfigItemListener;
import com.android.messaging.util.PhoneUtils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
/**
* Show list of all MmsConfig key/value pairs and allow editing.
*/
public class DebugMmsConfigFragment extends Fragment {
@Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
final Bundle savedInstanceState) {
final View fragmentView = inflater.inflate(R.layout.mms_config_debug_fragment, container,
false);
final ListView listView = (ListView) fragmentView.findViewById(android.R.id.list);
final Spinner spinner = (Spinner) fragmentView.findViewById(R.id.sim_selector);
final Integer[] subIdArray = getActiveSubIds();
ArrayAdapter<Integer> spinnerAdapter = new ArrayAdapter<Integer>(getActivity(),
android.R.layout.simple_spinner_item, subIdArray);
spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(spinnerAdapter);
spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
listView.setAdapter(new MmsConfigAdapter(getActivity(), subIdArray[position]));
final int[] mccmnc = PhoneUtils.get(subIdArray[position]).getMccMnc();
// Set the title with the mcc/mnc
final TextView title = (TextView) fragmentView.findViewById(R.id.sim_title);
title.setText("(" + mccmnc[0] + "/" + mccmnc[1] + ") " +
getActivity().getString(R.string.debug_sub_id_spinner_text));
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
return fragmentView;
}
public static Integer[] getActiveSubIds() {
final List<SubscriptionInfo> subRecords =
PhoneUtils.getDefault().getActiveSubscriptionInfoList();
if (subRecords == null) {
return new Integer[0];
}
final Integer[] retArray = new Integer[subRecords.size()];
for (int i = 0; i < subRecords.size(); i++) {
retArray[i] = subRecords.get(i).getSubscriptionId();
}
return retArray;
}
private class MmsConfigAdapter extends BaseAdapter implements
DebugMmsConfigItemView.MmsConfigItemListener {
private final LayoutInflater mInflater;
private final List<String> mKeys;
private final MmsConfig mMmsConfig;
public MmsConfigAdapter(Context context, int subId) {
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mMmsConfig = MmsConfig.get(subId);
mKeys = new ArrayList<>(mMmsConfig.keySet());
Iterator<String> it = mKeys.iterator();
while (it.hasNext()) {
// Remove a config if the MmsConfig.sKeyTypeMap doesn't have it.
if (MmsConfig.getKeyType(it.next()) == null) {
it.remove();
}
}
Collections.sort(mKeys);
}
@Override
public View getView(final int position, final View convertView, final ViewGroup parent) {
final DebugMmsConfigItemView view;
if (convertView != null && convertView instanceof DebugMmsConfigItemView) {
view = (DebugMmsConfigItemView) convertView;
} else {
view = (DebugMmsConfigItemView) mInflater.inflate(
R.layout.debug_mmsconfig_item_view, parent, false);
}
final String key = mKeys.get(position);
view.bind(key,
MmsConfig.getKeyType(key),
String.valueOf(mMmsConfig.getValue(key)),
this);
return view;
}
@Override
public void onValueChanged(String key, String keyType, String value) {
mMmsConfig.update(keyType, key, value);
notifyDataSetChanged();
}
@Override
public int getCount() {
return mKeys.size();
}
@Override
public Object getItem(int position) {
return mKeys.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
}
}
@@ -1,131 +0,0 @@
/*
* Copyright (C) 2015 The Android Open Source Project
* Copyright (C) 2024 The LineageOS 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.debug;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.text.InputType;
import android.util.AttributeSet;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.inputmethod.InputMethodManager;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.Switch;
import android.widget.TextView;
import com.android.messaging.R;
import com.android.messaging.sms.MmsConfig;
import com.android.messaging.util.LogUtil;
public class DebugMmsConfigItemView extends LinearLayout implements OnClickListener,
OnCheckedChangeListener, DialogInterface.OnClickListener {
public interface MmsConfigItemListener {
void onValueChanged(String key, String keyType, String value);
}
private TextView mTitle;
private TextView mTextValue;
private Switch mSwitch;
private String mKey;
private String mKeyType;
private MmsConfigItemListener mListener;
private EditText mEditText;
public DebugMmsConfigItemView(Context context, AttributeSet attributeSet) {
super(context, attributeSet);
}
@Override
protected void onFinishInflate () {
mTitle = (TextView) findViewById(R.id.title);
mTextValue = (TextView) findViewById(R.id.text_value);
mSwitch = (Switch) findViewById(R.id.switch_button);
setOnClickListener(this);
mSwitch.setOnCheckedChangeListener(this);
}
public void bind(final String key, final String keyType, final String value,
final MmsConfigItemListener listener) {
mListener = listener;
mKey = key;
mKeyType = keyType;
mTitle.setText(key);
switch (keyType) {
case MmsConfig.KEY_TYPE_BOOL:
mSwitch.setVisibility(View.VISIBLE);
mTextValue.setVisibility(View.GONE);
mSwitch.setChecked(Boolean.valueOf(value));
break;
case MmsConfig.KEY_TYPE_STRING:
case MmsConfig.KEY_TYPE_INT:
mTextValue.setVisibility(View.VISIBLE);
mSwitch.setVisibility(View.GONE);
mTextValue.setText(value);
break;
default:
mTextValue.setVisibility(View.GONE);
mSwitch.setVisibility(View.GONE);
LogUtil.e(LogUtil.BUGLE_TAG, "Unexpected keytype: " + keyType);
break;
}
}
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mListener.onValueChanged(mKey, mKeyType, String.valueOf(isChecked));
}
@Override
public void onClick(View v) {
if (MmsConfig.KEY_TYPE_BOOL.equals(mKeyType)) {
return;
}
final Context context = getContext();
mEditText = new EditText(context);
mEditText.setText(mTextValue.getText());
mEditText.setFocusable(true);
if (MmsConfig.KEY_TYPE_INT.equals(mKeyType)) {
mEditText.setInputType(InputType.TYPE_CLASS_PHONE);
} else {
mEditText.setInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
}
final AlertDialog dialog = new AlertDialog.Builder(context)
.setTitle(mKey)
.setView(mEditText)
.setPositiveButton(android.R.string.ok, this)
.setNegativeButton(android.R.string.cancel, null)
.create();
dialog.setOnShowListener(dialog1 -> {
mEditText.requestFocus();
mEditText.selectAll();
((InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE))
.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, 0);
});
dialog.show();
}
@Override
public void onClick(DialogInterface dialog, int which) {
mListener.onValueChanged(mKey, mKeyType, mEditText.getText().toString());
}
}
@@ -1,171 +0,0 @@
/*
* Copyright (C) 2015 The Android Open Source Project
* Copyright (C) 2024 The LineageOS 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.debug;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.telephony.SmsMessage;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import com.android.messaging.R;
import com.android.messaging.datamodel.action.ReceiveMmsMessageAction;
import com.android.messaging.datamodel.data.ParticipantData;
import com.android.messaging.receiver.SmsReceiver;
import com.android.messaging.sms.MmsUtils;
import com.android.messaging.util.DebugUtils;
import com.android.messaging.util.LogUtil;
/**
* Class that displays UI for choosing SMS/MMS dump files for debugging
*/
public class DebugSmsMmsFromDumpFileDialogFragment extends DialogFragment {
public static final String APPLICATION_OCTET_STREAM = "application/octet-stream";
public static final String KEY_DUMP_FILES = "dump_files";
public static final String KEY_ACTION = "action";
public static final String ACTION_LOAD = "load";
public static final String ACTION_EMAIL = "email";
private String[] mDumpFiles;
private String mAction;
public static DebugSmsMmsFromDumpFileDialogFragment newInstance(final String[] dumpFiles,
final String action) {
final DebugSmsMmsFromDumpFileDialogFragment frag =
new DebugSmsMmsFromDumpFileDialogFragment();
final Bundle args = new Bundle();
args.putSerializable(KEY_DUMP_FILES, dumpFiles);
args.putString(KEY_ACTION, action);
frag.setArguments(args);
return frag;
}
@Override
public Dialog onCreateDialog(final Bundle savedInstanceState) {
final Bundle args = getArguments();
mDumpFiles = (String[]) args.getSerializable(KEY_DUMP_FILES);
mAction = args.getString(KEY_ACTION);
final LayoutInflater inflater = getActivity().getLayoutInflater();
final View layout = inflater.inflate(
R.layout.debug_sms_mms_from_dump_file_dialog, null/*root*/);
final ListView list = (ListView) layout.findViewById(R.id.dump_file_list);
list.setAdapter(new DumpFileListAdapter(getActivity(), mDumpFiles));
final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
final Resources resources = getResources();
if (ACTION_LOAD.equals(mAction)) {
builder.setTitle(resources.getString(
R.string.load_sms_mms_from_dump_file_dialog_title));
} else if (ACTION_EMAIL.equals(mAction)) {
builder.setTitle(resources.getString(
R.string.email_sms_mms_from_dump_file_dialog_title));
}
builder.setView(layout);
return builder.create();
}
private class DumpFileListAdapter extends ArrayAdapter<String> {
public DumpFileListAdapter(final Context context, final String[] dumpFiles) {
super(context, R.layout.sms_mms_dump_file_list_item, dumpFiles);
}
@NonNull
@Override
public View getView(final int position, final View view, @NonNull final ViewGroup parent) {
TextView actionItemView;
if (view == null || !(view instanceof TextView)) {
final LayoutInflater inflater = LayoutInflater.from(getContext());
actionItemView = (TextView) inflater.inflate(
R.layout.sms_mms_dump_file_list_item, parent, false);
} else {
actionItemView = (TextView) view;
}
final String file = getItem(position);
actionItemView.setText(file);
actionItemView.setOnClickListener(view1 -> {
dismiss();
if (ACTION_LOAD.equals(mAction)) {
receiveFromDumpFile(file);
} else if (ACTION_EMAIL.equals(mAction)) {
emailDumpFile(file);
}
});
return actionItemView;
}
}
/**
* Load MMS/SMS from the dump file
*/
private void receiveFromDumpFile(final String dumpFileName) {
if (dumpFileName.startsWith(MmsUtils.SMS_DUMP_PREFIX)) {
final SmsMessage[] messages = DebugUtils.retreiveSmsFromDumpFile(dumpFileName);
if (messages != null) {
SmsReceiver.deliverSmsMessages(getActivity(), ParticipantData.DEFAULT_SELF_SUB_ID,
0, messages);
} else {
LogUtil.e(LogUtil.BUGLE_TAG,
"receiveFromDumpFile: invalid sms dump file " + dumpFileName);
}
} else if (dumpFileName.startsWith(MmsUtils.MMS_DUMP_PREFIX)) {
final byte[] data = MmsUtils.createDebugNotificationInd(dumpFileName);
if (data != null) {
final ReceiveMmsMessageAction action = new ReceiveMmsMessageAction(
ParticipantData.DEFAULT_SELF_SUB_ID, data);
action.start();
} else {
LogUtil.e(LogUtil.BUGLE_TAG,
"receiveFromDumpFile: invalid mms dump file " + dumpFileName);
}
} else {
LogUtil.e(LogUtil.BUGLE_TAG,
"receiveFromDumpFile: invalid dump file name " + dumpFileName);
}
}
/**
* Launch email app to send the dump file
*/
private void emailDumpFile(final String file) {
final Resources resources = getResources();
final String fileLocation = "file://"
+ Environment.getExternalStorageDirectory() + "/" + file;
final Intent sharingIntent = new Intent(Intent.ACTION_SEND);
sharingIntent.setType(APPLICATION_OCTET_STREAM);
sharingIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse(fileLocation));
sharingIntent.putExtra(Intent.EXTRA_SUBJECT,
resources.getString(R.string.email_sms_mms_dump_file_subject));
getActivity().startActivity(Intent.createChooser(sharingIntent,
resources.getString(R.string.email_sms_mms_dump_file_chooser_title)));
}
}
@@ -45,8 +45,6 @@ import com.android.messaging.sms.MmsConfig;
import com.android.messaging.ui.mediapicker.camerafocus.FocusOverlayManager;
import com.android.messaging.ui.mediapicker.camerafocus.RenderOverlay;
import com.android.messaging.util.Assert;
import com.android.messaging.util.BugleGservices;
import com.android.messaging.util.BugleGservicesKeys;
import com.android.messaging.util.LogUtil;
import com.android.messaging.util.OsUtil;
import com.android.messaging.util.UiUtils;
@@ -975,9 +973,7 @@ class CameraManager implements FocusOverlayManager.Listener {
screenWidth *= scaleFactor;
screenHeight *= scaleFactor;
final float aspectRatio = BugleGservices.get().getFloat(
BugleGservicesKeys.CAMERA_ASPECT_RATIO,
screenWidth / (float) screenHeight);
final float aspectRatio = screenWidth / (float) screenHeight;
final List<Camera.Size> sizes = new ArrayList<Camera.Size>(
mCamera.getParameters().getSupportedPictureSizes());
final int maxPixels = maxWidth * maxHeight;