diff options
Diffstat (limited to 'src/com/android/dialer/util')
-rw-r--r-- | src/com/android/dialer/util/AppCompatConstants.java | 30 | ||||
-rw-r--r-- | src/com/android/dialer/util/Assert.java | 36 | ||||
-rw-r--r-- | src/com/android/dialer/util/AsyncTaskExecutor.java | 48 | ||||
-rw-r--r-- | src/com/android/dialer/util/AsyncTaskExecutors.java | 100 | ||||
-rw-r--r-- | src/com/android/dialer/util/BlockReportSpamDialogs.java | 293 | ||||
-rw-r--r-- | src/com/android/dialer/util/DialerUtils.java | 195 | ||||
-rw-r--r-- | src/com/android/dialer/util/EmptyLoader.java | 60 | ||||
-rw-r--r-- | src/com/android/dialer/util/ExpirableCache.java | 266 | ||||
-rw-r--r-- | src/com/android/dialer/util/IntentUtil.java | 162 | ||||
-rw-r--r-- | src/com/android/dialer/util/MoreStrings.java | 43 | ||||
-rw-r--r-- | src/com/android/dialer/util/OrientationUtil.java | 34 | ||||
-rw-r--r-- | src/com/android/dialer/util/PhoneLookupUtil.java | 40 | ||||
-rw-r--r-- | src/com/android/dialer/util/PhoneNumberUtil.java | 138 | ||||
-rw-r--r-- | src/com/android/dialer/util/TelecomUtil.java | 229 |
14 files changed, 0 insertions, 1674 deletions
diff --git a/src/com/android/dialer/util/AppCompatConstants.java b/src/com/android/dialer/util/AppCompatConstants.java deleted file mode 100644 index 1d52eee1d..000000000 --- a/src/com/android/dialer/util/AppCompatConstants.java +++ /dev/null @@ -1,30 +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.dialer.util; - -import android.provider.CallLog.Calls; - -public final class AppCompatConstants { - - public static final int CALLS_INCOMING_TYPE = Calls.INCOMING_TYPE; - public static final int CALLS_OUTGOING_TYPE = Calls.OUTGOING_TYPE; - public static final int CALLS_MISSED_TYPE = Calls.MISSED_TYPE; - public static final int CALLS_VOICEMAIL_TYPE = Calls.VOICEMAIL_TYPE; - // Added to android.provider.CallLog.Calls in N+. - public static final int CALLS_REJECTED_TYPE = 5; - // Added to android.provider.CallLog.Calls in N+. - public static final int CALLS_BLOCKED_TYPE = 6; -} diff --git a/src/com/android/dialer/util/Assert.java b/src/com/android/dialer/util/Assert.java deleted file mode 100644 index ec0a6ccb6..000000000 --- a/src/com/android/dialer/util/Assert.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2016 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.dialer.util; - -import android.os.Looper; - -public class Assert { - public static void assertNotUiThread(String msg) { - if (Looper.myLooper() == Looper.getMainLooper()) { - throw new AssertionError(msg); - } - } - - public static void assertNotNull(Object object, String msg) { - if (object == null) { - throw new AssertionError(object); - } - } - - public static void assertNotNull(Object object) { - assertNotNull(object, null); - } -} diff --git a/src/com/android/dialer/util/AsyncTaskExecutor.java b/src/com/android/dialer/util/AsyncTaskExecutor.java deleted file mode 100644 index ca09f0878..000000000 --- a/src/com/android/dialer/util/AsyncTaskExecutor.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2011 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.dialer.util; - -import android.os.AsyncTask; - -import java.util.concurrent.Executor; - -/** - * Interface used to submit {@link AsyncTask} objects to run in the background. - * <p> - * This interface has a direct parallel with the {@link Executor} interface. It exists to decouple - * the mechanics of AsyncTask submission from the description of how that AsyncTask will execute. - * <p> - * One immediate benefit of this approach is that testing becomes much easier, since it is easy to - * introduce a mock or fake AsyncTaskExecutor in unit/integration tests, and thus inspect which - * tasks have been submitted and control their execution in an orderly manner. - * <p> - * Another benefit in due course will be the management of the submitted tasks. An extension to this - * interface is planned to allow Activities to easily cancel all the submitted tasks that are still - * pending in the onDestroy() method of the Activity. - */ -public interface AsyncTaskExecutor { - /** - * Executes the given AsyncTask with the default Executor. - * <p> - * This method <b>must only be called from the ui thread</b>. - * <p> - * The identifier supplied is any Object that can be used to identify the task later. Most - * commonly this will be an enum which the tests can also refer to. {@code null} is also - * accepted, though of course this won't help in identifying the task later. - */ - <T> AsyncTask<T, ?, ?> submit(Object identifier, AsyncTask<T, ?, ?> task, T... params); -} diff --git a/src/com/android/dialer/util/AsyncTaskExecutors.java b/src/com/android/dialer/util/AsyncTaskExecutors.java deleted file mode 100644 index a59af3e41..000000000 --- a/src/com/android/dialer/util/AsyncTaskExecutors.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2011 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.dialer.util; - -import android.os.AsyncTask; -import android.os.Looper; - -import com.android.contacts.common.testing.NeededForTesting; -import com.google.common.base.Preconditions; - -import java.util.concurrent.Executor; - -/** - * Factory methods for creating AsyncTaskExecutors. - * <p> - * All of the factory methods on this class check first to see if you have set a static - * {@link AsyncTaskExecutorFactory} set through the - * {@link #setFactoryForTest(AsyncTaskExecutorFactory)} method, and if so delegate to that instead, - * which is one way of injecting dependencies for testing classes whose construction cannot be - * controlled such as {@link android.app.Activity}. - */ -public final class AsyncTaskExecutors { - /** - * A single instance of the {@link AsyncTaskExecutorFactory}, to which we delegate if it is - * non-null, for injecting when testing. - */ - private static AsyncTaskExecutorFactory mInjectedAsyncTaskExecutorFactory = null; - - /** - * Creates an AsyncTaskExecutor that submits tasks to run with - * {@link AsyncTask#SERIAL_EXECUTOR}. - */ - public static AsyncTaskExecutor createAsyncTaskExecutor() { - synchronized (AsyncTaskExecutors.class) { - if (mInjectedAsyncTaskExecutorFactory != null) { - return mInjectedAsyncTaskExecutorFactory.createAsyncTaskExeuctor(); - } - return new SimpleAsyncTaskExecutor(AsyncTask.SERIAL_EXECUTOR); - } - } - - /** - * Creates an AsyncTaskExecutor that submits tasks to run with - * {@link AsyncTask#THREAD_POOL_EXECUTOR}. - */ - public static AsyncTaskExecutor createThreadPoolExecutor() { - synchronized (AsyncTaskExecutors.class) { - if (mInjectedAsyncTaskExecutorFactory != null) { - return mInjectedAsyncTaskExecutorFactory.createAsyncTaskExeuctor(); - } - return new SimpleAsyncTaskExecutor(AsyncTask.THREAD_POOL_EXECUTOR); - } - } - - /** Interface for creating AsyncTaskExecutor objects. */ - public interface AsyncTaskExecutorFactory { - AsyncTaskExecutor createAsyncTaskExeuctor(); - } - - @NeededForTesting - public static void setFactoryForTest(AsyncTaskExecutorFactory factory) { - synchronized (AsyncTaskExecutors.class) { - mInjectedAsyncTaskExecutorFactory = factory; - } - } - - public static void checkCalledFromUiThread() { - Preconditions.checkState(Thread.currentThread() == Looper.getMainLooper().getThread(), - "submit method must be called from ui thread, was: " + Thread.currentThread()); - } - - private static class SimpleAsyncTaskExecutor implements AsyncTaskExecutor { - private final Executor mExecutor; - - public SimpleAsyncTaskExecutor(Executor executor) { - mExecutor = executor; - } - - @Override - public <T> AsyncTask<T, ?, ?> submit(Object identifer, AsyncTask<T, ?, ?> task, - T... params) { - checkCalledFromUiThread(); - return task.executeOnExecutor(mExecutor, params); - } - } -} diff --git a/src/com/android/dialer/util/BlockReportSpamDialogs.java b/src/com/android/dialer/util/BlockReportSpamDialogs.java deleted file mode 100644 index 45b2f4228..000000000 --- a/src/com/android/dialer/util/BlockReportSpamDialogs.java +++ /dev/null @@ -1,293 +0,0 @@ -/* - * Copyright (C) 2016 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.dialer.util; - -import android.app.Activity; -import android.app.AlertDialog; -import android.app.Dialog; -import android.app.DialogFragment; -import android.content.DialogInterface; -import android.os.Bundle; -import android.support.annotation.Nullable; -import android.view.View; -import android.widget.CheckBox; -import android.widget.CompoundButton; - -import com.android.dialer.R; - -/** - * Helper class for creating block/report dialog fragments. - */ -public class BlockReportSpamDialogs { - public static final String BLOCK_REPORT_SPAM_DIALOG_TAG = "BlockReportSpamDialog"; - public static final String BLOCK_DIALOG_TAG = "BlockDialog"; - public static final String UNBLOCK_DIALOG_TAG = "UnblockDialog"; - public static final String NOT_SPAM_DIALOG_TAG = "NotSpamDialog"; - - /** - * Listener passed to block/report spam dialog for positive click in - * {@link BlockReportSpamDialogFragment}. - */ - public interface OnSpamDialogClickListener { - /** - * Called when user clicks on positive button in block/report spam dialog. - * @param isSpamChecked Whether the spam checkbox is checked. - */ - void onClick(boolean isSpamChecked); - } - - /** - * Listener passed to all dialogs except the block/report spam dialog for positive click. - */ - public interface OnConfirmListener { - /** - * Called when user clicks on positive button in the dialog. - */ - void onClick(); - } - - /** - * Contains the common attributes between all block/unblock/report dialog fragments. - */ - private static class CommonDialogsFragment extends DialogFragment { - /** - * The number to display in the dialog title. - */ - protected String mDisplayNumber; - - /** - * Called when dialog positive button is pressed. - */ - protected OnConfirmListener mPositiveListener; - - /** - * Called when dialog is dismissed. - */ - @Nullable - protected DialogInterface.OnDismissListener mDismissListener; - - @Override - public void onDismiss(DialogInterface dialog) { - if (mDismissListener != null) { - mDismissListener.onDismiss(dialog); - } - super.onDismiss(dialog); - } - - @Override - public void onPause() { - // The dialog is dismissed onPause, i.e. rotation. - dismiss(); - mDismissListener = null; - mPositiveListener = null; - mDisplayNumber = null; - super.onPause(); - } - } - - /** - * Dialog for block/report spam with the mark as spam checkbox. - */ - public static class BlockReportSpamDialogFragment extends CommonDialogsFragment { - /** - * Called when dialog positive button is pressed. - */ - private OnSpamDialogClickListener mPositiveListener; - - /** - * Whether the mark as spam checkbox is checked before displaying the dialog. - */ - private boolean mSpamChecked; - - public static DialogFragment newInstance(String displayNumber, - boolean spamChecked, - OnSpamDialogClickListener positiveListener, - @Nullable DialogInterface.OnDismissListener - dismissListener) { - BlockReportSpamDialogFragment fragment = new BlockReportSpamDialogFragment(); - fragment.mSpamChecked = spamChecked; - fragment.mDisplayNumber = displayNumber; - fragment.mPositiveListener = positiveListener; - fragment.mDismissListener = dismissListener; - return fragment; - } - - @Override - public Dialog onCreateDialog(Bundle savedInstanceState) { - super.onCreateDialog(savedInstanceState); - View dialogView = View.inflate(getActivity(), R.layout.block_report_spam_dialog, null); - final CheckBox isSpamCheckbox = - (CheckBox) dialogView.findViewById(R.id.report_number_as_spam_action); - // Listen for changes on the checkbox and update if orientation changes - isSpamCheckbox.setChecked(mSpamChecked); - isSpamCheckbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - mSpamChecked = isChecked; - } - }); - - AlertDialog.Builder alertDialogBuilder = createDialogBuilder(getActivity(), this); - Dialog dialog = alertDialogBuilder - .setView(dialogView) - .setTitle(getString(R.string.block_report_number_alert_title, mDisplayNumber)) - .setPositiveButton(R.string.block_number_ok, - new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - dismiss(); - mPositiveListener.onClick(isSpamCheckbox.isChecked()); - } - }).create(); - dialog.setCanceledOnTouchOutside(true); - return dialog; - } - } - - /** - * Dialog for blocking a number. - */ - public static class BlockDialogFragment extends CommonDialogsFragment { - public static DialogFragment newInstance(String displayNumber, - OnConfirmListener positiveListener, - @Nullable DialogInterface.OnDismissListener - dismissListener) { - BlockDialogFragment fragment = new BlockDialogFragment(); - fragment.mDisplayNumber = displayNumber; - fragment.mPositiveListener = positiveListener; - fragment.mDismissListener = dismissListener; - return fragment; - } - - @Override - public Dialog onCreateDialog(Bundle savedInstanceState) { - super.onCreateDialog(savedInstanceState); - // Return the newly created dialog - AlertDialog.Builder alertDialogBuilder = createDialogBuilder(getActivity(), this); - Dialog dialog = alertDialogBuilder - .setTitle(getString(R.string.block_report_number_alert_title, mDisplayNumber)) - .setPositiveButton(R.string.block_number_ok, - createGenericOnClickListener(this, mPositiveListener)) - .create(); - dialog.setCanceledOnTouchOutside(true); - return dialog; - } - } - - /** - * Dialog for unblocking a number. - */ - public static class UnblockDialogFragment extends CommonDialogsFragment { - /** - * Whether or not the number is spam. - */ - private boolean mIsSpam; - - public static DialogFragment newInstance(String displayNumber, - boolean isSpam, - OnConfirmListener positiveListener, - @Nullable DialogInterface.OnDismissListener - dismissListener) { - UnblockDialogFragment fragment = new UnblockDialogFragment(); - fragment.mDisplayNumber = displayNumber; - fragment.mIsSpam = isSpam; - fragment.mPositiveListener = positiveListener; - fragment.mDismissListener = dismissListener; - return fragment; - } - - @Override - public Dialog onCreateDialog(Bundle savedInstanceState) { - super.onCreateDialog(savedInstanceState); - // Return the newly created dialog - AlertDialog.Builder alertDialogBuilder = createDialogBuilder(getActivity(), this); - if (mIsSpam) { - alertDialogBuilder.setMessage(R.string.unblock_number_alert_details); - } - Dialog dialog = alertDialogBuilder - .setTitle(getString(R.string.unblock_report_number_alert_title, mDisplayNumber)) - .setPositiveButton(R.string.unblock_number_ok, - createGenericOnClickListener(this, mPositiveListener)) - .create(); - dialog.setCanceledOnTouchOutside(true); - return dialog; - } - } - - /** - * Dialog for reporting a number as not spam. - */ - public static class ReportNotSpamDialogFragment extends CommonDialogsFragment { - public static DialogFragment newInstance(String displayNumber, - OnConfirmListener positiveListener, - @Nullable DialogInterface.OnDismissListener - dismissListener) { - ReportNotSpamDialogFragment fragment = new ReportNotSpamDialogFragment(); - fragment.mDisplayNumber = displayNumber; - fragment.mPositiveListener = positiveListener; - fragment.mDismissListener = dismissListener; - return fragment; - } - - @Override - public Dialog onCreateDialog(Bundle savedInstanceState) { - super.onCreateDialog(savedInstanceState); - // Return the newly created dialog - AlertDialog.Builder alertDialogBuilder = createDialogBuilder(getActivity(), this); - Dialog dialog = alertDialogBuilder - .setTitle(getString(R.string.report_not_spam_alert_title, mDisplayNumber)) - .setMessage(R.string.report_not_spam_alert_details) - .setPositiveButton(R.string.report_not_spam_alert_button, - createGenericOnClickListener(this, mPositiveListener)) - .create(); - dialog.setCanceledOnTouchOutside(true); - return dialog; - } - } - - /** - * Creates a dialog with the default cancel button listener (dismisses dialog). - */ - private static AlertDialog.Builder createDialogBuilder(Activity activity, - final DialogFragment fragment) { - return new AlertDialog.Builder(activity) - .setCancelable(true) - .setNegativeButton(android.R.string.cancel, - new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - fragment.dismiss(); - } - }); - } - - /** - * Creates a generic click listener which dismisses the fragment and then calls the actual - * listener. - */ - private static DialogInterface.OnClickListener createGenericOnClickListener( - final DialogFragment fragment, - final OnConfirmListener listener) { - return new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - fragment.dismiss(); - listener.onClick(); - } - }; - } -} diff --git a/src/com/android/dialer/util/DialerUtils.java b/src/com/android/dialer/util/DialerUtils.java deleted file mode 100644 index 95d6a81b6..000000000 --- a/src/com/android/dialer/util/DialerUtils.java +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright (C) 2014 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.dialer.util; - -import android.app.Activity; -import android.content.ActivityNotFoundException; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.content.res.Resources; -import android.graphics.Point; -import android.net.Uri; -import android.os.Bundle; -import android.provider.Telephony; -import android.telecom.TelecomManager; -import android.text.BidiFormatter; -import android.text.TextDirectionHeuristics; -import android.text.TextUtils; -import android.view.View; -import android.view.inputmethod.InputMethodManager; -import android.widget.Toast; - -import com.android.contacts.common.ContactsUtils; -import com.android.contacts.common.interactions.TouchPointManager; -import com.android.dialer.R; - -import java.util.Iterator; -import java.util.List; -import java.util.Locale; - -/** - * General purpose utility methods for the Dialer. - */ -public class DialerUtils { - - /** - * Attempts to start an activity and displays a toast with the default error message if the - * activity is not found, instead of throwing an exception. - * - * @param context to start the activity with. - * @param intent to start the activity with. - */ - public static void startActivityWithErrorToast(Context context, Intent intent) { - startActivityWithErrorToast(context, intent, R.string.activity_not_available); - } - - /** - * Attempts to start an activity and displays a toast with a provided error message if the - * activity is not found, instead of throwing an exception. - * - * @param context to start the activity with. - * @param intent to start the activity with. - * @param msgId Resource ID of the string to display in an error message if the activity is - * not found. - */ - public static void startActivityWithErrorToast(Context context, Intent intent, int msgId) { - try { - if ((IntentUtil.CALL_ACTION.equals(intent.getAction()) - && context instanceof Activity)) { - // All dialer-initiated calls should pass the touch point to the InCallUI - Point touchPoint = TouchPointManager.getInstance().getPoint(); - if (touchPoint.x != 0 || touchPoint.y != 0) { - Bundle extras; - // Make sure to not accidentally clobber any existing extras - if (intent.hasExtra(TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS)) { - extras = intent.getParcelableExtra( - TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS); - } else { - extras = new Bundle(); - } - extras.putParcelable(TouchPointManager.TOUCH_POINT, touchPoint); - intent.putExtra(TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS, extras); - } - - final boolean hasCallPermission = TelecomUtil.placeCall((Activity) context, intent); - if (!hasCallPermission) { - // TODO: Make calling activity show request permission dialog and handle - // callback results appropriately. - Toast.makeText(context, "Cannot place call without Phone permission", - Toast.LENGTH_SHORT); - } - } else { - context.startActivity(intent); - } - } catch (ActivityNotFoundException e) { - Toast.makeText(context, msgId, Toast.LENGTH_SHORT).show(); - } - } - - /** - * Returns the component name to use in order to send an SMS using the default SMS application, - * or null if none exists. - */ - public static ComponentName getSmsComponent(Context context) { - String smsPackage = Telephony.Sms.getDefaultSmsPackage(context); - if (smsPackage != null) { - final PackageManager packageManager = context.getPackageManager(); - final Intent intent = new Intent(Intent.ACTION_SENDTO, - Uri.fromParts(ContactsUtils.SCHEME_SMSTO, "", null)); - final List<ResolveInfo> resolveInfos = packageManager.queryIntentActivities(intent, 0); - for (ResolveInfo resolveInfo : resolveInfos) { - if (smsPackage.equals(resolveInfo.activityInfo.packageName)) { - return new ComponentName(smsPackage, resolveInfo.activityInfo.name); - } - } - } - return null; - } - - /** - * Closes an {@link AutoCloseable}, silently ignoring any checked exceptions. Does nothing if - * null. - * - * @param closeable to close. - */ - public static void closeQuietly(AutoCloseable closeable) { - if (closeable != null) { - try { - closeable.close(); - } catch (RuntimeException rethrown) { - throw rethrown; - } catch (Exception ignored) { - } - } - } - - /** - * Joins a list of {@link CharSequence} into a single {@link CharSequence} seperated by a - * localized delimiter such as ", ". - * - * @param resources Resources used to get list delimiter. - * @param list List of char sequences to join. - * @return Joined char sequences. - */ - public static CharSequence join(Resources resources, Iterable<CharSequence> list) { - StringBuilder sb = new StringBuilder(); - final BidiFormatter formatter = BidiFormatter.getInstance(); - final CharSequence separator = resources.getString(R.string.list_delimeter); - - Iterator<CharSequence> itr = list.iterator(); - boolean firstTime = true; - while (itr.hasNext()) { - if (firstTime) { - firstTime = false; - } else { - sb.append(separator); - } - // Unicode wrap the elements of the list to respect RTL for individual strings. - sb.append(formatter.unicodeWrap( - itr.next().toString(), TextDirectionHeuristics.FIRSTSTRONG_LTR)); - } - - // Unicode wrap the joined value, to respect locale's RTL ordering for the whole list. - return formatter.unicodeWrap(sb.toString()); - } - - /** - * @return True if the application is currently in RTL mode. - */ - public static boolean isRtl() { - return TextUtils.getLayoutDirectionFromLocale(Locale.getDefault()) == - View.LAYOUT_DIRECTION_RTL; - } - - public static void showInputMethod(View view) { - final InputMethodManager imm = (InputMethodManager) view.getContext().getSystemService( - Context.INPUT_METHOD_SERVICE); - if (imm != null) { - imm.showSoftInput(view, 0); - } - } - - public static void hideInputMethod(View view) { - final InputMethodManager imm = (InputMethodManager) view.getContext().getSystemService( - Context.INPUT_METHOD_SERVICE); - if (imm != null) { - imm.hideSoftInputFromWindow(view.getWindowToken(), 0); - } - } -} diff --git a/src/com/android/dialer/util/EmptyLoader.java b/src/com/android/dialer/util/EmptyLoader.java deleted file mode 100644 index dd4c0a330..000000000 --- a/src/com/android/dialer/util/EmptyLoader.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2011 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.dialer.util; - -import android.app.LoaderManager.LoaderCallbacks; -import android.content.Context; -import android.content.Loader; -import android.os.Bundle; - -/** - * A {@link Loader} only used to make use of the {@link android.app.Fragment#setStartDeferred} - * feature from an old-style fragment which doesn't use {@link Loader}s to load data. - * - * This loader never delivers results. A caller fragment must destroy it when deferred fragments - * should be started. - */ -public class EmptyLoader extends Loader<Object> { - public EmptyLoader(Context context) { - super(context); - } - - /** - * {@link LoaderCallbacks} which just generates {@link EmptyLoader}. {@link #onLoadFinished} - * and {@link #onLoaderReset} are no-op. - */ - public static class Callback implements LoaderCallbacks<Object> { - private final Context mContext; - - public Callback(Context context) { - mContext = context.getApplicationContext(); - } - - @Override - public Loader<Object> onCreateLoader(int id, Bundle args) { - return new EmptyLoader(mContext); - } - - @Override - public void onLoadFinished(Loader<Object> loader, Object data) { - } - - @Override - public void onLoaderReset(Loader<Object> loader) { - } - } -} diff --git a/src/com/android/dialer/util/ExpirableCache.java b/src/com/android/dialer/util/ExpirableCache.java deleted file mode 100644 index 00ebd1607..000000000 --- a/src/com/android/dialer/util/ExpirableCache.java +++ /dev/null @@ -1,266 +0,0 @@ -/* - * Copyright (C) 2011 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.dialer.util; - -import android.util.LruCache; - -import com.android.contacts.common.testing.NeededForTesting; - -import java.util.concurrent.atomic.AtomicInteger; - -import javax.annotation.concurrent.Immutable; -import javax.annotation.concurrent.ThreadSafe; - -/** - * An LRU cache in which all items can be marked as expired at a given time and it is possible to - * query whether a particular cached value is expired or not. - * <p> - * A typical use case for this is caching of values which are expensive to compute but which are - * still useful when out of date. - * <p> - * Consider a cache for contact information: - * <pre>{@code - * private ExpirableCache<String, Contact> mContactCache;}</pre> - * which stores the contact information for a given phone number. - * <p> - * When we need to store contact information for a given phone number, we can look up the info in - * the cache: - * <pre>{@code - * CachedValue<Contact> cachedContact = mContactCache.getCachedValue(phoneNumber); - * }</pre> - * We might also want to fetch the contact information again if the item is expired. - * <pre> - * if (cachedContact.isExpired()) { - * fetchContactForNumber(phoneNumber, - * new FetchListener() { - * @Override - * public void onFetched(Contact contact) { - * mContactCache.put(phoneNumber, contact); - * } - * }); - * }</pre> - * and insert it back into the cache when the fetch completes. - * <p> - * At a certain point we want to expire the content of the cache because we know the content may - * no longer be up-to-date, for instance, when resuming the activity this is shown into: - * <pre> - * @Override - * protected onResume() { - * // We were paused for some time, the cached value might no longer be up to date. - * mContactCache.expireAll(); - * super.onResume(); - * } - * </pre> - * The values will be still available from the cache, but they will be expired. - * <p> - * If interested only in the value itself, not whether it is expired or not, one should use the - * {@link #getPossiblyExpired(Object)} method. If interested only in non-expired values, one should - * use the {@link #get(Object)} method instead. - * <p> - * This class wraps around an {@link LruCache} instance: it follows the {@link LruCache} behavior - * for evicting items when the cache is full. It is possible to supply your own subclass of LruCache - * by using the {@link #create(LruCache)} method, which can define a custom expiration policy. - * Since the underlying cache maps keys to cached values it can determine which items are expired - * and which are not, allowing for an implementation that evicts expired items before non expired - * ones. - * <p> - * This class is thread-safe. - * - * @param <K> the type of the keys - * @param <V> the type of the values - */ -@ThreadSafe -public class ExpirableCache<K, V> { - /** - * A cached value stored inside the cache. - * <p> - * It provides access to the value stored in the cache but also allows to check whether the - * value is expired. - * - * @param <V> the type of value stored in the cache - */ - public interface CachedValue<V> { - /** Returns the value stored in the cache for a given key. */ - public V getValue(); - - /** - * Checks whether the value, while still being present in the cache, is expired. - * - * @return true if the value is expired - */ - public boolean isExpired(); - } - - /** - * Cached values storing the generation at which they were added. - */ - @Immutable - private static class GenerationalCachedValue<V> implements ExpirableCache.CachedValue<V> { - /** The value stored in the cache. */ - public final V mValue; - /** The generation at which the value was added to the cache. */ - private final int mGeneration; - /** The atomic integer storing the current generation of the cache it belongs to. */ - private final AtomicInteger mCacheGeneration; - - /** - * @param cacheGeneration the atomic integer storing the generation of the cache in which - * this value will be stored - */ - public GenerationalCachedValue(V value, AtomicInteger cacheGeneration) { - mValue = value; - mCacheGeneration = cacheGeneration; - // Snapshot the current generation. - mGeneration = mCacheGeneration.get(); - } - - @Override - public V getValue() { - return mValue; - } - - @Override - public boolean isExpired() { - return mGeneration != mCacheGeneration.get(); - } - } - - /** The underlying cache used to stored the cached values. */ - private LruCache<K, CachedValue<V>> mCache; - - /** - * The current generation of items added to the cache. - * <p> - * Items in the cache can belong to a previous generation, but in that case they would be - * expired. - * - * @see ExpirableCache.CachedValue#isExpired() - */ - private final AtomicInteger mGeneration; - - private ExpirableCache(LruCache<K, CachedValue<V>> cache) { - mCache = cache; - mGeneration = new AtomicInteger(0); - } - - /** - * Returns the cached value for the given key, or null if no value exists. - * <p> - * The cached value gives access both to the value associated with the key and whether it is - * expired or not. - * <p> - * If not interested in whether the value is expired, use {@link #getPossiblyExpired(Object)} - * instead. - * <p> - * If only wants values that are not expired, use {@link #get(Object)} instead. - * - * @param key the key to look up - */ - public CachedValue<V> getCachedValue(K key) { - return mCache.get(key); - } - - /** - * Returns the value for the given key, or null if no value exists. - * <p> - * When using this method, it is not possible to determine whether the value is expired or not. - * Use {@link #getCachedValue(Object)} to achieve that instead. However, if using - * {@link #getCachedValue(Object)} to determine if an item is expired, one should use the item - * within the {@link CachedValue} and not call {@link #getPossiblyExpired(Object)} to get the - * value afterwards, since that is not guaranteed to return the same value or that the newly - * returned value is in the same state. - * - * @param key the key to look up - */ - public V getPossiblyExpired(K key) { - CachedValue<V> cachedValue = getCachedValue(key); - return cachedValue == null ? null : cachedValue.getValue(); - } - - /** - * Returns the value for the given key only if it is not expired, or null if no value exists or - * is expired. - * <p> - * This method will return null if either there is no value associated with this key or if the - * associated value is expired. - * - * @param key the key to look up - */ - @NeededForTesting - public V get(K key) { - CachedValue<V> cachedValue = getCachedValue(key); - return cachedValue == null || cachedValue.isExpired() ? null : cachedValue.getValue(); - } - - /** - * Puts an item in the cache. - * <p> - * Newly added item will not be expired until {@link #expireAll()} is next called. - * - * @param key the key to look up - * @param value the value to associate with the key - */ - public void put(K key, V value) { - mCache.put(key, newCachedValue(value)); - } - - /** - * Mark all items currently in the cache as expired. - * <p> - * Newly added items after this call will be marked as not expired. - * <p> - * Expiring the items in the cache does not imply they will be evicted. - */ - public void expireAll() { - mGeneration.incrementAndGet(); - } - - /** - * Creates a new {@link CachedValue} instance to be stored in this cache. - * <p> - * Implementation of {@link LruCache#create(K)} can use this method to create a new entry. - */ - public CachedValue<V> newCachedValue(V value) { - return new GenerationalCachedValue<V>(value, mGeneration); - } - - /** - * Creates a new {@link ExpirableCache} that wraps the given {@link LruCache}. - * <p> - * The created cache takes ownership of the cache passed in as an argument. - * - * @param <K> the type of the keys - * @param <V> the type of the values - * @param cache the cache to store the value in - * @return the newly created expirable cache - * @throws IllegalArgumentException if the cache is not empty - */ - public static <K, V> ExpirableCache<K, V> create(LruCache<K, CachedValue<V>> cache) { - return new ExpirableCache<K, V>(cache); - } - - /** - * Creates a new {@link ExpirableCache} with the given maximum size. - * - * @param <K> the type of the keys - * @param <V> the type of the values - * @return the newly created expirable cache - */ - public static <K, V> ExpirableCache<K, V> create(int maxSize) { - return create(new LruCache<K, CachedValue<V>>(maxSize)); - } -} diff --git a/src/com/android/dialer/util/IntentUtil.java b/src/com/android/dialer/util/IntentUtil.java deleted file mode 100644 index 581e10da4..000000000 --- a/src/com/android/dialer/util/IntentUtil.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (C) 2012 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.dialer.util; - -import android.content.Intent; -import android.net.Uri; -import android.os.Bundle; -import android.os.SystemClock; -import android.provider.ContactsContract; -import android.telecom.PhoneAccountHandle; -import android.telecom.TelecomManager; -import android.telecom.VideoProfile; - -import com.android.contacts.common.CallUtil; - -/** - * Utilities for creation of intents in Dialer, such as {@link Intent#ACTION_CALL}. - */ -public class IntentUtil { - - public static final String CALL_ACTION = Intent.ACTION_CALL; - private static final String SMS_URI_PREFIX = "sms:"; - private static final int NO_PHONE_TYPE = -1; - - public static final String EXTRA_CALL_INITIATION_TYPE - = "com.android.dialer.EXTRA_CALL_INITIATION_TYPE"; - public static final String EXTRA_CALL_CREATED_TIME_MILLIS = - "android.telecom.extra.CALL_CREATED_TIME_MILLIS"; - - public static class CallIntentBuilder { - private Uri mUri; - private int mCallInitiationType; - private PhoneAccountHandle mPhoneAccountHandle; - private boolean mIsVideoCall = false; - - public CallIntentBuilder(Uri uri) { - mUri = uri; - } - - public CallIntentBuilder(String number) { - this(CallUtil.getCallUri(number)); - } - - public CallIntentBuilder setCallInitiationType(int initiationType) { - mCallInitiationType = initiationType; - return this; - } - - public CallIntentBuilder setPhoneAccountHandle(PhoneAccountHandle accountHandle) { - mPhoneAccountHandle = accountHandle; - return this; - } - - public CallIntentBuilder setIsVideoCall(boolean isVideoCall) { - mIsVideoCall = isVideoCall; - return this; - } - - public Intent build() { - return getCallIntent( - mUri, - mPhoneAccountHandle, - mIsVideoCall ? VideoProfile.STATE_BIDIRECTIONAL : VideoProfile.STATE_AUDIO_ONLY, - mCallInitiationType); - } - } - - /** - * Create a call intent that can be used to place a call. - * - * @param uri Address to place the call to. - * @param accountHandle {@link PhoneAccountHandle} to place the call with. - * @param videoState Initial video state of the call. - * @param callIntiationType The UI affordance the call was initiated by. - * @return Call intent with provided extras and data. - */ - public static Intent getCallIntent( - Uri uri, PhoneAccountHandle accountHandle, int videoState, int callIntiationType) { - final Intent intent = new Intent(CALL_ACTION, uri); - intent.putExtra(TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE, videoState); - - final Bundle b = new Bundle(); - b.putLong(EXTRA_CALL_CREATED_TIME_MILLIS, SystemClock.elapsedRealtime()); - b.putInt(EXTRA_CALL_INITIATION_TYPE, callIntiationType); - intent.putExtra(TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS, b); - - if (accountHandle != null) { - intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, accountHandle); - } - - return intent; - } - - public static Intent getSendSmsIntent(CharSequence phoneNumber) { - return new Intent(Intent.ACTION_SENDTO, Uri.parse(SMS_URI_PREFIX + phoneNumber)); - } - - public static Intent getNewContactIntent() { - return new Intent(Intent.ACTION_INSERT, ContactsContract.Contacts.CONTENT_URI); - } - - public static Intent getNewContactIntent(CharSequence phoneNumber) { - return getNewContactIntent( - null /* name */, - phoneNumber /* phoneNumber */, - NO_PHONE_TYPE); - } - - public static Intent getNewContactIntent( - CharSequence name, CharSequence phoneNumber, int phoneNumberType) { - Intent intent = getNewContactIntent(); - populateContactIntent(intent, name, phoneNumber, phoneNumberType); - return intent; - } - - public static Intent getAddToExistingContactIntent() { - Intent intent = new Intent(Intent.ACTION_INSERT_OR_EDIT); - intent.setType(ContactsContract.Contacts.CONTENT_ITEM_TYPE); - return intent; - } - - public static Intent getAddToExistingContactIntent(CharSequence phoneNumber) { - return getAddToExistingContactIntent( - null /* name */, - phoneNumber /* phoneNumber */, - NO_PHONE_TYPE); - } - - public static Intent getAddToExistingContactIntent( - CharSequence name, CharSequence phoneNumber, int phoneNumberType) { - Intent intent = getAddToExistingContactIntent(); - populateContactIntent(intent, name, phoneNumber, phoneNumberType); - return intent; - } - - private static void populateContactIntent( - Intent intent, CharSequence name, CharSequence phoneNumber, int phoneNumberType) { - if (phoneNumber != null) { - intent.putExtra(ContactsContract.Intents.Insert.PHONE, phoneNumber); - } - if (name != null) { - intent.putExtra(ContactsContract.Intents.Insert.NAME, name); - } - if (phoneNumberType != NO_PHONE_TYPE) { - intent.putExtra(ContactsContract.Intents.Insert.PHONE_TYPE, phoneNumberType); - } - } -} diff --git a/src/com/android/dialer/util/MoreStrings.java b/src/com/android/dialer/util/MoreStrings.java deleted file mode 100644 index 68956f25c..000000000 --- a/src/com/android/dialer/util/MoreStrings.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2013 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.dialer.util; - -/** - * Static utility methods for Strings. - */ -public class MoreStrings { - - public static String toSafeString(String value) { - if (value == null) { - return null; - } - - // Do exactly same thing as Uri#toSafeString() does, which will enable us to compare - // sanitized phone numbers. - final StringBuilder builder = new StringBuilder(); - for (int i = 0; i < value.length(); i++) { - final char c = value.charAt(i); - if (c == '-' || c == '@' || c == '.') { - builder.append(c); - } else { - builder.append('x'); - } - } - return builder.toString(); - } - -} diff --git a/src/com/android/dialer/util/OrientationUtil.java b/src/com/android/dialer/util/OrientationUtil.java deleted file mode 100644 index 2eb2af3ff..000000000 --- a/src/com/android/dialer/util/OrientationUtil.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2012 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.dialer.util; - -import android.content.Context; -import android.content.res.Configuration; - -/** - * Static methods related to device orientation. - */ -public class OrientationUtil { - - /** - * @return if the context is in landscape orientation. - */ - public static boolean isLandscape(Context context) { - return context.getResources().getConfiguration().orientation - == Configuration.ORIENTATION_LANDSCAPE; - } -} diff --git a/src/com/android/dialer/util/PhoneLookupUtil.java b/src/com/android/dialer/util/PhoneLookupUtil.java deleted file mode 100644 index 1a7239642..000000000 --- a/src/com/android/dialer/util/PhoneLookupUtil.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2016 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.dialer.util; - -import android.net.Uri; -import android.provider.ContactsContract; - -import com.android.contacts.common.compat.CompatUtils; -import com.android.contacts.common.compat.PhoneLookupSdkCompat; - -public final class PhoneLookupUtil { - /** - * @return the column name that stores contact id for phone lookup query. - */ - public static String getContactIdColumnNameForUri(Uri phoneLookupUri) { - if (CompatUtils.isNCompatible()) { - return PhoneLookupSdkCompat.CONTACT_ID; - } - // In pre-N, contact id is stored in {@link PhoneLookup#_ID} in non-sip query. - boolean isSip = phoneLookupUri.getBooleanQueryParameter( - ContactsContract.PhoneLookup.QUERY_PARAMETER_SIP_ADDRESS, false); - return (isSip) ? PhoneLookupSdkCompat.CONTACT_ID : ContactsContract.PhoneLookup._ID; - } - - private PhoneLookupUtil() {} -} diff --git a/src/com/android/dialer/util/PhoneNumberUtil.java b/src/com/android/dialer/util/PhoneNumberUtil.java deleted file mode 100644 index 33f987359..000000000 --- a/src/com/android/dialer/util/PhoneNumberUtil.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (C) 2013 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.dialer.util; - -import android.content.Context; -import android.provider.CallLog; -import android.telecom.PhoneAccountHandle; -import android.text.TextUtils; -import android.util.Log; -import android.util.Pair; - -import com.android.contacts.common.util.PhoneNumberHelper; -import com.android.contacts.common.util.TelephonyManagerUtils; -import com.google.common.collect.Sets; -import com.google.i18n.phonenumbers.NumberParseException; -import com.google.i18n.phonenumbers.Phonenumber; -import com.google.i18n.phonenumbers.geocoding.PhoneNumberOfflineGeocoder; - -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; -import java.util.Set; - -public class PhoneNumberUtil { - private static final String TAG = "PhoneNumberUtil"; - private static final Set<String> LEGACY_UNKNOWN_NUMBERS = Sets.newHashSet("-1", "-2", "-3"); - - /** Returns true if it is possible to place a call to the given number. */ - public static boolean canPlaceCallsTo(CharSequence number, int presentation) { - return presentation == CallLog.Calls.PRESENTATION_ALLOWED - && !TextUtils.isEmpty(number) && !isLegacyUnknownNumbers(number); - } - - /** - * Returns true if the given number is the number of the configured voicemail. To be able to - * mock-out this, it is not a static method. - */ - public static boolean isVoicemailNumber( - Context context, PhoneAccountHandle accountHandle, CharSequence number) { - if (TextUtils.isEmpty(number)) { - return false; - } - return TelecomUtil.isVoicemailNumber(context, accountHandle, number.toString()); - } - - /** - * Returns true if the given number is a SIP address. To be able to mock-out this, it is not a - * static method. - */ - public static boolean isSipNumber(CharSequence number) { - return number != null && PhoneNumberHelper.isUriNumber(number.toString()); - } - - public static boolean isUnknownNumberThatCanBeLookedUp( - Context context, - PhoneAccountHandle accountHandle, - CharSequence number, - int presentation) { - if (presentation == CallLog.Calls.PRESENTATION_UNKNOWN) { - return false; - } - if (presentation == CallLog.Calls.PRESENTATION_RESTRICTED) { - return false; - } - if (presentation == CallLog.Calls.PRESENTATION_PAYPHONE) { - return false; - } - if (TextUtils.isEmpty(number)) { - return false; - } - if (isVoicemailNumber(context, accountHandle, number)) { - return false; - } - if (isLegacyUnknownNumbers(number)) { - return false; - } - return true; - } - - public static boolean isLegacyUnknownNumbers(CharSequence number) { - return number != null && LEGACY_UNKNOWN_NUMBERS.contains(number.toString()); - } - - /** - * @return a geographical description string for the specified number. - * @see com.android.i18n.phonenumbers.PhoneNumberOfflineGeocoder - */ - public static String getGeoDescription(Context context, String number) { - Log.v(TAG, "getGeoDescription('" + pii(number) + "')..."); - - if (TextUtils.isEmpty(number)) { - return null; - } - - com.google.i18n.phonenumbers.PhoneNumberUtil util = - com.google.i18n.phonenumbers.PhoneNumberUtil.getInstance(); - PhoneNumberOfflineGeocoder geocoder = PhoneNumberOfflineGeocoder.getInstance(); - - Locale locale = context.getResources().getConfiguration().locale; - String countryIso = TelephonyManagerUtils.getCurrentCountryIso(context, locale); - Phonenumber.PhoneNumber pn = null; - try { - Log.v(TAG, "parsing '" + pii(number) - + "' for countryIso '" + countryIso + "'..."); - pn = util.parse(number, countryIso); - Log.v(TAG, "- parsed number: " + pii(pn)); - } catch (NumberParseException e) { - Log.v(TAG, "getGeoDescription: NumberParseException for incoming number '" + - pii(number) + "'"); - } - - if (pn != null) { - String description = geocoder.getDescriptionForNumber(pn, locale); - Log.v(TAG, "- got description: '" + description + "'"); - return description; - } - - return null; - } - - private static String pii(Object pii) { - return com.android.incallui.Log.pii(pii); - } -} diff --git a/src/com/android/dialer/util/TelecomUtil.java b/src/com/android/dialer/util/TelecomUtil.java deleted file mode 100644 index 69c7334b9..000000000 --- a/src/com/android/dialer/util/TelecomUtil.java +++ /dev/null @@ -1,229 +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.dialer.util; - -import android.Manifest; -import android.app.Activity; -import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.net.Uri; -import android.provider.CallLog.Calls; -import android.support.annotation.Nullable; -import android.support.v4.content.ContextCompat; -import android.telecom.PhoneAccount; -import android.telecom.PhoneAccountHandle; -import android.telecom.TelecomManager; -import android.telephony.PhoneNumberUtils; -import android.telephony.TelephonyManager; -import android.text.TextUtils; -import android.util.Log; - -import com.android.contacts.common.compat.CompatUtils; -import com.android.contacts.common.compat.telecom.TelecomManagerCompat; -import com.android.dialer.compat.DialerCompatUtils; - -import java.util.ArrayList; -import java.util.List; - -/** - * Performs permission checks before calling into TelecomManager. Each method is self-explanatory - - * perform the required check and return the fallback default if the permission is missing, - * otherwise return the value from TelecomManager. - * - */ -public class TelecomUtil { - private static final String TAG = "TelecomUtil"; - private static boolean sWarningLogged = false; - - public static void showInCallScreen(Context context, boolean showDialpad) { - if (hasReadPhoneStatePermission(context)) { - try { - getTelecomManager(context).showInCallScreen(showDialpad); - } catch (SecurityException e) { - // Just in case - Log.w(TAG, "TelecomManager.showInCallScreen called without permission."); - } - } - } - - public static void silenceRinger(Context context) { - if (hasModifyPhoneStatePermission(context)) { - try { - TelecomManagerCompat.silenceRinger(getTelecomManager(context)); - } catch (SecurityException e) { - // Just in case - Log.w(TAG, "TelecomManager.silenceRinger called without permission."); - } - } - } - - public static void cancelMissedCallsNotification(Context context) { - if (hasModifyPhoneStatePermission(context)) { - try { - getTelecomManager(context).cancelMissedCallsNotification(); - } catch (SecurityException e) { - Log.w(TAG, "TelecomManager.cancelMissedCalls called without permission."); - } - } - } - - public static Uri getAdnUriForPhoneAccount(Context context, PhoneAccountHandle handle) { - if (hasModifyPhoneStatePermission(context)) { - try { - return TelecomManagerCompat.getAdnUriForPhoneAccount( - getTelecomManager(context), handle); - } catch (SecurityException e) { - Log.w(TAG, "TelecomManager.getAdnUriForPhoneAccount called without permission."); - } - } - return null; - } - - public static boolean handleMmi(Context context, String dialString, - @Nullable PhoneAccountHandle handle) { - if (hasModifyPhoneStatePermission(context)) { - try { - if (handle == null) { - return getTelecomManager(context).handleMmi(dialString); - } else { - return getTelecomManager(context).handleMmi(dialString, handle); - } - } catch (SecurityException e) { - Log.w(TAG, "TelecomManager.handleMmi called without permission."); - } - } - return false; - } - - @Nullable - public static PhoneAccountHandle getDefaultOutgoingPhoneAccount(Context context, - String uriScheme) { - if (hasReadPhoneStatePermission(context)) { - return TelecomManagerCompat.getDefaultOutgoingPhoneAccount( - getTelecomManager(context), uriScheme); - } - return null; - } - - public static PhoneAccount getPhoneAccount(Context context, PhoneAccountHandle handle) { - return TelecomManagerCompat.getPhoneAccount(getTelecomManager(context), handle); - } - - public static List<PhoneAccountHandle> getCallCapablePhoneAccounts(Context context) { - if (hasReadPhoneStatePermission(context)) { - return TelecomManagerCompat.getCallCapablePhoneAccounts(getTelecomManager(context)); - } - return new ArrayList<>(); - } - - public static boolean isInCall(Context context) { - if (hasReadPhoneStatePermission(context)) { - return getTelecomManager(context).isInCall(); - } - return false; - } - - public static boolean isVoicemailNumber(Context context, PhoneAccountHandle accountHandle, - String number) { - if (hasReadPhoneStatePermission(context)) { - return TelecomManagerCompat.isVoiceMailNumber(getTelecomManager(context), - accountHandle, number); - } - return false; - } - - @Nullable - public static String getVoicemailNumber(Context context, PhoneAccountHandle accountHandle) { - if (hasReadPhoneStatePermission(context)) { - return TelecomManagerCompat.getVoiceMailNumber(getTelecomManager(context), - getTelephonyManager(context), accountHandle); - } - return null; - } - - /** - * Tries to place a call using the {@link TelecomManager}. - * - * @param activity a valid activity. - * @param intent the call intent. - * - * @return {@code true} if we successfully attempted to place the call, {@code false} if it - * failed due to a permission check. - */ - public static boolean placeCall(Activity activity, Intent intent) { - if (hasCallPhonePermission(activity)) { - TelecomManagerCompat.placeCall(activity, getTelecomManager(activity), intent); - return true; - } - return false; - } - - public static Uri getCallLogUri(Context context) { - return hasReadWriteVoicemailPermissions(context) ? Calls.CONTENT_URI_WITH_VOICEMAIL - : Calls.CONTENT_URI; - } - - public static boolean hasReadWriteVoicemailPermissions(Context context) { - return isDefaultDialer(context) - || (hasPermission(context, Manifest.permission.READ_VOICEMAIL) - && hasPermission(context, Manifest.permission.WRITE_VOICEMAIL)); - } - - public static boolean hasModifyPhoneStatePermission(Context context) { - return isDefaultDialer(context) - || hasPermission(context, Manifest.permission.MODIFY_PHONE_STATE); - } - - public static boolean hasReadPhoneStatePermission(Context context) { - return isDefaultDialer(context) - || hasPermission(context, Manifest.permission.READ_PHONE_STATE); - } - - public static boolean hasCallPhonePermission(Context context) { - return isDefaultDialer(context) - || hasPermission(context, Manifest.permission.CALL_PHONE); - } - - private static boolean hasPermission(Context context, String permission) { - return ContextCompat.checkSelfPermission(context, permission) - == PackageManager.PERMISSION_GRANTED; - } - - public static boolean isDefaultDialer(Context context) { - final boolean result = TextUtils.equals(context.getPackageName(), - TelecomManagerCompat.getDefaultDialerPackage(getTelecomManager(context))); - if (result) { - sWarningLogged = false; - } else { - if (!sWarningLogged) { - // Log only once to prevent spam. - Log.w(TAG, "Dialer is not currently set to be default dialer"); - sWarningLogged = true; - } - } - return result; - } - - private static TelecomManager getTelecomManager(Context context) { - return (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE); - } - - private static TelephonyManager getTelephonyManager(Context context) { - return (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); - } -} |