From 2ca4318cc1ee57dda907ba2069bd61d162b1baef Mon Sep 17 00:00:00 2001 From: Eric Erfanian Date: Thu, 31 Aug 2017 06:57:16 -0700 Subject: Update Dialer source to latest internal Google revision. Previously, Android's Dialer app was developed in an internal Google source control system and only exported to public during AOSP drops. The Dialer team is now switching to a public development model similar to the telephony team. This CL represents all internal Google changes that were committed to Dialer between the public O release and today's tip of tree on internal master. This CL squashes those changes into a single commit. In subsequent changes, changes will be exported on a per-commit basis. Test: make, flash install, run Merged-In: I45270eaa8ce732d71a1bd84b08c7fa0e99af3160 Change-Id: I529aaeb88535b9533c0ae4ef4e6c1222d4e0f1c8 PiperOrigin-RevId: 167068436 --- .../dialer/dialpadview/DialpadFragment.java | 1720 ++++++++++++++++++++ .../android/dialer/dialpadview/DialpadView.java | 9 +- .../dialpadview/PseudoEmergencyAnimator.java | 142 ++ .../dialer/dialpadview/SmartDialCursorLoader.java | 183 +++ .../dialer/dialpadview/SpecialCharSequenceMgr.java | 497 ++++++ .../dialpadview/UnicodeDialerKeyListener.java | 56 + .../res/drawable-hdpi/ic_close_black_24dp.png | Bin 207 -> 0 bytes .../res/drawable-hdpi/ic_dialer_fork_add_call.png | Bin 0 -> 1649 bytes .../drawable-hdpi/ic_dialer_fork_current_call.png | Bin 0 -> 2305 bytes .../res/drawable-hdpi/ic_dialer_fork_tt_keypad.png | Bin 0 -> 2419 bytes .../res/drawable-hdpi/ic_dialpad_delete.png | Bin 805 -> 0 bytes .../res/drawable-hdpi/ic_dialpad_voicemail.png | Bin 623 -> 0 bytes .../res/drawable-hdpi/ic_overflow_menu.png | Bin 503 -> 0 bytes .../res/drawable-mdpi/ic_dialer_fork_add_call.png | Bin 0 -> 1309 bytes .../drawable-mdpi/ic_dialer_fork_current_call.png | Bin 0 -> 1581 bytes .../res/drawable-mdpi/ic_dialer_fork_tt_keypad.png | Bin 0 -> 1586 bytes .../res/drawable-xhdpi/ic_dialer_fork_add_call.png | Bin 0 -> 2150 bytes .../drawable-xhdpi/ic_dialer_fork_current_call.png | Bin 0 -> 3154 bytes .../drawable-xhdpi/ic_dialer_fork_tt_keypad.png | Bin 0 -> 3298 bytes .../drawable-xxhdpi/ic_dialer_fork_add_call.png | Bin 0 -> 2583 bytes .../ic_dialer_fork_current_call.png | Bin 0 -> 3622 bytes .../drawable-xxhdpi/ic_dialer_fork_tt_keypad.png | Bin 0 -> 3229 bytes .../dialpadview/res/drawable/dialpad_scrim.xml | 7 - .../dialpadview/res/drawable/ic_wifi_calling.xml | 29 + .../dialpadview/res/drawable/shadow_fade_left.xml | 24 + .../dialpadview/res/drawable/shadow_fade_up.xml | 24 + .../res/layout-land/dialpad_fragment.xml | 82 + .../res/layout-land/dialpad_key_one.xml | 2 +- .../res/layout/dialpad_chooser_list_item.xml | 38 + .../dialpadview/res/layout/dialpad_fragment.xml | 72 + .../dialpadview/res/layout/dialpad_key_one.xml | 6 +- .../res/layout/dialpad_view_unthemed.xml | 201 +-- .../dialpadview/res/menu/dialpad_options.xml | 30 + .../dialer/dialpadview/res/values-af/strings.xml | 14 + .../dialer/dialpadview/res/values-am/strings.xml | 14 + .../dialer/dialpadview/res/values-ar/strings.xml | 14 + .../dialer/dialpadview/res/values-az/strings.xml | 14 + .../dialpadview/res/values-b+sr+Latn/strings.xml | 14 + .../dialer/dialpadview/res/values-be/strings.xml | 14 + .../dialer/dialpadview/res/values-bg/strings.xml | 14 + .../dialer/dialpadview/res/values-bn/strings.xml | 14 + .../dialer/dialpadview/res/values-bs/strings.xml | 14 + .../dialer/dialpadview/res/values-ca/strings.xml | 14 + .../dialer/dialpadview/res/values-cs/strings.xml | 14 + .../dialer/dialpadview/res/values-da/strings.xml | 14 + .../dialer/dialpadview/res/values-de/strings.xml | 14 + .../dialer/dialpadview/res/values-el/strings.xml | 14 + .../dialpadview/res/values-en-rAU/strings.xml | 14 + .../dialpadview/res/values-en-rGB/strings.xml | 14 + .../dialpadview/res/values-en-rIN/strings.xml | 14 + .../dialpadview/res/values-es-rUS/strings.xml | 14 + .../dialer/dialpadview/res/values-es/strings.xml | 14 + .../dialer/dialpadview/res/values-et/strings.xml | 14 + .../dialer/dialpadview/res/values-eu/strings.xml | 14 + .../dialer/dialpadview/res/values-fa/strings.xml | 14 + .../dialer/dialpadview/res/values-fi/strings.xml | 14 + .../dialpadview/res/values-fr-rCA/strings.xml | 14 + .../dialer/dialpadview/res/values-fr/strings.xml | 14 + .../dialer/dialpadview/res/values-gl/strings.xml | 14 + .../dialer/dialpadview/res/values-gu/strings.xml | 14 + .../dialer/dialpadview/res/values-hi/strings.xml | 14 + .../dialer/dialpadview/res/values-hr/strings.xml | 14 + .../dialer/dialpadview/res/values-hu/strings.xml | 14 + .../dialer/dialpadview/res/values-hy/strings.xml | 14 + .../dialer/dialpadview/res/values-in/strings.xml | 14 + .../dialer/dialpadview/res/values-is/strings.xml | 14 + .../dialer/dialpadview/res/values-it/strings.xml | 14 + .../dialer/dialpadview/res/values-iw/strings.xml | 14 + .../dialer/dialpadview/res/values-ja/strings.xml | 14 + .../dialer/dialpadview/res/values-ka/strings.xml | 14 + .../dialer/dialpadview/res/values-kk/strings.xml | 14 + .../dialer/dialpadview/res/values-km/strings.xml | 14 + .../dialer/dialpadview/res/values-kn/strings.xml | 14 + .../dialer/dialpadview/res/values-ko/strings.xml | 14 + .../dialer/dialpadview/res/values-ky/strings.xml | 14 + .../dialer/dialpadview/res/values-lo/strings.xml | 14 + .../dialer/dialpadview/res/values-lt/strings.xml | 14 + .../dialer/dialpadview/res/values-lv/strings.xml | 14 + .../dialer/dialpadview/res/values-mk/strings.xml | 14 + .../dialer/dialpadview/res/values-ml/strings.xml | 14 + .../dialer/dialpadview/res/values-mn/strings.xml | 14 + .../dialer/dialpadview/res/values-mr/strings.xml | 14 + .../dialer/dialpadview/res/values-ms/strings.xml | 14 + .../dialer/dialpadview/res/values-my/strings.xml | 14 + .../dialer/dialpadview/res/values-nb/strings.xml | 14 + .../dialer/dialpadview/res/values-ne/strings.xml | 14 + .../dialer/dialpadview/res/values-nl/strings.xml | 14 + .../dialer/dialpadview/res/values-no/strings.xml | 14 + .../dialer/dialpadview/res/values-pa/strings.xml | 14 + .../dialer/dialpadview/res/values-pl/strings.xml | 14 + .../dialpadview/res/values-pt-rBR/strings.xml | 14 + .../dialpadview/res/values-pt-rPT/strings.xml | 14 + .../dialer/dialpadview/res/values-pt/strings.xml | 14 + .../dialer/dialpadview/res/values-ro/strings.xml | 14 + .../dialer/dialpadview/res/values-ru/strings.xml | 14 + .../dialer/dialpadview/res/values-si/strings.xml | 14 + .../dialer/dialpadview/res/values-sk/strings.xml | 14 + .../dialer/dialpadview/res/values-sl/strings.xml | 14 + .../dialer/dialpadview/res/values-sq/strings.xml | 14 + .../dialer/dialpadview/res/values-sr/strings.xml | 14 + .../dialer/dialpadview/res/values-sv/strings.xml | 14 + .../dialer/dialpadview/res/values-sw/strings.xml | 14 + .../dialer/dialpadview/res/values-ta/strings.xml | 14 + .../dialer/dialpadview/res/values-te/strings.xml | 14 + .../dialer/dialpadview/res/values-th/strings.xml | 14 + .../dialer/dialpadview/res/values-tl/strings.xml | 14 + .../dialer/dialpadview/res/values-tr/strings.xml | 14 + .../dialer/dialpadview/res/values-uk/strings.xml | 14 + .../dialer/dialpadview/res/values-ur/strings.xml | 14 + .../dialer/dialpadview/res/values-uz/strings.xml | 14 + .../dialer/dialpadview/res/values-vi/strings.xml | 14 + .../dialpadview/res/values-zh-rCN/strings.xml | 14 + .../dialpadview/res/values-zh-rHK/strings.xml | 14 + .../dialpadview/res/values-zh-rTW/strings.xml | 14 + .../dialer/dialpadview/res/values-zu/strings.xml | 14 + .../dialer/dialpadview/res/values/colors.xml | 2 - .../dialer/dialpadview/res/values/dimens.xml | 11 +- .../dialer/dialpadview/res/values/strings.xml | 59 +- 118 files changed, 4218 insertions(+), 124 deletions(-) create mode 100644 java/com/android/dialer/dialpadview/DialpadFragment.java create mode 100644 java/com/android/dialer/dialpadview/PseudoEmergencyAnimator.java create mode 100644 java/com/android/dialer/dialpadview/SmartDialCursorLoader.java create mode 100644 java/com/android/dialer/dialpadview/SpecialCharSequenceMgr.java create mode 100644 java/com/android/dialer/dialpadview/UnicodeDialerKeyListener.java delete mode 100644 java/com/android/dialer/dialpadview/res/drawable-hdpi/ic_close_black_24dp.png create mode 100755 java/com/android/dialer/dialpadview/res/drawable-hdpi/ic_dialer_fork_add_call.png create mode 100755 java/com/android/dialer/dialpadview/res/drawable-hdpi/ic_dialer_fork_current_call.png create mode 100755 java/com/android/dialer/dialpadview/res/drawable-hdpi/ic_dialer_fork_tt_keypad.png delete mode 100644 java/com/android/dialer/dialpadview/res/drawable-hdpi/ic_dialpad_delete.png delete mode 100644 java/com/android/dialer/dialpadview/res/drawable-hdpi/ic_dialpad_voicemail.png delete mode 100644 java/com/android/dialer/dialpadview/res/drawable-hdpi/ic_overflow_menu.png create mode 100644 java/com/android/dialer/dialpadview/res/drawable-mdpi/ic_dialer_fork_add_call.png create mode 100644 java/com/android/dialer/dialpadview/res/drawable-mdpi/ic_dialer_fork_current_call.png create mode 100644 java/com/android/dialer/dialpadview/res/drawable-mdpi/ic_dialer_fork_tt_keypad.png create mode 100644 java/com/android/dialer/dialpadview/res/drawable-xhdpi/ic_dialer_fork_add_call.png create mode 100644 java/com/android/dialer/dialpadview/res/drawable-xhdpi/ic_dialer_fork_current_call.png create mode 100644 java/com/android/dialer/dialpadview/res/drawable-xhdpi/ic_dialer_fork_tt_keypad.png create mode 100644 java/com/android/dialer/dialpadview/res/drawable-xxhdpi/ic_dialer_fork_add_call.png create mode 100644 java/com/android/dialer/dialpadview/res/drawable-xxhdpi/ic_dialer_fork_current_call.png create mode 100644 java/com/android/dialer/dialpadview/res/drawable-xxhdpi/ic_dialer_fork_tt_keypad.png delete mode 100644 java/com/android/dialer/dialpadview/res/drawable/dialpad_scrim.xml create mode 100644 java/com/android/dialer/dialpadview/res/drawable/ic_wifi_calling.xml create mode 100644 java/com/android/dialer/dialpadview/res/drawable/shadow_fade_left.xml create mode 100644 java/com/android/dialer/dialpadview/res/drawable/shadow_fade_up.xml create mode 100644 java/com/android/dialer/dialpadview/res/layout-land/dialpad_fragment.xml create mode 100644 java/com/android/dialer/dialpadview/res/layout/dialpad_chooser_list_item.xml create mode 100644 java/com/android/dialer/dialpadview/res/layout/dialpad_fragment.xml create mode 100644 java/com/android/dialer/dialpadview/res/menu/dialpad_options.xml (limited to 'java/com/android/dialer/dialpadview') diff --git a/java/com/android/dialer/dialpadview/DialpadFragment.java b/java/com/android/dialer/dialpadview/DialpadFragment.java new file mode 100644 index 000000000..c15014fd0 --- /dev/null +++ b/java/com/android/dialer/dialpadview/DialpadFragment.java @@ -0,0 +1,1720 @@ +/* + * 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.dialpadview; + +import android.app.Activity; +import android.app.AlertDialog; +import android.app.Dialog; +import android.app.DialogFragment; +import android.app.Fragment; +import android.content.BroadcastReceiver; +import android.content.ContentResolver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.res.Resources; +import android.database.Cursor; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.media.AudioManager; +import android.media.ToneGenerator; +import android.net.Uri; +import android.os.Bundle; +import android.os.Trace; +import android.provider.Contacts.People; +import android.provider.Contacts.Phones; +import android.provider.Contacts.PhonesColumns; +import android.provider.Settings; +import android.support.annotation.Nullable; +import android.support.annotation.VisibleForTesting; +import android.support.design.widget.FloatingActionButton; +import android.telecom.PhoneAccount; +import android.telecom.PhoneAccountHandle; +import android.telephony.PhoneNumberFormattingTextWatcher; +import android.telephony.PhoneNumberUtils; +import android.telephony.TelephonyManager; +import android.text.Editable; +import android.text.TextUtils; +import android.text.TextWatcher; +import android.util.AttributeSet; +import android.view.HapticFeedbackConstants; +import android.view.KeyEvent; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.BaseAdapter; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.ListView; +import android.widget.PopupMenu; +import android.widget.RelativeLayout; +import android.widget.TextView; +import com.android.contacts.common.dialog.CallSubjectDialog; +import com.android.contacts.common.util.StopWatch; +import com.android.contacts.common.widget.FloatingActionButtonController; +import com.android.dialer.animation.AnimUtils; +import com.android.dialer.callintent.CallInitiationType; +import com.android.dialer.callintent.CallIntentBuilder; +import com.android.dialer.calllogutils.PhoneAccountUtils; +import com.android.dialer.common.FragmentUtils; +import com.android.dialer.common.LogUtil; +import com.android.dialer.common.concurrent.DialerExecutor; +import com.android.dialer.common.concurrent.DialerExecutor.Worker; +import com.android.dialer.common.concurrent.DialerExecutors; +import com.android.dialer.location.GeoUtil; +import com.android.dialer.logging.UiAction; +import com.android.dialer.oem.MotorolaUtils; +import com.android.dialer.performancereport.PerformanceReport; +import com.android.dialer.proguard.UsedByReflection; +import com.android.dialer.telecom.TelecomUtil; +import com.android.dialer.util.CallUtil; +import com.android.dialer.util.DialerUtils; +import com.android.dialer.util.PermissionsUtil; +import java.util.HashSet; +import java.util.List; + +/** Fragment that displays a twelve-key phone dialpad. */ +public class DialpadFragment extends Fragment + implements View.OnClickListener, + View.OnLongClickListener, + View.OnKeyListener, + AdapterView.OnItemClickListener, + TextWatcher, + PopupMenu.OnMenuItemClickListener, + DialpadKeyButton.OnPressedListener { + + private static final String TAG = "DialpadFragment"; + private static final String EMPTY_NUMBER = ""; + private static final char PAUSE = ','; + private static final char WAIT = ';'; + /** The length of DTMF tones in milliseconds */ + private static final int TONE_LENGTH_MS = 150; + + private static final int TONE_LENGTH_INFINITE = -1; + /** The DTMF tone volume relative to other sounds in the stream */ + private static final int TONE_RELATIVE_VOLUME = 80; + /** Stream type used to play the DTMF tones off call, and mapped to the volume control keys */ + private static final int DIAL_TONE_STREAM_TYPE = AudioManager.STREAM_DTMF; + /** Identifier for the "Add Call" intent extra. */ + private static final String ADD_CALL_MODE_KEY = "add_call_mode"; + /** + * Identifier for intent extra for sending an empty Flash message for CDMA networks. This message + * is used by the network to simulate a press/depress of the "hookswitch" of a landline phone. Aka + * "empty flash". + * + *

TODO: Using an intent extra to tell the phone to send this flash is a temporary measure. To + * be replaced with an Telephony/TelecomManager call in the future. TODO: Keep in sync with the + * string defined in OutgoingCallBroadcaster.java in Phone app until this is replaced with the + * Telephony/Telecom API. + */ + private static final String EXTRA_SEND_EMPTY_FLASH = "com.android.phone.extra.SEND_EMPTY_FLASH"; + + private static final String PREF_DIGITS_FILLED_BY_INTENT = "pref_digits_filled_by_intent"; + private final Object mToneGeneratorLock = new Object(); + /** Set of dialpad keys that are currently being pressed */ + private final HashSet mPressedDialpadKeys = new HashSet<>(12); + + private OnDialpadQueryChangedListener mDialpadQueryListener; + private DialpadView mDialpadView; + private EditText mDigits; + private int mDialpadSlideInDuration; + /** Remembers if we need to clear digits field when the screen is completely gone. */ + private boolean mClearDigitsOnStop; + + private View mOverflowMenuButton; + private PopupMenu mOverflowPopupMenu; + private View mDelete; + private ToneGenerator mToneGenerator; + private FloatingActionButtonController mFloatingActionButtonController; + private FloatingActionButton mFloatingActionButton; + private ListView mDialpadChooser; + private DialpadChooserAdapter mDialpadChooserAdapter; + /** Regular expression prohibiting manual phone call. Can be empty, which means "no rule". */ + private String mProhibitedPhoneNumberRegexp; + + private PseudoEmergencyAnimator mPseudoEmergencyAnimator; + private String mLastNumberDialed = EMPTY_NUMBER; + + // determines if we want to playback local DTMF tones. + private boolean mDTMFToneEnabled; + private String mCurrentCountryIso; + private CallStateReceiver mCallStateReceiver; + private boolean mWasEmptyBeforeTextChange; + /** + * This field is set to true while processing an incoming DIAL intent, in order to make sure that + * SpecialCharSequenceMgr actions can be triggered by user input but *not* by a tel: URI passed by + * some other app. It will be set to false when all digits are cleared. + */ + private boolean mDigitsFilledByIntent; + + private boolean mStartedFromNewIntent = false; + private boolean mFirstLaunch = false; + private boolean mAnimate = false; + + private DialerExecutor initPhoneNumberFormattingTextWatcherExecutor; + + /** + * Determines whether an add call operation is requested. + * + * @param intent The intent. + * @return {@literal true} if add call operation was requested. {@literal false} otherwise. + */ + public static boolean isAddCallMode(Intent intent) { + if (intent == null) { + return false; + } + final String action = intent.getAction(); + if (Intent.ACTION_DIAL.equals(action) || Intent.ACTION_VIEW.equals(action)) { + // see if we are "adding a call" from the InCallScreen; false by default. + return intent.getBooleanExtra(ADD_CALL_MODE_KEY, false); + } else { + return false; + } + } + + /** + * Format the provided string of digits into one that represents a properly formatted phone + * number. + * + * @param dialString String of characters to format + * @param normalizedNumber the E164 format number whose country code is used if the given + * phoneNumber doesn't have the country code. + * @param countryIso The country code representing the format to use if the provided normalized + * number is null or invalid. + * @return the provided string of digits as a formatted phone number, retaining any post-dial + * portion of the string. + */ + @VisibleForTesting + static String getFormattedDigits(String dialString, String normalizedNumber, String countryIso) { + String number = PhoneNumberUtils.extractNetworkPortion(dialString); + // Also retrieve the post dial portion of the provided data, so that the entire dial + // string can be reconstituted later. + final String postDial = PhoneNumberUtils.extractPostDialPortion(dialString); + + if (TextUtils.isEmpty(number)) { + return postDial; + } + + number = PhoneNumberUtils.formatNumber(number, normalizedNumber, countryIso); + + if (TextUtils.isEmpty(postDial)) { + return number; + } + + return number.concat(postDial); + } + + /** + * Returns true of the newDigit parameter can be added at the current selection point, otherwise + * returns false. Only prevents input of WAIT and PAUSE digits at an unsupported position. Fails + * early if start == -1 or start is larger than end. + */ + @VisibleForTesting + /* package */ static boolean canAddDigit(CharSequence digits, int start, int end, char newDigit) { + if (newDigit != WAIT && newDigit != PAUSE) { + throw new IllegalArgumentException( + "Should not be called for anything other than PAUSE & WAIT"); + } + + // False if no selection, or selection is reversed (end < start) + if (start == -1 || end < start) { + return false; + } + + // unsupported selection-out-of-bounds state + if (start > digits.length() || end > digits.length()) { + return false; + } + + // Special digit cannot be the first digit + if (start == 0) { + return false; + } + + if (newDigit == WAIT) { + // preceding char is ';' (WAIT) + if (digits.charAt(start - 1) == WAIT) { + return false; + } + + // next char is ';' (WAIT) + if ((digits.length() > end) && (digits.charAt(end) == WAIT)) { + return false; + } + } + + return true; + } + + private TelephonyManager getTelephonyManager() { + return (TelephonyManager) getActivity().getSystemService(Context.TELEPHONY_SERVICE); + } + + @Override + public Context getContext() { + return getActivity(); + } + + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + mWasEmptyBeforeTextChange = TextUtils.isEmpty(s); + } + + @Override + public void onTextChanged(CharSequence input, int start, int before, int changeCount) { + if (mWasEmptyBeforeTextChange != TextUtils.isEmpty(input)) { + final Activity activity = getActivity(); + if (activity != null) { + activity.invalidateOptionsMenu(); + updateMenuOverflowButton(mWasEmptyBeforeTextChange); + } + } + + // DTMF Tones do not need to be played here any longer - + // the DTMF dialer handles that functionality now. + } + + @Override + public void afterTextChanged(Editable input) { + // When DTMF dialpad buttons are being pressed, we delay SpecialCharSequenceMgr sequence, + // since some of SpecialCharSequenceMgr's behavior is too abrupt for the "touch-down" + // behavior. + if (!mDigitsFilledByIntent + && SpecialCharSequenceMgr.handleChars(getActivity(), input.toString(), mDigits)) { + // A special sequence was entered, clear the digits + mDigits.getText().clear(); + } + + if (isDigitsEmpty()) { + mDigitsFilledByIntent = false; + mDigits.setCursorVisible(false); + } + + if (mDialpadQueryListener != null) { + mDialpadQueryListener.onDialpadQueryChanged(mDigits.getText().toString()); + } + + updateDeleteButtonEnabledState(); + } + + @Override + public void onCreate(Bundle state) { + Trace.beginSection(TAG + " onCreate"); + super.onCreate(state); + + mFirstLaunch = state == null; + + mCurrentCountryIso = GeoUtil.getCurrentCountryIso(getActivity()); + + mProhibitedPhoneNumberRegexp = + getResources().getString(R.string.config_prohibited_phone_number_regexp); + + if (state != null) { + mDigitsFilledByIntent = state.getBoolean(PREF_DIGITS_FILLED_BY_INTENT); + } + + mDialpadSlideInDuration = getResources().getInteger(R.integer.dialpad_slide_in_duration); + + if (mCallStateReceiver == null) { + IntentFilter callStateIntentFilter = + new IntentFilter(TelephonyManager.ACTION_PHONE_STATE_CHANGED); + mCallStateReceiver = new CallStateReceiver(); + getActivity().registerReceiver(mCallStateReceiver, callStateIntentFilter); + } + + initPhoneNumberFormattingTextWatcherExecutor = + DialerExecutors.createUiTaskBuilder( + getFragmentManager(), + "DialpadFragment.initPhoneNumberFormattingTextWatcher", + new InitPhoneNumberFormattingTextWatcherWorker()) + .onSuccess(watcher -> mDialpadView.getDigits().addTextChangedListener(watcher)) + .build(); + Trace.endSection(); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) { + Trace.beginSection(TAG + " onCreateView"); + Trace.beginSection(TAG + " inflate view"); + View fragmentView = inflater.inflate(R.layout.dialpad_fragment, container, false); + Trace.endSection(); + Trace.beginSection(TAG + " buildLayer"); + fragmentView.buildLayer(); + Trace.endSection(); + + Trace.beginSection(TAG + " setup views"); + + mDialpadView = fragmentView.findViewById(R.id.dialpad_view); + mDialpadView.setCanDigitsBeEdited(true); + mDigits = mDialpadView.getDigits(); + mDigits.setKeyListener(UnicodeDialerKeyListener.INSTANCE); + mDigits.setOnClickListener(this); + mDigits.setOnKeyListener(this); + mDigits.setOnLongClickListener(this); + mDigits.addTextChangedListener(this); + mDigits.setElegantTextHeight(false); + + initPhoneNumberFormattingTextWatcherExecutor.executeSerial( + GeoUtil.getCurrentCountryIso(getActivity())); + + // Check for the presence of the keypad + View oneButton = fragmentView.findViewById(R.id.one); + if (oneButton != null) { + configureKeypadListeners(fragmentView); + } + + mDelete = mDialpadView.getDeleteButton(); + + if (mDelete != null) { + mDelete.setOnClickListener(this); + mDelete.setOnLongClickListener(this); + } + + fragmentView + .findViewById(R.id.spacer) + .setOnTouchListener( + (v, event) -> { + if (isDigitsEmpty()) { + if (getActivity() != null) { + return ((HostInterface) getActivity()).onDialpadSpacerTouchWithEmptyQuery(); + } + return true; + } + return false; + }); + + mDigits.setCursorVisible(false); + + // Set up the "dialpad chooser" UI; see showDialpadChooser(). + mDialpadChooser = fragmentView.findViewById(R.id.dialpadChooser); + mDialpadChooser.setOnItemClickListener(this); + + mFloatingActionButton = fragmentView.findViewById(R.id.dialpad_floating_action_button); + mFloatingActionButton.setOnClickListener(this); + mFloatingActionButtonController = + new FloatingActionButtonController(getActivity(), mFloatingActionButton); + Trace.endSection(); + Trace.endSection(); + return fragmentView; + } + + private boolean isLayoutReady() { + return mDigits != null; + } + + public EditText getDigitsWidget() { + return mDigits; + } + + /** @return true when {@link #mDigits} is actually filled by the Intent. */ + private boolean fillDigitsIfNecessary(Intent intent) { + // Only fills digits from an intent if it is a new intent. + // Otherwise falls back to the previously used number. + if (!mFirstLaunch && !mStartedFromNewIntent) { + return false; + } + + final String action = intent.getAction(); + if (Intent.ACTION_DIAL.equals(action) || Intent.ACTION_VIEW.equals(action)) { + Uri uri = intent.getData(); + if (uri != null) { + if (PhoneAccount.SCHEME_TEL.equals(uri.getScheme())) { + // Put the requested number into the input area + String data = uri.getSchemeSpecificPart(); + // Remember it is filled via Intent. + mDigitsFilledByIntent = true; + final String converted = + PhoneNumberUtils.convertKeypadLettersToDigits( + PhoneNumberUtils.replaceUnicodeDigits(data)); + setFormattedDigits(converted, null); + return true; + } else { + if (!PermissionsUtil.hasContactsReadPermissions(getActivity())) { + return false; + } + String type = intent.getType(); + if (People.CONTENT_ITEM_TYPE.equals(type) || Phones.CONTENT_ITEM_TYPE.equals(type)) { + // Query the phone number + Cursor c = + getActivity() + .getContentResolver() + .query( + intent.getData(), + new String[] {PhonesColumns.NUMBER, PhonesColumns.NUMBER_KEY}, + null, + null, + null); + if (c != null) { + try { + if (c.moveToFirst()) { + // Remember it is filled via Intent. + mDigitsFilledByIntent = true; + // Put the number into the input area + setFormattedDigits(c.getString(0), c.getString(1)); + return true; + } + } finally { + c.close(); + } + } + } + } + } + } + return false; + } + + /** + * Checks the given Intent and changes dialpad's UI state. For example, if the Intent requires the + * screen to enter "Add Call" mode, this method will show correct UI for the mode. + */ + private void configureScreenFromIntent(Activity parent) { + // If we were not invoked with a DIAL intent + if (!Intent.ACTION_DIAL.equals(parent.getIntent().getAction())) { + setStartedFromNewIntent(false); + return; + } + + // See if we were invoked with a DIAL intent. If we were, fill in the appropriate + // digits in the dialer field. + Intent intent = parent.getIntent(); + + if (!isLayoutReady()) { + // This happens typically when parent's Activity#onNewIntent() is called while + // Fragment#onCreateView() isn't called yet, and thus we cannot configure Views at + // this point. onViewCreate() should call this method after preparing layouts, so + // just ignore this call now. + LogUtil.i( + "DialpadFragment.configureScreenFromIntent", + "Screen configuration is requested before onCreateView() is called. Ignored"); + return; + } + + boolean needToShowDialpadChooser = false; + + // Be sure *not* to show the dialpad chooser if this is an + // explicit "Add call" action, though. + final boolean isAddCallMode = isAddCallMode(intent); + if (!isAddCallMode) { + + // Don't show the chooser when called via onNewIntent() and phone number is present. + // i.e. User clicks a telephone link from gmail for example. + // In this case, we want to show the dialpad with the phone number. + final boolean digitsFilled = fillDigitsIfNecessary(intent); + if (!(mStartedFromNewIntent && digitsFilled)) { + + final String action = intent.getAction(); + if (Intent.ACTION_DIAL.equals(action) + || Intent.ACTION_VIEW.equals(action) + || Intent.ACTION_MAIN.equals(action)) { + // If there's already an active call, bring up an intermediate UI to + // make the user confirm what they really want to do. + if (isPhoneInUse()) { + needToShowDialpadChooser = true; + } + } + } + } + showDialpadChooser(needToShowDialpadChooser); + setStartedFromNewIntent(false); + } + + public void setStartedFromNewIntent(boolean value) { + mStartedFromNewIntent = value; + } + + public void clearCallRateInformation() { + setCallRateInformation(null, null); + } + + public void setCallRateInformation(String countryName, String displayRate) { + mDialpadView.setCallRateInformation(countryName, displayRate); + } + + /** Sets formatted digits to digits field. */ + private void setFormattedDigits(String data, String normalizedNumber) { + final String formatted = getFormattedDigits(data, normalizedNumber, mCurrentCountryIso); + if (!TextUtils.isEmpty(formatted)) { + Editable digits = mDigits.getText(); + digits.replace(0, digits.length(), formatted); + // for some reason this isn't getting called in the digits.replace call above.. + // but in any case, this will make sure the background drawable looks right + afterTextChanged(digits); + } + } + + private void configureKeypadListeners(View fragmentView) { + final int[] buttonIds = + new int[] { + R.id.one, + R.id.two, + R.id.three, + R.id.four, + R.id.five, + R.id.six, + R.id.seven, + R.id.eight, + R.id.nine, + R.id.star, + R.id.zero, + R.id.pound + }; + + DialpadKeyButton dialpadKey; + + for (int buttonId : buttonIds) { + dialpadKey = fragmentView.findViewById(buttonId); + dialpadKey.setOnPressedListener(this); + } + + // Long-pressing one button will initiate Voicemail. + final DialpadKeyButton one = fragmentView.findViewById(R.id.one); + one.setOnLongClickListener(this); + + // Long-pressing zero button will enter '+' instead. + final DialpadKeyButton zero = fragmentView.findViewById(R.id.zero); + zero.setOnLongClickListener(this); + } + + @Override + public void onStart() { + LogUtil.d("DialpadFragment.onStart", "first launch: %b", mFirstLaunch); + Trace.beginSection(TAG + " onStart"); + super.onStart(); + // if the mToneGenerator creation fails, just continue without it. It is + // a local audio signal, and is not as important as the dtmf tone itself. + final long start = System.currentTimeMillis(); + synchronized (mToneGeneratorLock) { + if (mToneGenerator == null) { + try { + mToneGenerator = new ToneGenerator(DIAL_TONE_STREAM_TYPE, TONE_RELATIVE_VOLUME); + } catch (RuntimeException e) { + LogUtil.e( + "DialpadFragment.onStart", + "Exception caught while creating local tone generator: " + e); + mToneGenerator = null; + } + } + } + final long total = System.currentTimeMillis() - start; + if (total > 50) { + LogUtil.i("DialpadFragment.onStart", "Time for ToneGenerator creation: " + total); + } + Trace.endSection(); + } + + @Override + public void onResume() { + LogUtil.d("DialpadFragment.onResume", ""); + Trace.beginSection(TAG + " onResume"); + super.onResume(); + + Resources res = getResources(); + int iconId = R.drawable.quantum_ic_call_vd_theme_24; + if (MotorolaUtils.isWifiCallingAvailable(getContext())) { + iconId = R.drawable.ic_wifi_calling; + } + mFloatingActionButtonController.changeIcon( + res.getDrawable(iconId, null), res.getString(R.string.description_dial_button)); + + mDialpadQueryListener = + FragmentUtils.getParentUnsafe(this, OnDialpadQueryChangedListener.class); + + final StopWatch stopWatch = StopWatch.start("Dialpad.onResume"); + + // Query the last dialed number. Do it first because hitting + // the DB is 'slow'. This call is asynchronous. + queryLastOutgoingCall(); + + stopWatch.lap("qloc"); + + final ContentResolver contentResolver = getActivity().getContentResolver(); + + // retrieve the DTMF tone play back setting. + mDTMFToneEnabled = + Settings.System.getInt(contentResolver, Settings.System.DTMF_TONE_WHEN_DIALING, 1) == 1; + + stopWatch.lap("dtwd"); + + stopWatch.lap("hptc"); + + mPressedDialpadKeys.clear(); + + configureScreenFromIntent(getActivity()); + + stopWatch.lap("fdin"); + + if (!isPhoneInUse()) { + // A sanity-check: the "dialpad chooser" UI should not be visible if the phone is idle. + showDialpadChooser(false); + } + + stopWatch.lap("hnt"); + + updateDeleteButtonEnabledState(); + + stopWatch.lap("bes"); + + stopWatch.stopAndLog(TAG, 50); + + // Populate the overflow menu in onResume instead of onCreate, so that if the SMS activity + // is disabled while Dialer is paused, the "Send a text message" option can be correctly + // removed when resumed. + mOverflowMenuButton = mDialpadView.getOverflowMenuButton(); + mOverflowPopupMenu = buildOptionsMenu(mOverflowMenuButton); + mOverflowMenuButton.setOnTouchListener(mOverflowPopupMenu.getDragToOpenListener()); + mOverflowMenuButton.setOnClickListener(this); + mOverflowMenuButton.setVisibility(isDigitsEmpty() ? View.INVISIBLE : View.VISIBLE); + + if (mFirstLaunch) { + // The onHiddenChanged callback does not get called the first time the fragment is + // attached, so call it ourselves here. + onHiddenChanged(false); + } + + mFirstLaunch = false; + Trace.endSection(); + } + + @Override + public void onPause() { + super.onPause(); + + // Make sure we don't leave this activity with a tone still playing. + stopTone(); + mPressedDialpadKeys.clear(); + + // TODO: I wonder if we should not check if the AsyncTask that + // lookup the last dialed number has completed. + mLastNumberDialed = EMPTY_NUMBER; // Since we are going to query again, free stale number. + + SpecialCharSequenceMgr.cleanup(); + mOverflowPopupMenu.dismiss(); + } + + @Override + public void onStop() { + super.onStop(); + + synchronized (mToneGeneratorLock) { + if (mToneGenerator != null) { + mToneGenerator.release(); + mToneGenerator = null; + } + } + + if (mClearDigitsOnStop) { + mClearDigitsOnStop = false; + clearDialpad(); + } + } + + @Override + public void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + outState.putBoolean(PREF_DIGITS_FILLED_BY_INTENT, mDigitsFilledByIntent); + } + + @Override + public void onDestroy() { + super.onDestroy(); + if (mPseudoEmergencyAnimator != null) { + mPseudoEmergencyAnimator.destroy(); + mPseudoEmergencyAnimator = null; + } + getActivity().unregisterReceiver(mCallStateReceiver); + } + + private void keyPressed(int keyCode) { + if (getView() == null || getView().getTranslationY() != 0) { + return; + } + switch (keyCode) { + case KeyEvent.KEYCODE_1: + playTone(ToneGenerator.TONE_DTMF_1, TONE_LENGTH_INFINITE); + break; + case KeyEvent.KEYCODE_2: + playTone(ToneGenerator.TONE_DTMF_2, TONE_LENGTH_INFINITE); + break; + case KeyEvent.KEYCODE_3: + playTone(ToneGenerator.TONE_DTMF_3, TONE_LENGTH_INFINITE); + break; + case KeyEvent.KEYCODE_4: + playTone(ToneGenerator.TONE_DTMF_4, TONE_LENGTH_INFINITE); + break; + case KeyEvent.KEYCODE_5: + playTone(ToneGenerator.TONE_DTMF_5, TONE_LENGTH_INFINITE); + break; + case KeyEvent.KEYCODE_6: + playTone(ToneGenerator.TONE_DTMF_6, TONE_LENGTH_INFINITE); + break; + case KeyEvent.KEYCODE_7: + playTone(ToneGenerator.TONE_DTMF_7, TONE_LENGTH_INFINITE); + break; + case KeyEvent.KEYCODE_8: + playTone(ToneGenerator.TONE_DTMF_8, TONE_LENGTH_INFINITE); + break; + case KeyEvent.KEYCODE_9: + playTone(ToneGenerator.TONE_DTMF_9, TONE_LENGTH_INFINITE); + break; + case KeyEvent.KEYCODE_0: + playTone(ToneGenerator.TONE_DTMF_0, TONE_LENGTH_INFINITE); + break; + case KeyEvent.KEYCODE_POUND: + playTone(ToneGenerator.TONE_DTMF_P, TONE_LENGTH_INFINITE); + break; + case KeyEvent.KEYCODE_STAR: + playTone(ToneGenerator.TONE_DTMF_S, TONE_LENGTH_INFINITE); + break; + default: + break; + } + + getView().performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY); + KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, keyCode); + mDigits.onKeyDown(keyCode, event); + + // If the cursor is at the end of the text we hide it. + final int length = mDigits.length(); + if (length == mDigits.getSelectionStart() && length == mDigits.getSelectionEnd()) { + mDigits.setCursorVisible(false); + } + } + + @Override + public boolean onKey(View view, int keyCode, KeyEvent event) { + if (view.getId() == R.id.digits) { + if (keyCode == KeyEvent.KEYCODE_ENTER) { + handleDialButtonPressed(); + return true; + } + } + return false; + } + + /** + * When a key is pressed, we start playing DTMF tone, do vibration, and enter the digit + * immediately. When a key is released, we stop the tone. Note that the "key press" event will be + * delivered by the system with certain amount of delay, it won't be synced with user's actual + * "touch-down" behavior. + */ + @Override + public void onPressed(View view, boolean pressed) { + if (pressed) { + int resId = view.getId(); + if (resId == R.id.one) { + keyPressed(KeyEvent.KEYCODE_1); + } else if (resId == R.id.two) { + keyPressed(KeyEvent.KEYCODE_2); + } else if (resId == R.id.three) { + keyPressed(KeyEvent.KEYCODE_3); + } else if (resId == R.id.four) { + keyPressed(KeyEvent.KEYCODE_4); + } else if (resId == R.id.five) { + keyPressed(KeyEvent.KEYCODE_5); + } else if (resId == R.id.six) { + keyPressed(KeyEvent.KEYCODE_6); + } else if (resId == R.id.seven) { + keyPressed(KeyEvent.KEYCODE_7); + } else if (resId == R.id.eight) { + keyPressed(KeyEvent.KEYCODE_8); + } else if (resId == R.id.nine) { + keyPressed(KeyEvent.KEYCODE_9); + } else if (resId == R.id.zero) { + keyPressed(KeyEvent.KEYCODE_0); + } else if (resId == R.id.pound) { + keyPressed(KeyEvent.KEYCODE_POUND); + } else if (resId == R.id.star) { + keyPressed(KeyEvent.KEYCODE_STAR); + } else { + LogUtil.e( + "DialpadFragment.onPressed", "Unexpected onTouch(ACTION_DOWN) event from: " + view); + } + mPressedDialpadKeys.add(view); + } else { + mPressedDialpadKeys.remove(view); + if (mPressedDialpadKeys.isEmpty()) { + stopTone(); + } + } + } + + /** + * Called by the containing Activity to tell this Fragment to build an overflow options menu for + * display by the container when appropriate. + * + * @param invoker the View that invoked the options menu, to act as an anchor location. + */ + private PopupMenu buildOptionsMenu(View invoker) { + final PopupMenu popupMenu = + new PopupMenu(getActivity(), invoker) { + @Override + public void show() { + final Menu menu = getMenu(); + + boolean enable = !isDigitsEmpty(); + for (int i = 0; i < menu.size(); i++) { + MenuItem item = menu.getItem(i); + item.setEnabled(enable); + if (item.getItemId() == R.id.menu_call_with_note) { + item.setVisible(CallUtil.isCallWithSubjectSupported(getContext())); + } + } + super.show(); + } + }; + popupMenu.inflate(R.menu.dialpad_options); + popupMenu.setOnMenuItemClickListener(this); + return popupMenu; + } + + @Override + public void onClick(View view) { + int resId = view.getId(); + if (resId == R.id.dialpad_floating_action_button) { + view.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY); + handleDialButtonPressed(); + } else if (resId == R.id.deleteButton) { + keyPressed(KeyEvent.KEYCODE_DEL); + } else if (resId == R.id.digits) { + if (!isDigitsEmpty()) { + mDigits.setCursorVisible(true); + } + } else if (resId == R.id.dialpad_overflow) { + mOverflowPopupMenu.show(); + } else { + LogUtil.w("DialpadFragment.onClick", "Unexpected event from: " + view); + } + } + + @Override + public boolean onLongClick(View view) { + final Editable digits = mDigits.getText(); + final int id = view.getId(); + if (id == R.id.deleteButton) { + digits.clear(); + return true; + } else if (id == R.id.one) { + if (isDigitsEmpty() || TextUtils.equals(mDigits.getText(), "1")) { + // We'll try to initiate voicemail and thus we want to remove irrelevant string. + removePreviousDigitIfPossible('1'); + + List subscriptionAccountHandles = + PhoneAccountUtils.getSubscriptionPhoneAccounts(getActivity()); + boolean hasUserSelectedDefault = + subscriptionAccountHandles.contains( + TelecomUtil.getDefaultOutgoingPhoneAccount( + getActivity(), PhoneAccount.SCHEME_VOICEMAIL)); + boolean needsAccountDisambiguation = + subscriptionAccountHandles.size() > 1 && !hasUserSelectedDefault; + + if (needsAccountDisambiguation || isVoicemailAvailable()) { + // On a multi-SIM phone, if the user has not selected a default + // subscription, initiate a call to voicemail so they can select an account + // from the "Call with" dialog. + callVoicemail(); + } else if (getActivity() != null) { + // Voicemail is unavailable maybe because Airplane mode is turned on. + // Check the current status and show the most appropriate error message. + final boolean isAirplaneModeOn = + Settings.System.getInt( + getActivity().getContentResolver(), Settings.System.AIRPLANE_MODE_ON, 0) + != 0; + if (isAirplaneModeOn) { + DialogFragment dialogFragment = + ErrorDialogFragment.newInstance(R.string.dialog_voicemail_airplane_mode_message); + dialogFragment.show(getFragmentManager(), "voicemail_request_during_airplane_mode"); + } else { + DialogFragment dialogFragment = + ErrorDialogFragment.newInstance(R.string.dialog_voicemail_not_ready_message); + dialogFragment.show(getFragmentManager(), "voicemail_not_ready"); + } + } + return true; + } + return false; + } else if (id == R.id.zero) { + if (mPressedDialpadKeys.contains(view)) { + // If the zero key is currently pressed, then the long press occurred by touch + // (and not via other means like certain accessibility input methods). + // Remove the '0' that was input when the key was first pressed. + removePreviousDigitIfPossible('0'); + } + keyPressed(KeyEvent.KEYCODE_PLUS); + stopTone(); + mPressedDialpadKeys.remove(view); + return true; + } else if (id == R.id.digits) { + mDigits.setCursorVisible(true); + return false; + } + return false; + } + + /** + * Remove the digit just before the current position of the cursor, iff the following conditions + * are true: 1) The cursor is not positioned at index 0. 2) The digit before the current cursor + * position matches the current digit. + * + * @param digit to remove from the digits view. + */ + private void removePreviousDigitIfPossible(char digit) { + final int currentPosition = mDigits.getSelectionStart(); + if (currentPosition > 0 && digit == mDigits.getText().charAt(currentPosition - 1)) { + mDigits.setSelection(currentPosition); + mDigits.getText().delete(currentPosition - 1, currentPosition); + } + } + + public void callVoicemail() { + DialerUtils.startActivityWithErrorToast( + getActivity(), + new CallIntentBuilder(CallUtil.getVoicemailUri(), CallInitiationType.Type.DIALPAD).build()); + hideAndClearDialpad(false); + } + + private void hideAndClearDialpad(boolean animate) { + FragmentUtils.getParentUnsafe(this, DialpadListener.class).hideDialpadFragment(animate, true); + } + + /** + * In most cases, when the dial button is pressed, there is a number in digits area. Pack it in + * the intent, start the outgoing call broadcast as a separate task and finish this activity. + * + *

When there is no digit and the phone is CDMA and off hook, we're sending a blank flash for + * CDMA. CDMA networks use Flash messages when special processing needs to be done, mainly for + * 3-way or call waiting scenarios. Presumably, here we're in a special 3-way scenario where the + * network needs a blank flash before being able to add the new participant. (This is not the case + * with all 3-way calls, just certain CDMA infrastructures.) + * + *

Otherwise, there is no digit, display the last dialed number. Don't finish since the user + * may want to edit it. The user needs to press the dial button again, to dial it (general case + * described above). + */ + private void handleDialButtonPressed() { + if (isDigitsEmpty()) { // No number entered. + // No real call made, so treat it as a click + PerformanceReport.recordClick(UiAction.Type.PRESS_CALL_BUTTON_WITHOUT_CALLING); + handleDialButtonClickWithEmptyDigits(); + } else { + final String number = mDigits.getText().toString(); + + // "persist.radio.otaspdial" is a temporary hack needed for one carrier's automated + // test equipment. + // TODO: clean it up. + if (number != null + && !TextUtils.isEmpty(mProhibitedPhoneNumberRegexp) + && number.matches(mProhibitedPhoneNumberRegexp)) { + PerformanceReport.recordClick(UiAction.Type.PRESS_CALL_BUTTON_WITHOUT_CALLING); + LogUtil.i( + "DialpadFragment.handleDialButtonPressed", + "The phone number is prohibited explicitly by a rule."); + if (getActivity() != null) { + DialogFragment dialogFragment = + ErrorDialogFragment.newInstance(R.string.dialog_phone_call_prohibited_message); + dialogFragment.show(getFragmentManager(), "phone_prohibited_dialog"); + } + + // Clear the digits just in case. + clearDialpad(); + } else { + final Intent intent = + new CallIntentBuilder(number, CallInitiationType.Type.DIALPAD).build(); + DialerUtils.startActivityWithErrorToast(getActivity(), intent); + hideAndClearDialpad(false); + } + } + } + + public void clearDialpad() { + if (mDigits != null) { + mDigits.getText().clear(); + } + } + + private void handleDialButtonClickWithEmptyDigits() { + if (phoneIsCdma() && isPhoneInUse()) { + // TODO: Move this logic into services/Telephony + // + // This is really CDMA specific. On GSM is it possible + // to be off hook and wanted to add a 3rd party using + // the redial feature. + startActivity(newFlashIntent()); + } else { + if (!TextUtils.isEmpty(mLastNumberDialed)) { + // Dialpad will be filled with last called number, + // but we don't want to record it as user action + PerformanceReport.setIgnoreActionOnce(UiAction.Type.TEXT_CHANGE_WITH_INPUT); + + // Recall the last number dialed. + mDigits.setText(mLastNumberDialed); + + // ...and move the cursor to the end of the digits string, + // so you'll be able to delete digits using the Delete + // button (just as if you had typed the number manually.) + // + // Note we use mDigits.getText().length() here, not + // mLastNumberDialed.length(), since the EditText widget now + // contains a *formatted* version of mLastNumberDialed (due to + // mTextWatcher) and its length may have changed. + mDigits.setSelection(mDigits.getText().length()); + } else { + // There's no "last number dialed" or the + // background query is still running. There's + // nothing useful for the Dial button to do in + // this case. Note: with a soft dial button, this + // can never happens since the dial button is + // disabled under these conditons. + playTone(ToneGenerator.TONE_PROP_NACK); + } + } + } + + /** Plays the specified tone for TONE_LENGTH_MS milliseconds. */ + private void playTone(int tone) { + playTone(tone, TONE_LENGTH_MS); + } + + /** + * Play the specified tone for the specified milliseconds + * + *

The tone is played locally, using the audio stream for phone calls. Tones are played only if + * the "Audible touch tones" user preference is checked, and are NOT played if the device is in + * silent mode. + * + *

The tone length can be -1, meaning "keep playing the tone." If the caller does so, it should + * call stopTone() afterward. + * + * @param tone a tone code from {@link ToneGenerator} + * @param durationMs tone length. + */ + private void playTone(int tone, int durationMs) { + // if local tone playback is disabled, just return. + if (!mDTMFToneEnabled) { + return; + } + + // Also do nothing if the phone is in silent mode. + // We need to re-check the ringer mode for *every* playTone() + // call, rather than keeping a local flag that's updated in + // onResume(), since it's possible to toggle silent mode without + // leaving the current activity (via the ENDCALL-longpress menu.) + AudioManager audioManager = + (AudioManager) getActivity().getSystemService(Context.AUDIO_SERVICE); + int ringerMode = audioManager.getRingerMode(); + if ((ringerMode == AudioManager.RINGER_MODE_SILENT) + || (ringerMode == AudioManager.RINGER_MODE_VIBRATE)) { + return; + } + + synchronized (mToneGeneratorLock) { + if (mToneGenerator == null) { + LogUtil.w("DialpadFragment.playTone", "mToneGenerator == null, tone: " + tone); + return; + } + + // Start the new tone (will stop any playing tone) + mToneGenerator.startTone(tone, durationMs); + } + } + + /** Stop the tone if it is played. */ + private void stopTone() { + // if local tone playback is disabled, just return. + if (!mDTMFToneEnabled) { + return; + } + synchronized (mToneGeneratorLock) { + if (mToneGenerator == null) { + LogUtil.w("DialpadFragment.stopTone", "mToneGenerator == null"); + return; + } + mToneGenerator.stopTone(); + } + } + + /** + * Brings up the "dialpad chooser" UI in place of the usual Dialer elements (the textfield/button + * and the dialpad underneath). + * + *

We show this UI if the user brings up the Dialer while a call is already in progress, since + * there's a good chance we got here accidentally (and the user really wanted the in-call dialpad + * instead). So in this situation we display an intermediate UI that lets the user explicitly + * choose between the in-call dialpad ("Use touch tone keypad") and the regular Dialer ("Add + * call"). (Or, the option "Return to call in progress" just goes back to the in-call UI with no + * dialpad at all.) + * + * @param enabled If true, show the "dialpad chooser" instead of the regular Dialer UI + */ + private void showDialpadChooser(boolean enabled) { + if (getActivity() == null) { + return; + } + // Check if onCreateView() is already called by checking one of View objects. + if (!isLayoutReady()) { + return; + } + + if (enabled) { + LogUtil.i("DialpadFragment.showDialpadChooser", "Showing dialpad chooser!"); + if (mDialpadView != null) { + mDialpadView.setVisibility(View.GONE); + } + + if (mOverflowPopupMenu != null) { + mOverflowPopupMenu.dismiss(); + } + + mFloatingActionButtonController.setVisible(false); + mDialpadChooser.setVisibility(View.VISIBLE); + + // Instantiate the DialpadChooserAdapter and hook it up to the + // ListView. We do this only once. + if (mDialpadChooserAdapter == null) { + mDialpadChooserAdapter = new DialpadChooserAdapter(getActivity()); + } + mDialpadChooser.setAdapter(mDialpadChooserAdapter); + } else { + LogUtil.i("DialpadFragment.showDialpadChooser", "Displaying normal Dialer UI."); + if (mDialpadView != null) { + mDialpadView.setVisibility(View.VISIBLE); + } else { + mDigits.setVisibility(View.VISIBLE); + } + + // mFloatingActionButtonController must also be 'scaled in', in order to be visible after + // 'scaleOut()' hidden method. + if (!mFloatingActionButtonController.isVisible()) { + // Just call 'scaleIn()' method if the mFloatingActionButtonController was not already + // previously visible. + mFloatingActionButtonController.scaleIn(0); + } + mDialpadChooser.setVisibility(View.GONE); + } + } + + /** @return true if we're currently showing the "dialpad chooser" UI. */ + private boolean isDialpadChooserVisible() { + return mDialpadChooser.getVisibility() == View.VISIBLE; + } + + /** Handle clicks from the dialpad chooser. */ + @Override + public void onItemClick(AdapterView parent, View v, int position, long id) { + DialpadChooserAdapter.ChoiceItem item = + (DialpadChooserAdapter.ChoiceItem) parent.getItemAtPosition(position); + int itemId = item.id; + if (itemId == DialpadChooserAdapter.DIALPAD_CHOICE_USE_DTMF_DIALPAD) { + // Fire off an intent to go back to the in-call UI + // with the dialpad visible. + returnToInCallScreen(true); + } else if (itemId == DialpadChooserAdapter.DIALPAD_CHOICE_RETURN_TO_CALL) { + // Fire off an intent to go back to the in-call UI + // (with the dialpad hidden). + returnToInCallScreen(false); + } else if (itemId == DialpadChooserAdapter.DIALPAD_CHOICE_ADD_NEW_CALL) { + // Ok, guess the user really did want to be here (in the + // regular Dialer) after all. Bring back the normal Dialer UI. + showDialpadChooser(false); + } else { + LogUtil.w("DialpadFragment.onItemClick", "Unexpected itemId: " + itemId); + } + } + + /** + * Returns to the in-call UI (where there's presumably a call in progress) in response to the user + * selecting "use touch tone keypad" or "return to call" from the dialpad chooser. + */ + private void returnToInCallScreen(boolean showDialpad) { + TelecomUtil.showInCallScreen(getActivity(), showDialpad); + + // Finally, finish() ourselves so that we don't stay on the + // activity stack. + // Note that we do this whether or not the showCallScreenWithDialpad() + // call above had any effect or not! (That call is a no-op if the + // phone is idle, which can happen if the current call ends while + // the dialpad chooser is up. In this case we can't show the + // InCallScreen, and there's no point staying here in the Dialer, + // so we just take the user back where he came from...) + getActivity().finish(); + } + + /** + * @return true if the phone is "in use", meaning that at least one line is active (ie. off hook + * or ringing or dialing, or on hold). + */ + private boolean isPhoneInUse() { + return getContext() != null && TelecomUtil.isInCall(getContext()); + } + + /** @return true if the phone is a CDMA phone type */ + private boolean phoneIsCdma() { + return getTelephonyManager().getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA; + } + + @Override + public boolean onMenuItemClick(MenuItem item) { + int resId = item.getItemId(); + if (resId == R.id.menu_2s_pause) { + updateDialString(PAUSE); + return true; + } else if (resId == R.id.menu_add_wait) { + updateDialString(WAIT); + return true; + } else if (resId == R.id.menu_call_with_note) { + CallSubjectDialog.start(getActivity(), mDigits.getText().toString()); + hideAndClearDialpad(false); + return true; + } else { + return false; + } + } + + /** + * Updates the dial string (mDigits) after inserting a Pause character (,) or Wait character (;). + */ + private void updateDialString(char newDigit) { + if (newDigit != WAIT && newDigit != PAUSE) { + throw new IllegalArgumentException("Not expected for anything other than PAUSE & WAIT"); + } + + int selectionStart; + int selectionEnd; + + // SpannableStringBuilder editable_text = new SpannableStringBuilder(mDigits.getText()); + int anchor = mDigits.getSelectionStart(); + int point = mDigits.getSelectionEnd(); + + selectionStart = Math.min(anchor, point); + selectionEnd = Math.max(anchor, point); + + if (selectionStart == -1) { + selectionStart = selectionEnd = mDigits.length(); + } + + Editable digits = mDigits.getText(); + + if (canAddDigit(digits, selectionStart, selectionEnd, newDigit)) { + digits.replace(selectionStart, selectionEnd, Character.toString(newDigit)); + + if (selectionStart != selectionEnd) { + // Unselect: back to a regular cursor, just pass the character inserted. + mDigits.setSelection(selectionStart + 1); + } + } + } + + /** Update the enabledness of the "Dial" and "Backspace" buttons if applicable. */ + private void updateDeleteButtonEnabledState() { + if (getActivity() == null) { + return; + } + final boolean digitsNotEmpty = !isDigitsEmpty(); + mDelete.setEnabled(digitsNotEmpty); + } + + /** + * Handle transitions for the menu button depending on the state of the digits edit text. + * Transition out when going from digits to no digits and transition in when the first digit is + * pressed. + * + * @param transitionIn True if transitioning in, False if transitioning out + */ + private void updateMenuOverflowButton(boolean transitionIn) { + mOverflowMenuButton = mDialpadView.getOverflowMenuButton(); + if (transitionIn) { + AnimUtils.fadeIn(mOverflowMenuButton, AnimUtils.DEFAULT_DURATION); + } else { + AnimUtils.fadeOut(mOverflowMenuButton, AnimUtils.DEFAULT_DURATION); + } + } + + /** + * Check if voicemail is enabled/accessible. + * + * @return true if voicemail is enabled and accessible. Note that this can be false "temporarily" + * after the app boot. + */ + private boolean isVoicemailAvailable() { + try { + PhoneAccountHandle defaultUserSelectedAccount = + TelecomUtil.getDefaultOutgoingPhoneAccount(getActivity(), PhoneAccount.SCHEME_VOICEMAIL); + if (defaultUserSelectedAccount == null) { + // In a single-SIM phone, there is no default outgoing phone account selected by + // the user, so just call TelephonyManager#getVoicemailNumber directly. + return !TextUtils.isEmpty(getTelephonyManager().getVoiceMailNumber()); + } else { + return !TextUtils.isEmpty( + TelecomUtil.getVoicemailNumber(getActivity(), defaultUserSelectedAccount)); + } + } catch (SecurityException se) { + // Possibly no READ_PHONE_STATE privilege. + LogUtil.w( + "DialpadFragment.isVoicemailAvailable", + "SecurityException is thrown. Maybe privilege isn't sufficient."); + } + return false; + } + + /** @return true if the widget with the phone number digits is empty. */ + private boolean isDigitsEmpty() { + return mDigits.length() == 0; + } + + /** + * Starts the asyn query to get the last dialed/outgoing number. When the background query + * finishes, mLastNumberDialed is set to the last dialed number or an empty string if none exists + * yet. + */ + private void queryLastOutgoingCall() { + mLastNumberDialed = EMPTY_NUMBER; + if (!PermissionsUtil.hasCallLogReadPermissions(getContext())) { + return; + } + FragmentUtils.getParentUnsafe(this, DialpadListener.class) + .getLastOutgoingCall( + number -> { + // TODO: Filter out emergency numbers if the carrier does not want redial for these. + + // If the fragment has already been detached since the last time we called + // queryLastOutgoingCall in onResume there is no point doing anything here. + if (getActivity() == null) { + return; + } + mLastNumberDialed = number; + updateDeleteButtonEnabledState(); + }); + } + + private Intent newFlashIntent() { + Intent intent = new CallIntentBuilder(EMPTY_NUMBER, CallInitiationType.Type.DIALPAD).build(); + intent.putExtra(EXTRA_SEND_EMPTY_FLASH, true); + return intent; + } + + @Override + public void onHiddenChanged(boolean hidden) { + super.onHiddenChanged(hidden); + if (getActivity() == null || getView() == null) { + return; + } + final DialpadView dialpadView = getView().findViewById(R.id.dialpad_view); + if (!hidden && !isDialpadChooserVisible()) { + if (mAnimate) { + dialpadView.animateShow(); + } + mFloatingActionButtonController.setVisible(false); + mFloatingActionButtonController.scaleIn(mAnimate ? mDialpadSlideInDuration : 0); + FragmentUtils.getParentUnsafe(this, DialpadListener.class).onDialpadShown(); + mDigits.requestFocus(); + } + if (hidden) { + if (mAnimate) { + mFloatingActionButtonController.scaleOut(); + } else { + mFloatingActionButtonController.setVisible(false); + } + } + } + + public boolean getAnimate() { + return mAnimate; + } + + public void setAnimate(boolean value) { + mAnimate = value; + } + + public void setYFraction(float yFraction) { + ((DialpadSlidingRelativeLayout) getView()).setYFraction(yFraction); + } + + public int getDialpadHeight() { + if (mDialpadView == null) { + return 0; + } + return mDialpadView.getHeight(); + } + + public void process_quote_emergency_unquote(String query) { + if (PseudoEmergencyAnimator.PSEUDO_EMERGENCY_NUMBER.equals(query)) { + if (mPseudoEmergencyAnimator == null) { + mPseudoEmergencyAnimator = + new PseudoEmergencyAnimator( + new PseudoEmergencyAnimator.ViewProvider() { + @Override + public View getFab() { + return mFloatingActionButton; + } + + @Override + public Context getContext() { + return DialpadFragment.this.getContext(); + } + }); + } + mPseudoEmergencyAnimator.start(); + } else { + if (mPseudoEmergencyAnimator != null) { + mPseudoEmergencyAnimator.end(); + } + } + } + + public interface OnDialpadQueryChangedListener { + + void onDialpadQueryChanged(String query); + } + + public interface HostInterface { + + /** + * Notifies the parent activity that the space above the dialpad has been tapped with no query + * in the dialpad present. In most situations this will cause the dialpad to be dismissed, + * unless there happens to be content showing. + */ + boolean onDialpadSpacerTouchWithEmptyQuery(); + } + + /** + * LinearLayout with getter and setter methods for the translationY property using floats, for + * animation purposes. + */ + public static class DialpadSlidingRelativeLayout extends RelativeLayout { + + public DialpadSlidingRelativeLayout(Context context) { + super(context); + } + + public DialpadSlidingRelativeLayout(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public DialpadSlidingRelativeLayout(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + } + + @UsedByReflection(value = "dialpad_fragment.xml") + public float getYFraction() { + final int height = getHeight(); + if (height == 0) { + return 0; + } + return getTranslationY() / height; + } + + @UsedByReflection(value = "dialpad_fragment.xml") + public void setYFraction(float yFraction) { + setTranslationY(yFraction * getHeight()); + } + } + + public static class ErrorDialogFragment extends DialogFragment { + + private static final String ARG_TITLE_RES_ID = "argTitleResId"; + private static final String ARG_MESSAGE_RES_ID = "argMessageResId"; + private int mTitleResId; + private int mMessageResId; + + public static ErrorDialogFragment newInstance(int messageResId) { + return newInstance(0, messageResId); + } + + public static ErrorDialogFragment newInstance(int titleResId, int messageResId) { + final ErrorDialogFragment fragment = new ErrorDialogFragment(); + final Bundle args = new Bundle(); + args.putInt(ARG_TITLE_RES_ID, titleResId); + args.putInt(ARG_MESSAGE_RES_ID, messageResId); + fragment.setArguments(args); + return fragment; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + mTitleResId = getArguments().getInt(ARG_TITLE_RES_ID); + mMessageResId = getArguments().getInt(ARG_MESSAGE_RES_ID); + } + + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + if (mTitleResId != 0) { + builder.setTitle(mTitleResId); + } + if (mMessageResId != 0) { + builder.setMessage(mMessageResId); + } + builder.setPositiveButton(android.R.string.ok, (dialog, which) -> dismiss()); + return builder.create(); + } + } + + /** + * Simple list adapter, binding to an icon + text label for each item in the "dialpad chooser" + * list. + */ + private static class DialpadChooserAdapter extends BaseAdapter { + + // IDs for the possible "choices": + static final int DIALPAD_CHOICE_USE_DTMF_DIALPAD = 101; + static final int DIALPAD_CHOICE_RETURN_TO_CALL = 102; + static final int DIALPAD_CHOICE_ADD_NEW_CALL = 103; + private static final int NUM_ITEMS = 3; + private LayoutInflater mInflater; + private ChoiceItem[] mChoiceItems = new ChoiceItem[NUM_ITEMS]; + + DialpadChooserAdapter(Context context) { + // Cache the LayoutInflate to avoid asking for a new one each time. + mInflater = LayoutInflater.from(context); + + // Initialize the possible choices. + // TODO: could this be specified entirely in XML? + + // - "Use touch tone keypad" + mChoiceItems[0] = + new ChoiceItem( + context.getString(R.string.dialer_useDtmfDialpad), + BitmapFactory.decodeResource( + context.getResources(), R.drawable.ic_dialer_fork_tt_keypad), + DIALPAD_CHOICE_USE_DTMF_DIALPAD); + + // - "Return to call in progress" + mChoiceItems[1] = + new ChoiceItem( + context.getString(R.string.dialer_returnToInCallScreen), + BitmapFactory.decodeResource( + context.getResources(), R.drawable.ic_dialer_fork_current_call), + DIALPAD_CHOICE_RETURN_TO_CALL); + + // - "Add call" + mChoiceItems[2] = + new ChoiceItem( + context.getString(R.string.dialer_addAnotherCall), + BitmapFactory.decodeResource( + context.getResources(), R.drawable.ic_dialer_fork_add_call), + DIALPAD_CHOICE_ADD_NEW_CALL); + } + + @Override + public int getCount() { + return NUM_ITEMS; + } + + /** Return the ChoiceItem for a given position. */ + @Override + public Object getItem(int position) { + return mChoiceItems[position]; + } + + /** Return a unique ID for each possible choice. */ + @Override + public long getItemId(int position) { + return position; + } + + /** Make a view for each row. */ + @Override + public View getView(int position, View convertView, ViewGroup parent) { + // When convertView is non-null, we can reuse it (there's no need + // to reinflate it.) + if (convertView == null) { + convertView = mInflater.inflate(R.layout.dialpad_chooser_list_item, null); + } + + TextView text = convertView.findViewById(R.id.text); + text.setText(mChoiceItems[position].text); + + ImageView icon = convertView.findViewById(R.id.icon); + icon.setImageBitmap(mChoiceItems[position].icon); + + return convertView; + } + + // Simple struct for a single "choice" item. + static class ChoiceItem { + + String text; + Bitmap icon; + int id; + + ChoiceItem(String s, Bitmap b, int i) { + text = s; + icon = b; + id = i; + } + } + } + + private class CallStateReceiver extends BroadcastReceiver { + + /** + * Receive call state changes so that we can take down the "dialpad chooser" if the phone + * becomes idle while the chooser UI is visible. + */ + @Override + public void onReceive(Context context, Intent intent) { + String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE); + if ((TextUtils.equals(state, TelephonyManager.EXTRA_STATE_IDLE) + || TextUtils.equals(state, TelephonyManager.EXTRA_STATE_OFFHOOK)) + && isDialpadChooserVisible()) { + // Note there's a race condition in the UI here: the + // dialpad chooser could conceivably disappear (on its + // own) at the exact moment the user was trying to select + // one of the choices, which would be confusing. (But at + // least that's better than leaving the dialpad chooser + // onscreen, but useless...) + showDialpadChooser(false); + } + } + } + + /** Listener for dialpad's parent. */ + public interface DialpadListener { + void getLastOutgoingCall(LastOutgoingCallCallback callback); + + void onDialpadShown(); + + void hideDialpadFragment(boolean animate, boolean value); + } + + /** Callback for async lookup of the last number dialed. */ + public interface LastOutgoingCallCallback { + + void lastOutgoingCall(String number); + } + + /** + * Input: the ISO 3166-1 two letters country code of the country the user is in + * + *

Output: PhoneNumberFormattingTextWatcher. Note: It is unusual to return a non-data value + * from a worker, but it is a limitation in libphonenumber API that the watcher cannot be + * initialized on the main thread. + */ + private static class InitPhoneNumberFormattingTextWatcherWorker + implements Worker { + + @Nullable + @Override + public PhoneNumberFormattingTextWatcher doInBackground(@Nullable String countryCode) { + return new PhoneNumberFormattingTextWatcher(countryCode); + } + } +} diff --git a/java/com/android/dialer/dialpadview/DialpadView.java b/java/com/android/dialer/dialpadview/DialpadView.java index 4a9b500b7..0c53273a4 100644 --- a/java/com/android/dialer/dialpadview/DialpadView.java +++ b/java/com/android/dialer/dialpadview/DialpadView.java @@ -29,7 +29,6 @@ import android.text.Spannable; import android.text.TextUtils; import android.text.style.TtsSpan; import android.util.AttributeSet; -import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; @@ -40,6 +39,8 @@ import android.widget.ImageButton; import android.widget.LinearLayout; import android.widget.TextView; import com.android.dialer.animation.AnimUtils; +import com.android.dialer.common.LogUtil; +import com.android.dialer.compat.CompatUtils; import java.text.DecimalFormat; import java.text.NumberFormat; import java.util.Locale; @@ -153,7 +154,7 @@ public class DialpadView extends LinearLayout { // We translate dialpad numbers only for "fa" and not any other locale // ("ar" anybody ?). if ("fa".equals(currentLocale.getLanguage())) { - nf = DecimalFormat.getInstance(resources.getConfiguration().locale); + nf = DecimalFormat.getInstance(CompatUtils.getLocale(getContext())); } else { nf = DecimalFormat.getInstance(Locale.ENGLISH); } @@ -395,7 +396,7 @@ public class DialpadView extends LinearLayout { } } - Log.wtf(TAG, "Attempted to get animation delay for invalid key button id."); + LogUtil.e(TAG, "Attempted to get animation delay for invalid key button id."); return 0; } @@ -458,7 +459,7 @@ public class DialpadView extends LinearLayout { } } - Log.wtf(TAG, "Attempted to get animation duration for invalid key button id."); + LogUtil.e(TAG, "Attempted to get animation duration for invalid key button id."); return 0; } } diff --git a/java/com/android/dialer/dialpadview/PseudoEmergencyAnimator.java b/java/com/android/dialer/dialpadview/PseudoEmergencyAnimator.java new file mode 100644 index 000000000..16bdd24c1 --- /dev/null +++ b/java/com/android/dialer/dialpadview/PseudoEmergencyAnimator.java @@ -0,0 +1,142 @@ +/* + * 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.dialpadview; + +import android.animation.Animator; +import android.animation.Animator.AnimatorListener; +import android.animation.ArgbEvaluator; +import android.animation.ValueAnimator; +import android.content.Context; +import android.graphics.Color; +import android.graphics.ColorFilter; +import android.graphics.LightingColorFilter; +import android.os.Handler; +import android.os.Vibrator; +import android.view.View; + +/** Animates the dial button on "emergency" phone numbers. */ +public class PseudoEmergencyAnimator { + + static final String PSEUDO_EMERGENCY_NUMBER = "01189998819991197253"; + private static final int VIBRATE_LENGTH_MILLIS = 200; + private static final int ITERATION_LENGTH_MILLIS = 1000; + private static final int ANIMATION_ITERATION_COUNT = 6; + private ViewProvider mViewProvider; + private ValueAnimator mPseudoEmergencyColorAnimator; + + PseudoEmergencyAnimator(ViewProvider viewProvider) { + mViewProvider = viewProvider; + } + + public void destroy() { + end(); + mViewProvider = null; + } + + public void start() { + if (mPseudoEmergencyColorAnimator == null) { + Integer colorFrom = Color.BLUE; + Integer colorTo = Color.RED; + mPseudoEmergencyColorAnimator = + ValueAnimator.ofObject(new ArgbEvaluator(), colorFrom, colorTo); + + mPseudoEmergencyColorAnimator.addUpdateListener( + animator -> { + try { + int color = (int) animator.getAnimatedValue(); + ColorFilter colorFilter = new LightingColorFilter(Color.BLACK, color); + + if (mViewProvider.getFab() != null) { + mViewProvider.getFab().getBackground().setColorFilter(colorFilter); + } + } catch (Exception e) { + animator.cancel(); + } + }); + + mPseudoEmergencyColorAnimator.addListener( + new AnimatorListener() { + @Override + public void onAnimationCancel(Animator animation) {} + + @Override + public void onAnimationRepeat(Animator animation) { + try { + vibrate(VIBRATE_LENGTH_MILLIS); + } catch (Exception e) { + animation.cancel(); + } + } + + @Override + public void onAnimationStart(Animator animation) {} + + @Override + public void onAnimationEnd(Animator animation) { + try { + if (mViewProvider.getFab() != null) { + mViewProvider.getFab().getBackground().clearColorFilter(); + } + + new Handler() + .postDelayed( + () -> { + try { + vibrate(VIBRATE_LENGTH_MILLIS); + } catch (Exception e) { + // ignored + } + }, + ITERATION_LENGTH_MILLIS); + } catch (Exception e) { + animation.cancel(); + } + } + }); + + mPseudoEmergencyColorAnimator.setDuration(VIBRATE_LENGTH_MILLIS); + mPseudoEmergencyColorAnimator.setRepeatMode(ValueAnimator.REVERSE); + mPseudoEmergencyColorAnimator.setRepeatCount(ANIMATION_ITERATION_COUNT); + } + if (!mPseudoEmergencyColorAnimator.isStarted()) { + mPseudoEmergencyColorAnimator.start(); + } + } + + public void end() { + if (mPseudoEmergencyColorAnimator != null && mPseudoEmergencyColorAnimator.isStarted()) { + mPseudoEmergencyColorAnimator.end(); + } + } + + private void vibrate(long milliseconds) { + Context context = mViewProvider.getContext(); + if (context != null) { + Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE); + if (vibrator != null) { + vibrator.vibrate(milliseconds); + } + } + } + + interface ViewProvider { + + View getFab(); + + Context getContext(); + } +} diff --git a/java/com/android/dialer/dialpadview/SmartDialCursorLoader.java b/java/com/android/dialer/dialpadview/SmartDialCursorLoader.java new file mode 100644 index 000000000..271535fce --- /dev/null +++ b/java/com/android/dialer/dialpadview/SmartDialCursorLoader.java @@ -0,0 +1,183 @@ +/* + * 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.dialpadview; + +import android.content.AsyncTaskLoader; +import android.content.Context; +import android.database.Cursor; +import android.database.MatrixCursor; +import com.android.contacts.common.list.PhoneNumberListAdapter.PhoneQuery; +import com.android.dialer.common.LogUtil; +import com.android.dialer.database.Database; +import com.android.dialer.database.DialerDatabaseHelper; +import com.android.dialer.database.DialerDatabaseHelper.ContactNumber; +import com.android.dialer.smartdial.SmartDialNameMatcher; +import com.android.dialer.smartdial.SmartDialPrefix; +import com.android.dialer.util.PermissionsUtil; +import java.util.ArrayList; + +/** Implements a Loader class to asynchronously load SmartDial search results. */ +public class SmartDialCursorLoader extends AsyncTaskLoader { + + private static final String TAG = "SmartDialCursorLoader"; + private static final boolean DEBUG = false; + + private final Context mContext; + + private Cursor mCursor; + + private String mQuery; + private SmartDialNameMatcher mNameMatcher; + + private boolean mShowEmptyListForNullQuery = true; + + public SmartDialCursorLoader(Context context) { + super(context); + mContext = context; + } + + /** + * Configures the query string to be used to find SmartDial matches. + * + * @param query The query string user typed. + */ + public void configureQuery(String query) { + if (DEBUG) { + LogUtil.v(TAG, "Configure new query to be " + query); + } + mQuery = SmartDialNameMatcher.normalizeNumber(query, SmartDialPrefix.getMap()); + + /** Constructs a name matcher object for matching names. */ + mNameMatcher = new SmartDialNameMatcher(mQuery, SmartDialPrefix.getMap()); + mNameMatcher.setShouldMatchEmptyQuery(!mShowEmptyListForNullQuery); + } + + /** + * Queries the SmartDial database and loads results in background. + * + * @return Cursor of contacts that matches the SmartDial query. + */ + @Override + public Cursor loadInBackground() { + if (DEBUG) { + LogUtil.v(TAG, "Load in background " + mQuery); + } + + if (!PermissionsUtil.hasContactsReadPermissions(mContext)) { + return new MatrixCursor(PhoneQuery.PROJECTION_PRIMARY); + } + + /** Loads results from the database helper. */ + final DialerDatabaseHelper dialerDatabaseHelper = + Database.get(mContext).getDatabaseHelper(mContext); + final ArrayList allMatches = + dialerDatabaseHelper.getLooseMatches(mQuery, mNameMatcher); + + if (DEBUG) { + LogUtil.v(TAG, "Loaded matches " + allMatches.size()); + } + + /** Constructs a cursor for the returned array of results. */ + final MatrixCursor cursor = new MatrixCursor(PhoneQuery.PROJECTION_PRIMARY); + Object[] row = new Object[PhoneQuery.PROJECTION_PRIMARY.length]; + for (ContactNumber contact : allMatches) { + row[PhoneQuery.PHONE_ID] = contact.dataId; + row[PhoneQuery.PHONE_NUMBER] = contact.phoneNumber; + row[PhoneQuery.CONTACT_ID] = contact.id; + row[PhoneQuery.LOOKUP_KEY] = contact.lookupKey; + row[PhoneQuery.PHOTO_ID] = contact.photoId; + row[PhoneQuery.DISPLAY_NAME] = contact.displayName; + row[PhoneQuery.CARRIER_PRESENCE] = contact.carrierPresence; + cursor.addRow(row); + } + return cursor; + } + + @Override + public void deliverResult(Cursor cursor) { + if (isReset()) { + /** The Loader has been reset; ignore the result and invalidate the data. */ + releaseResources(cursor); + return; + } + + /** Hold a reference to the old data so it doesn't get garbage collected. */ + Cursor oldCursor = mCursor; + mCursor = cursor; + + if (isStarted()) { + /** If the Loader is in a started state, deliver the results to the client. */ + super.deliverResult(cursor); + } + + /** Invalidate the old data as we don't need it any more. */ + if (oldCursor != null && oldCursor != cursor) { + releaseResources(oldCursor); + } + } + + @Override + protected void onStartLoading() { + if (mCursor != null) { + /** Deliver any previously loaded data immediately. */ + deliverResult(mCursor); + } + if (mCursor == null) { + /** Force loads every time as our results change with queries. */ + forceLoad(); + } + } + + @Override + protected void onStopLoading() { + /** The Loader is in a stopped state, so we should attempt to cancel the current load. */ + cancelLoad(); + } + + @Override + protected void onReset() { + /** Ensure the loader has been stopped. */ + onStopLoading(); + + /** Release all previously saved query results. */ + if (mCursor != null) { + releaseResources(mCursor); + mCursor = null; + } + } + + @Override + public void onCanceled(Cursor cursor) { + super.onCanceled(cursor); + + /** The load has been canceled, so we should release the resources associated with 'data'. */ + releaseResources(cursor); + } + + private void releaseResources(Cursor cursor) { + if (cursor != null) { + cursor.close(); + } + } + + public void setShowEmptyListForNullQuery(boolean show) { + mShowEmptyListForNullQuery = show; + if (mNameMatcher != null) { + mNameMatcher.setShouldMatchEmptyQuery(!show); + } + } +} diff --git a/java/com/android/dialer/dialpadview/SpecialCharSequenceMgr.java b/java/com/android/dialer/dialpadview/SpecialCharSequenceMgr.java new file mode 100644 index 000000000..7ff0d084a --- /dev/null +++ b/java/com/android/dialer/dialpadview/SpecialCharSequenceMgr.java @@ -0,0 +1,497 @@ +/* + * Copyright (C) 2006 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.dialpadview; + +import android.Manifest; +import android.app.Activity; +import android.app.AlertDialog; +import android.app.DialogFragment; +import android.app.KeyguardManager; +import android.app.ProgressDialog; +import android.content.ActivityNotFoundException; +import android.content.ContentResolver; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.database.Cursor; +import android.net.Uri; +import android.provider.Settings; +import android.support.annotation.Nullable; +import android.telecom.PhoneAccount; +import android.telecom.PhoneAccountHandle; +import android.telephony.PhoneNumberUtils; +import android.telephony.TelephonyManager; +import android.text.TextUtils; +import android.view.WindowManager; +import android.widget.EditText; +import android.widget.Toast; +import com.android.common.io.MoreCloseables; +import com.android.contacts.common.database.NoNullCursorAsyncQueryHandler; +import com.android.contacts.common.util.ContactDisplayUtils; +import com.android.contacts.common.widget.SelectPhoneAccountDialogFragment; +import com.android.contacts.common.widget.SelectPhoneAccountDialogFragment.SelectPhoneAccountListener; +import com.android.dialer.calllogutils.PhoneAccountUtils; +import com.android.dialer.common.Assert; +import com.android.dialer.common.LogUtil; +import com.android.dialer.compat.telephony.TelephonyManagerCompat; +import com.android.dialer.oem.MotorolaUtils; +import com.android.dialer.telecom.TelecomUtil; +import com.android.dialer.util.PermissionsUtil; +import java.util.ArrayList; +import java.util.List; + +/** + * Helper class to listen for some magic character sequences that are handled specially by the + * dialer. + * + *

Note the Phone app also handles these sequences too (in a couple of relatively obscure places + * in the UI), so there's a separate version of this class under apps/Phone. + * + *

TODO: there's lots of duplicated code between this class and the corresponding class under + * apps/Phone. Let's figure out a way to unify these two classes (in the framework? in a common + * shared library?) + */ +public class SpecialCharSequenceMgr { + + private static final String TAG = "SpecialCharSequenceMgr"; + + private static final String TAG_SELECT_ACCT_FRAGMENT = "tag_select_acct_fragment"; + + private static final String MMI_IMEI_DISPLAY = "*#06#"; + private static final String MMI_REGULATORY_INFO_DISPLAY = "*#07#"; + /** ***** This code is used to handle SIM Contact queries ***** */ + private static final String ADN_PHONE_NUMBER_COLUMN_NAME = "number"; + + private static final String ADN_NAME_COLUMN_NAME = "name"; + private static final int ADN_QUERY_TOKEN = -1; + /** + * Remembers the previous {@link QueryHandler} and cancel the operation when needed, to prevent + * possible crash. + * + *

QueryHandler may call {@link ProgressDialog#dismiss()} when the screen is already gone, + * which will cause the app crash. This variable enables the class to prevent the crash on {@link + * #cleanup()}. + * + *

TODO: Remove this and replace it (and {@link #cleanup()}) with better implementation. One + * complication is that we have SpecialCharSequenceMgr in Phone package too, which has *slightly* + * different implementation. Note that Phone package doesn't have this problem, so the class on + * Phone side doesn't have this functionality. Fundamental fix would be to have one shared + * implementation and resolve this corner case more gracefully. + */ + private static QueryHandler sPreviousAdnQueryHandler; + + /** This class is never instantiated. */ + private SpecialCharSequenceMgr() {} + + public static boolean handleChars(Context context, String input, EditText textField) { + // get rid of the separators so that the string gets parsed correctly + String dialString = PhoneNumberUtils.stripSeparators(input); + + if (handleDeviceIdDisplay(context, dialString) + || handleRegulatoryInfoDisplay(context, dialString) + || handlePinEntry(context, dialString) + || handleAdnEntry(context, dialString, textField) + || handleSecretCode(context, dialString)) { + return true; + } + + if (MotorolaUtils.handleSpecialCharSequence(context, input)) { + return true; + } + + return false; + } + + /** + * Cleanup everything around this class. Must be run inside the main thread. + * + *

This should be called when the screen becomes background. + */ + public static void cleanup() { + Assert.isMainThread(); + + if (sPreviousAdnQueryHandler != null) { + sPreviousAdnQueryHandler.cancel(); + sPreviousAdnQueryHandler = null; + } + } + + /** + * Handles secret codes to launch arbitrary activities in the form of *#*##*#*. + * + * @param context the context to use + * @param input the text to check for a secret code in + * @return true if a secret code was encountered and handled + */ + static boolean handleSecretCode(Context context, String input) { + // Secret codes are accessed by dialing *#*##*#* + + int len = input.length(); + if (len <= 8 || !input.startsWith("*#*#") || !input.endsWith("#*#*")) { + return false; + } + String secretCode = input.substring(4, len - 4); + TelephonyManagerCompat.handleSecretCode(context, secretCode); + return true; + } + + /** + * Handle ADN requests by filling in the SIM contact number into the requested EditText. + * + *

This code works alongside the Asynchronous query handler {@link QueryHandler} and query + * cancel handler implemented in {@link SimContactQueryCookie}. + */ + static boolean handleAdnEntry(Context context, String input, EditText textField) { + /* ADN entries are of the form "N(N)(N)#" */ + TelephonyManager telephonyManager = + (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); + if (telephonyManager == null + || telephonyManager.getPhoneType() != TelephonyManager.PHONE_TYPE_GSM) { + return false; + } + + // if the phone is keyguard-restricted, then just ignore this + // input. We want to make sure that sim card contacts are NOT + // exposed unless the phone is unlocked, and this code can be + // accessed from the emergency dialer. + KeyguardManager keyguardManager = + (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE); + if (keyguardManager.inKeyguardRestrictedInputMode()) { + return false; + } + + int len = input.length(); + if ((len > 1) && (len < 5) && (input.endsWith("#"))) { + try { + // get the ordinal number of the sim contact + final int index = Integer.parseInt(input.substring(0, len - 1)); + + // The original code that navigated to a SIM Contacts list view did not + // highlight the requested contact correctly, a requirement for PTCRB + // certification. This behaviour is consistent with the UI paradigm + // for touch-enabled lists, so it does not make sense to try to work + // around it. Instead we fill in the the requested phone number into + // the dialer text field. + + // create the async query handler + final QueryHandler handler = new QueryHandler(context.getContentResolver()); + + // create the cookie object + final SimContactQueryCookie sc = + new SimContactQueryCookie(index - 1, handler, ADN_QUERY_TOKEN); + + // setup the cookie fields + sc.contactNum = index - 1; + sc.setTextField(textField); + + // create the progress dialog + sc.progressDialog = new ProgressDialog(context); + sc.progressDialog.setTitle(R.string.simContacts_title); + sc.progressDialog.setMessage(context.getText(R.string.simContacts_emptyLoading)); + sc.progressDialog.setIndeterminate(true); + sc.progressDialog.setCancelable(true); + sc.progressDialog.setOnCancelListener(sc); + sc.progressDialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND); + + List subscriptionAccountHandles = + PhoneAccountUtils.getSubscriptionPhoneAccounts(context); + Context applicationContext = context.getApplicationContext(); + boolean hasUserSelectedDefault = + subscriptionAccountHandles.contains( + TelecomUtil.getDefaultOutgoingPhoneAccount( + applicationContext, PhoneAccount.SCHEME_TEL)); + + if (subscriptionAccountHandles.size() <= 1 || hasUserSelectedDefault) { + Uri uri = TelecomUtil.getAdnUriForPhoneAccount(applicationContext, null); + handleAdnQuery(handler, sc, uri); + } else { + SelectPhoneAccountListener callback = + new HandleAdnEntryAccountSelectedCallback(applicationContext, handler, sc); + + DialogFragment dialogFragment = + SelectPhoneAccountDialogFragment.newInstance( + subscriptionAccountHandles, callback, null); + dialogFragment.show(((Activity) context).getFragmentManager(), TAG_SELECT_ACCT_FRAGMENT); + } + + return true; + } catch (NumberFormatException ex) { + // Ignore + } + } + return false; + } + + private static void handleAdnQuery(QueryHandler handler, SimContactQueryCookie cookie, Uri uri) { + if (handler == null || cookie == null || uri == null) { + LogUtil.w("SpecialCharSequenceMgr.handleAdnQuery", "queryAdn parameters incorrect"); + return; + } + + // display the progress dialog + cookie.progressDialog.show(); + + // run the query. + handler.startQuery( + ADN_QUERY_TOKEN, + cookie, + uri, + new String[] {ADN_PHONE_NUMBER_COLUMN_NAME}, + null, + null, + null); + + if (sPreviousAdnQueryHandler != null) { + // It is harmless to call cancel() even after the handler's gone. + sPreviousAdnQueryHandler.cancel(); + } + sPreviousAdnQueryHandler = handler; + } + + static boolean handlePinEntry(final Context context, final String input) { + if ((input.startsWith("**04") || input.startsWith("**05")) && input.endsWith("#")) { + List subscriptionAccountHandles = + PhoneAccountUtils.getSubscriptionPhoneAccounts(context); + boolean hasUserSelectedDefault = + subscriptionAccountHandles.contains( + TelecomUtil.getDefaultOutgoingPhoneAccount(context, PhoneAccount.SCHEME_TEL)); + + if (subscriptionAccountHandles.size() <= 1 || hasUserSelectedDefault) { + // Don't bring up the dialog for single-SIM or if the default outgoing account is + // a subscription account. + return TelecomUtil.handleMmi(context, input, null); + } else { + SelectPhoneAccountListener listener = new HandleMmiAccountSelectedCallback(context, input); + + DialogFragment dialogFragment = + SelectPhoneAccountDialogFragment.newInstance( + subscriptionAccountHandles, listener, null); + dialogFragment.show(((Activity) context).getFragmentManager(), TAG_SELECT_ACCT_FRAGMENT); + } + return true; + } + return false; + } + + // TODO: Use TelephonyCapabilities.getDeviceIdLabel() to get the device id label instead of a + // hard-coded string. + static boolean handleDeviceIdDisplay(Context context, String input) { + if (!PermissionsUtil.hasPermission(context, Manifest.permission.READ_PHONE_STATE)) { + return false; + } + TelephonyManager telephonyManager = + (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); + + if (telephonyManager != null && input.equals(MMI_IMEI_DISPLAY)) { + int labelResId = + (telephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_GSM) + ? R.string.imei + : R.string.meid; + + List deviceIds = new ArrayList(); + if (TelephonyManagerCompat.getPhoneCount(telephonyManager) > 1) { + for (int slot = 0; slot < telephonyManager.getPhoneCount(); slot++) { + String deviceId = telephonyManager.getDeviceId(slot); + if (!TextUtils.isEmpty(deviceId)) { + deviceIds.add(deviceId); + } + } + } else { + deviceIds.add(telephonyManager.getDeviceId()); + } + + new AlertDialog.Builder(context) + .setTitle(labelResId) + .setItems(deviceIds.toArray(new String[deviceIds.size()]), null) + .setPositiveButton(android.R.string.ok, null) + .setCancelable(false) + .show(); + return true; + } + return false; + } + + private static boolean handleRegulatoryInfoDisplay(Context context, String input) { + if (input.equals(MMI_REGULATORY_INFO_DISPLAY)) { + LogUtil.i( + "SpecialCharSequenceMgr.handleRegulatoryInfoDisplay", "sending intent to settings app"); + Intent showRegInfoIntent = new Intent(Settings.ACTION_SHOW_REGULATORY_INFO); + try { + context.startActivity(showRegInfoIntent); + } catch (ActivityNotFoundException e) { + LogUtil.e( + "SpecialCharSequenceMgr.handleRegulatoryInfoDisplay", "startActivity() failed: ", e); + } + return true; + } + return false; + } + + public static class HandleAdnEntryAccountSelectedCallback extends SelectPhoneAccountListener { + + private final Context mContext; + private final QueryHandler mQueryHandler; + private final SimContactQueryCookie mCookie; + + public HandleAdnEntryAccountSelectedCallback( + Context context, QueryHandler queryHandler, SimContactQueryCookie cookie) { + mContext = context; + mQueryHandler = queryHandler; + mCookie = cookie; + } + + @Override + public void onPhoneAccountSelected( + PhoneAccountHandle selectedAccountHandle, boolean setDefault, @Nullable String callId) { + Uri uri = TelecomUtil.getAdnUriForPhoneAccount(mContext, selectedAccountHandle); + handleAdnQuery(mQueryHandler, mCookie, uri); + // TODO: Show error dialog if result isn't valid. + } + } + + public static class HandleMmiAccountSelectedCallback extends SelectPhoneAccountListener { + + private final Context mContext; + private final String mInput; + + public HandleMmiAccountSelectedCallback(Context context, String input) { + mContext = context.getApplicationContext(); + mInput = input; + } + + @Override + public void onPhoneAccountSelected( + PhoneAccountHandle selectedAccountHandle, boolean setDefault, @Nullable String callId) { + TelecomUtil.handleMmi(mContext, mInput, selectedAccountHandle); + } + } + + /** + * Cookie object that contains everything we need to communicate to the handler's onQuery + * Complete, as well as what we need in order to cancel the query (if requested). + * + *

Note, access to the textField field is going to be synchronized, because the user can + * request a cancel at any time through the UI. + */ + private static class SimContactQueryCookie implements DialogInterface.OnCancelListener { + + public ProgressDialog progressDialog; + public int contactNum; + + // Used to identify the query request. + private int mToken; + private QueryHandler mHandler; + + // The text field we're going to update + private EditText textField; + + public SimContactQueryCookie(int number, QueryHandler handler, int token) { + contactNum = number; + mHandler = handler; + mToken = token; + } + + /** Synchronized getter for the EditText. */ + public synchronized EditText getTextField() { + return textField; + } + + /** Synchronized setter for the EditText. */ + public synchronized void setTextField(EditText text) { + textField = text; + } + + /** + * Cancel the ADN query by stopping the operation and signaling the cookie that a cancel request + * is made. + */ + @Override + public synchronized void onCancel(DialogInterface dialog) { + // close the progress dialog + if (progressDialog != null) { + progressDialog.dismiss(); + } + + // setting the textfield to null ensures that the UI does NOT get + // updated. + textField = null; + + // Cancel the operation if possible. + mHandler.cancelOperation(mToken); + } + } + + /** + * Asynchronous query handler that services requests to look up ADNs + * + *

Queries originate from {@link #handleAdnEntry}. + */ + private static class QueryHandler extends NoNullCursorAsyncQueryHandler { + + private boolean mCanceled; + + public QueryHandler(ContentResolver cr) { + super(cr); + } + + /** Override basic onQueryComplete to fill in the textfield when we're handed the ADN cursor. */ + @Override + protected void onNotNullableQueryComplete(int token, Object cookie, Cursor c) { + try { + sPreviousAdnQueryHandler = null; + if (mCanceled) { + return; + } + + SimContactQueryCookie sc = (SimContactQueryCookie) cookie; + + // close the progress dialog. + sc.progressDialog.dismiss(); + + // get the EditText to update or see if the request was cancelled. + EditText text = sc.getTextField(); + + // if the TextView is valid, and the cursor is valid and positionable on the + // Nth number, then we update the text field and display a toast indicating the + // caller name. + if ((c != null) && (text != null) && (c.moveToPosition(sc.contactNum))) { + String name = c.getString(c.getColumnIndexOrThrow(ADN_NAME_COLUMN_NAME)); + String number = c.getString(c.getColumnIndexOrThrow(ADN_PHONE_NUMBER_COLUMN_NAME)); + + // fill the text in. + text.getText().replace(0, 0, number); + + // display the name as a toast + Context context = sc.progressDialog.getContext(); + CharSequence msg = + ContactDisplayUtils.getTtsSpannedPhoneNumber( + context.getResources(), R.string.menu_callNumber, name); + Toast.makeText(context, msg, Toast.LENGTH_SHORT).show(); + } + } finally { + MoreCloseables.closeQuietly(c); + } + } + + public void cancel() { + mCanceled = true; + // Ask AsyncQueryHandler to cancel the whole request. This will fail when the query is + // already started. + cancelOperation(ADN_QUERY_TOKEN); + } + } +} diff --git a/java/com/android/dialer/dialpadview/UnicodeDialerKeyListener.java b/java/com/android/dialer/dialpadview/UnicodeDialerKeyListener.java new file mode 100644 index 000000000..e9201c0c2 --- /dev/null +++ b/java/com/android/dialer/dialpadview/UnicodeDialerKeyListener.java @@ -0,0 +1,56 @@ +/* + * 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.dialpadview; + +import android.telephony.PhoneNumberUtils; +import android.text.Spanned; +import android.text.method.DialerKeyListener; + +/** + * {@link DialerKeyListener} with Unicode support. Converts any Unicode(e.g. Arabic) characters that + * represent digits into digits before filtering the results so that we can support pasted digits + * from Unicode languages. + */ +public class UnicodeDialerKeyListener extends DialerKeyListener { + + public static final UnicodeDialerKeyListener INSTANCE = new UnicodeDialerKeyListener(); + + @Override + public CharSequence filter( + CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { + final String converted = + PhoneNumberUtils.convertKeypadLettersToDigits( + PhoneNumberUtils.replaceUnicodeDigits(source.toString())); + // PhoneNumberUtils.replaceUnicodeDigits performs a character for character replacement, + // so we can assume that start and end positions should remain unchanged. + CharSequence result = super.filter(converted, start, end, dest, dstart, dend); + if (result == null) { + if (source.equals(converted)) { + // There was no conversion or filtering performed. Just return null according to + // the behavior of DialerKeyListener. + return null; + } else { + // filter returns null if the charsequence is to be returned unchanged/unfiltered. + // But in this case we do want to return a modified character string (even if + // none of the characters in the modified string are filtered). So if + // result == null we return the unfiltered but converted numeric string instead. + return converted.subSequence(start, end); + } + } + return result; + } +} diff --git a/java/com/android/dialer/dialpadview/res/drawable-hdpi/ic_close_black_24dp.png b/java/com/android/dialer/dialpadview/res/drawable-hdpi/ic_close_black_24dp.png deleted file mode 100644 index 1a9cd75a0..000000000 Binary files a/java/com/android/dialer/dialpadview/res/drawable-hdpi/ic_close_black_24dp.png and /dev/null differ diff --git a/java/com/android/dialer/dialpadview/res/drawable-hdpi/ic_dialer_fork_add_call.png b/java/com/android/dialer/dialpadview/res/drawable-hdpi/ic_dialer_fork_add_call.png new file mode 100755 index 000000000..4e0d5649e Binary files /dev/null and b/java/com/android/dialer/dialpadview/res/drawable-hdpi/ic_dialer_fork_add_call.png differ diff --git a/java/com/android/dialer/dialpadview/res/drawable-hdpi/ic_dialer_fork_current_call.png b/java/com/android/dialer/dialpadview/res/drawable-hdpi/ic_dialer_fork_current_call.png new file mode 100755 index 000000000..2cf41d598 Binary files /dev/null and b/java/com/android/dialer/dialpadview/res/drawable-hdpi/ic_dialer_fork_current_call.png differ diff --git a/java/com/android/dialer/dialpadview/res/drawable-hdpi/ic_dialer_fork_tt_keypad.png b/java/com/android/dialer/dialpadview/res/drawable-hdpi/ic_dialer_fork_tt_keypad.png new file mode 100755 index 000000000..043685fd9 Binary files /dev/null and b/java/com/android/dialer/dialpadview/res/drawable-hdpi/ic_dialer_fork_tt_keypad.png differ diff --git a/java/com/android/dialer/dialpadview/res/drawable-hdpi/ic_dialpad_delete.png b/java/com/android/dialer/dialpadview/res/drawable-hdpi/ic_dialpad_delete.png deleted file mode 100644 index e588d90e9..000000000 Binary files a/java/com/android/dialer/dialpadview/res/drawable-hdpi/ic_dialpad_delete.png and /dev/null differ diff --git a/java/com/android/dialer/dialpadview/res/drawable-hdpi/ic_dialpad_voicemail.png b/java/com/android/dialer/dialpadview/res/drawable-hdpi/ic_dialpad_voicemail.png deleted file mode 100644 index 4706112d6..000000000 Binary files a/java/com/android/dialer/dialpadview/res/drawable-hdpi/ic_dialpad_voicemail.png and /dev/null differ diff --git a/java/com/android/dialer/dialpadview/res/drawable-hdpi/ic_overflow_menu.png b/java/com/android/dialer/dialpadview/res/drawable-hdpi/ic_overflow_menu.png deleted file mode 100644 index 262e9df91..000000000 Binary files a/java/com/android/dialer/dialpadview/res/drawable-hdpi/ic_overflow_menu.png and /dev/null differ diff --git a/java/com/android/dialer/dialpadview/res/drawable-mdpi/ic_dialer_fork_add_call.png b/java/com/android/dialer/dialpadview/res/drawable-mdpi/ic_dialer_fork_add_call.png new file mode 100644 index 000000000..56ac2a33a Binary files /dev/null and b/java/com/android/dialer/dialpadview/res/drawable-mdpi/ic_dialer_fork_add_call.png differ diff --git a/java/com/android/dialer/dialpadview/res/drawable-mdpi/ic_dialer_fork_current_call.png b/java/com/android/dialer/dialpadview/res/drawable-mdpi/ic_dialer_fork_current_call.png new file mode 100644 index 000000000..16a44a078 Binary files /dev/null and b/java/com/android/dialer/dialpadview/res/drawable-mdpi/ic_dialer_fork_current_call.png differ diff --git a/java/com/android/dialer/dialpadview/res/drawable-mdpi/ic_dialer_fork_tt_keypad.png b/java/com/android/dialer/dialpadview/res/drawable-mdpi/ic_dialer_fork_tt_keypad.png new file mode 100644 index 000000000..66df69eac Binary files /dev/null and b/java/com/android/dialer/dialpadview/res/drawable-mdpi/ic_dialer_fork_tt_keypad.png differ diff --git a/java/com/android/dialer/dialpadview/res/drawable-xhdpi/ic_dialer_fork_add_call.png b/java/com/android/dialer/dialpadview/res/drawable-xhdpi/ic_dialer_fork_add_call.png new file mode 100644 index 000000000..aff140fcd Binary files /dev/null and b/java/com/android/dialer/dialpadview/res/drawable-xhdpi/ic_dialer_fork_add_call.png differ diff --git a/java/com/android/dialer/dialpadview/res/drawable-xhdpi/ic_dialer_fork_current_call.png b/java/com/android/dialer/dialpadview/res/drawable-xhdpi/ic_dialer_fork_current_call.png new file mode 100644 index 000000000..8975727e0 Binary files /dev/null and b/java/com/android/dialer/dialpadview/res/drawable-xhdpi/ic_dialer_fork_current_call.png differ diff --git a/java/com/android/dialer/dialpadview/res/drawable-xhdpi/ic_dialer_fork_tt_keypad.png b/java/com/android/dialer/dialpadview/res/drawable-xhdpi/ic_dialer_fork_tt_keypad.png new file mode 100644 index 000000000..4d48ea9ea Binary files /dev/null and b/java/com/android/dialer/dialpadview/res/drawable-xhdpi/ic_dialer_fork_tt_keypad.png differ diff --git a/java/com/android/dialer/dialpadview/res/drawable-xxhdpi/ic_dialer_fork_add_call.png b/java/com/android/dialer/dialpadview/res/drawable-xxhdpi/ic_dialer_fork_add_call.png new file mode 100644 index 000000000..1657da4e2 Binary files /dev/null and b/java/com/android/dialer/dialpadview/res/drawable-xxhdpi/ic_dialer_fork_add_call.png differ diff --git a/java/com/android/dialer/dialpadview/res/drawable-xxhdpi/ic_dialer_fork_current_call.png b/java/com/android/dialer/dialpadview/res/drawable-xxhdpi/ic_dialer_fork_current_call.png new file mode 100644 index 000000000..f25cce695 Binary files /dev/null and b/java/com/android/dialer/dialpadview/res/drawable-xxhdpi/ic_dialer_fork_current_call.png differ diff --git a/java/com/android/dialer/dialpadview/res/drawable-xxhdpi/ic_dialer_fork_tt_keypad.png b/java/com/android/dialer/dialpadview/res/drawable-xxhdpi/ic_dialer_fork_tt_keypad.png new file mode 100644 index 000000000..7ac4d8b58 Binary files /dev/null and b/java/com/android/dialer/dialpadview/res/drawable-xxhdpi/ic_dialer_fork_tt_keypad.png differ diff --git a/java/com/android/dialer/dialpadview/res/drawable/dialpad_scrim.xml b/java/com/android/dialer/dialpadview/res/drawable/dialpad_scrim.xml deleted file mode 100644 index ee0f40ab5..000000000 --- a/java/com/android/dialer/dialpadview/res/drawable/dialpad_scrim.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - diff --git a/java/com/android/dialer/dialpadview/res/drawable/ic_wifi_calling.xml b/java/com/android/dialer/dialpadview/res/drawable/ic_wifi_calling.xml new file mode 100644 index 000000000..968713376 --- /dev/null +++ b/java/com/android/dialer/dialpadview/res/drawable/ic_wifi_calling.xml @@ -0,0 +1,29 @@ + + + + + + + \ No newline at end of file diff --git a/java/com/android/dialer/dialpadview/res/drawable/shadow_fade_left.xml b/java/com/android/dialer/dialpadview/res/drawable/shadow_fade_left.xml new file mode 100644 index 000000000..6271a8f86 --- /dev/null +++ b/java/com/android/dialer/dialpadview/res/drawable/shadow_fade_left.xml @@ -0,0 +1,24 @@ + + + + + + diff --git a/java/com/android/dialer/dialpadview/res/drawable/shadow_fade_up.xml b/java/com/android/dialer/dialpadview/res/drawable/shadow_fade_up.xml new file mode 100644 index 000000000..86d37a9bc --- /dev/null +++ b/java/com/android/dialer/dialpadview/res/drawable/shadow_fade_up.xml @@ -0,0 +1,24 @@ + + + + + + \ No newline at end of file diff --git a/java/com/android/dialer/dialpadview/res/layout-land/dialpad_fragment.xml b/java/com/android/dialer/dialpadview/res/layout-land/dialpad_fragment.xml new file mode 100644 index 000000000..6389853d9 --- /dev/null +++ b/java/com/android/dialer/dialpadview/res/layout-land/dialpad_fragment.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/com/android/dialer/dialpadview/res/layout-land/dialpad_key_one.xml b/java/com/android/dialer/dialpadview/res/layout-land/dialpad_key_one.xml index 6f178f0e1..135624681 100644 --- a/java/com/android/dialer/dialpadview/res/layout-land/dialpad_key_one.xml +++ b/java/com/android/dialer/dialpadview/res/layout-land/dialpad_key_one.xml @@ -35,7 +35,7 @@ diff --git a/java/com/android/dialer/dialpadview/res/layout/dialpad_chooser_list_item.xml b/java/com/android/dialer/dialpadview/res/layout/dialpad_chooser_list_item.xml new file mode 100644 index 000000000..e00529614 --- /dev/null +++ b/java/com/android/dialer/dialpadview/res/layout/dialpad_chooser_list_item.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + diff --git a/java/com/android/dialer/dialpadview/res/layout/dialpad_fragment.xml b/java/com/android/dialer/dialpadview/res/layout/dialpad_fragment.xml new file mode 100644 index 000000000..2f62e1407 --- /dev/null +++ b/java/com/android/dialer/dialpadview/res/layout/dialpad_fragment.xml @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/java/com/android/dialer/dialpadview/res/layout/dialpad_key_one.xml b/java/com/android/dialer/dialpadview/res/layout/dialpad_key_one.xml index 88594401f..4401c5bbd 100644 --- a/java/com/android/dialer/dialpadview/res/layout/dialpad_key_one.xml +++ b/java/com/android/dialer/dialpadview/res/layout/dialpad_key_one.xml @@ -18,7 +18,8 @@ android:id="@+id/one" style="@style/DialpadKeyButtonStyle"> + android:layout_marginTop="1dp" + style="@style/DialpadKeyInternalLayoutStyle"> @@ -28,9 +29,8 @@ diff --git a/java/com/android/dialer/dialpadview/res/layout/dialpad_view_unthemed.xml b/java/com/android/dialer/dialpadview/res/layout/dialpad_view_unthemed.xml index 838f1eca5..13c11f1ce 100644 --- a/java/com/android/dialer/dialpadview/res/layout/dialpad_view_unthemed.xml +++ b/java/com/android/dialer/dialpadview/res/layout/dialpad_view_unthemed.xml @@ -14,141 +14,142 @@ limitations under the License. --> + android:id="@+id/dialpad_view" + class="com.android.dialer.dialpadview.DialpadView" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_gravity="bottom" + android:background="?attr/dialpad_background" + android:clickable="true" + android:elevation="?attr/dialpad_elevation" + android:layoutDirection="ltr" + android:orientation="vertical"> + android:id="@+id/rate_container" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical" + android:visibility="gone"> + android:id="@+id/ild_container" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="@dimen/ild_margin_height" + android:layout_marginBottom="@dimen/ild_margin_height" + android:layout_gravity="center_horizontal" + android:orientation="horizontal"> + android:id="@+id/ild_country" + android:layout_width="wrap_content" + android:layout_height="wrap_content"/> + android:id="@+id/ild_rate" + android:textStyle="bold" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginStart="4dp"/> + android:layout_width="match_parent" + android:layout_height="1dp" + android:background="#e3e3e3"/> + android:id="@+id/digits_container" + android:layout_width="match_parent" + android:layout_height="?attr/dialpad_digits_adjustable_height" + android:orientation="horizontal"> + android:id="@+id/dialpad_back" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:layout_margin="@dimen/dialpad_overflow_margin" + android:paddingLeft="@dimen/dialpad_digits_menu_left_padding" + android:paddingRight="@dimen/dialpad_digits_menu_right_padding" + android:background="@drawable/btn_dialpad_key" + android:contentDescription="@string/description_dialpad_back" + android:gravity="center" + android:src="@drawable/quantum_ic_close_white_24" + android:tint="?attr/dialpad_icon_tint" + android:tintMode="src_in" + android:visibility="gone"/> + android:id="@+id/dialpad_overflow" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:layout_margin="@dimen/dialpad_overflow_margin" + android:paddingLeft="@dimen/dialpad_digits_menu_left_padding" + android:paddingRight="@dimen/dialpad_digits_menu_right_padding" + android:background="@drawable/btn_dialpad_key" + android:contentDescription="@string/description_dialpad_overflow" + android:gravity="center" + android:src="@drawable/quantum_ic_more_vert_white_24" + android:tint="?attr/dialpad_icon_tint" + android:tintMode="src_in" + android:visibility="gone"/> + android:id="@+id/digits" + class="com.android.dialer.dialpadview.DigitsEditText" + android:textStyle="normal" + android:layout_width="0dp" + android:layout_height="match_parent" + android:layout_weight="1" + android:background="@android:color/transparent" + android:cursorVisible="false" + android:focusableInTouchMode="true" + android:fontFamily="sans-serif" + android:freezesText="true" + android:gravity="center" + android:importantForAutofill="no" + android:maxLines="1" + android:scrollHorizontally="true" + android:singleLine="true" + android:textColor="?attr/dialpad_text_color" + android:textCursorDrawable="@null" + android:textSize="?attr/dialpad_digits_adjustable_text_size" + ex:resizing_text_min_size="@dimen/dialpad_digits_text_min_size"/> + android:id="@+id/deleteButton" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:paddingLeft="@dimen/dialpad_digits_padding" + android:paddingRight="@dimen/dialpad_digits_padding" + android:background="@drawable/btn_dialpad_key" + android:contentDescription="@string/description_delete_button" + android:src="@drawable/quantum_ic_backspace_white_24" + android:state_enabled="false" + android:tint="?attr/dialpad_icon_tint" + android:tintMode="src_in"/> + android:layout_width="match_parent" + android:layout_height="1dp" + android:background="#e3e3e3"/> + android:layout_width="match_parent" + android:layout_height="@dimen/dialpad_space_above_keys"/> + android:layout_width="match_parent" + android:layout_height="@dimen/dialpad_space_below_keys"/> diff --git a/java/com/android/dialer/dialpadview/res/menu/dialpad_options.xml b/java/com/android/dialer/dialpadview/res/menu/dialpad_options.xml new file mode 100644 index 000000000..2921ea3bb --- /dev/null +++ b/java/com/android/dialer/dialpadview/res/menu/dialpad_options.xml @@ -0,0 +1,30 @@ + + +

+ + + + + diff --git a/java/com/android/dialer/dialpadview/res/values-af/strings.xml b/java/com/android/dialer/dialpadview/res/values-af/strings.xml index b2d03a07f..c5c72e094 100644 --- a/java/com/android/dialer/dialpadview/res/values-af/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-af/strings.xml @@ -22,4 +22,18 @@ "backspace" "plus" "stemboodskap" + "bel" + "Om stemboodskapdiens te bel, skakel eers vliegtuigmodus af." + "Om stemboodskapdiens op te stel, gaan na Kieslys > Instellings." + "Voeg 2-sek.-pouse by" + "Voeg wagtyd by" + "Gebruik raak-nommerbord" + "Keer terug na oproep wat besig is" + "Voeg oproep by" + "IMEI" + "MEID" + "Laai tans van SIM-kaart af …" + "SIM-kaartkontakte" + "Bel %s" + "Kan nie hierdie nommer bel nie" diff --git a/java/com/android/dialer/dialpadview/res/values-am/strings.xml b/java/com/android/dialer/dialpadview/res/values-am/strings.xml index 04f6022d8..efbdb1de9 100644 --- a/java/com/android/dialer/dialpadview/res/values-am/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-am/strings.xml @@ -22,4 +22,18 @@ "የኋሊት ደምሳሽ" "የመደመር ምልክት" "የድምፅ መልዕክት" + "ይደውሉ" + "የድምጽ መልዕክት ጥሪ ለማድረግ፣ በመጀመሪያ የአውሮፕላን ሁነታን ያጥፉ።" + "የድምጽ መልዕክትን ለማዘጋጀት፣ ወደ ምናሌ > ቅንብሮች ይሂዱ።" + "2 ሴኮንድ ፋታ አክል" + "ቆይታ አክል" + "ባለድምጽ የንኪ ቁልፍ ሰሌዳን ይጠቀሙ" + "በመካሄድ ላይ ወዳለው ጥሪ ተመለስ" + "ጥሪ አክል" + "IMEI" + "MEID" + "ከSIM ካርድ ላይ በመጫን ላይ…" + "የSIM ካርድ ዕውቂያዎች" + "ወደ %s ደውል" + "ይህን ቁጥር መደወል አልተቻለም" diff --git a/java/com/android/dialer/dialpadview/res/values-ar/strings.xml b/java/com/android/dialer/dialpadview/res/values-ar/strings.xml index 9caea157e..649280a99 100644 --- a/java/com/android/dialer/dialpadview/res/values-ar/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-ar/strings.xml @@ -22,4 +22,18 @@ "مسافة للخلف" "علامة الجمع" "بريد صوتي" + "طلب" + "للاتصال بالبريد الصوتي، يجب أولاً إيقاف وضع الطائرة." + "لإعداد البريد الصوتي، انتقل إلى القائمة > الإعدادات." + "إضافة ثانيتين إيقاف مؤقت" + "إضافة انتظار" + "استخدام لوحة مفاتيح نغمات باللمس" + "عودة إلى المكالمة الجارية" + "إضافة مكالمة" + "IMEI" + "MEID" + "‏جارٍ التحميل من شريحة SIM…" + "‏شريحة SIM وجهات الاتصال" + "الاتصال بالرقم %s" + "لا يمكن الاتصال بهذا الرقم" diff --git a/java/com/android/dialer/dialpadview/res/values-az/strings.xml b/java/com/android/dialer/dialpadview/res/values-az/strings.xml index 46f218e09..8de688d05 100644 --- a/java/com/android/dialer/dialpadview/res/values-az/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-az/strings.xml @@ -22,4 +22,18 @@ "geri düyməsi" "plus" "səsli məktub" + "nömrə yığın" + "Səsli e-poçta zəng etmək üçün Təyyarə rejimini deaktiv edin." + "Səsli e-poçtu ayarlamaq üçün Menyu > Ayarlar bölməsinə daxil olun." + "2 saniyəlik pauza əlavə edin" + "Gözləmə əlavə edin" + "Toxunuş ton klaviaturasından istifadə edin" + "Davam edən zəngə qayıdın" + "Zəng əlavə edin" + "IMEI" + "MEID" + "SIM kartdan yüklənir..." + "SIM kart kontaktları" + "%s nömrəsinə zəng edin" + "Bu nömrəyə zəng etmək mümkün deyil" diff --git a/java/com/android/dialer/dialpadview/res/values-b+sr+Latn/strings.xml b/java/com/android/dialer/dialpadview/res/values-b+sr+Latn/strings.xml index 24ea30816..c15aee4bf 100644 --- a/java/com/android/dialer/dialpadview/res/values-b+sr+Latn/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-b+sr+Latn/strings.xml @@ -22,4 +22,18 @@ "backspace" "plus" "govorna pošta" + "birajte broj" + "Da biste pozvali govornu poštu, prvo isključite režim rada u avionu." + "Da biste podesili govornu poštu, idite u Meni > Podešavanja." + "Dodaj pauzu od 2 sekunde" + "Dodaj čekanje" + "Koristi tastaturu za tonsko biranje" + "Nazad u poziv koji je u toku" + "Dodaj poziv" + "IMEI" + "MEID" + "Učitava se sa SIM kartice…" + "Kontakti na SIM kartici" + "Pozovi %s" + "Nije moguće pozvati ovaj broj" diff --git a/java/com/android/dialer/dialpadview/res/values-be/strings.xml b/java/com/android/dialer/dialpadview/res/values-be/strings.xml index db504555e..cbe85f517 100644 --- a/java/com/android/dialer/dialpadview/res/values-be/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-be/strings.xml @@ -22,4 +22,18 @@ "backspace" "плюс" "галасавая пошта" + "набор" + "Каб пазваніць на галасавую пошту, спачатку адключыце Рэжым палёту." + "Каб наладзіць галасавую пошту, перайдзіце ў раздзел \"Меню > Налады\"." + "Дадаць 2-секундную паўзу" + "Дадаць чаканне" + "Выкарыстанне тонавай клавіятуры" + "Вярнуцца да бягучага выкліку" + "Дадаць выклік" + "IMEI" + "MEID" + "Загрузка з SIM-карты..." + "Кантакты SIM-карты" + "Выклікаць %s" + "Немагчыма выклікаць гэты нумар" diff --git a/java/com/android/dialer/dialpadview/res/values-bg/strings.xml b/java/com/android/dialer/dialpadview/res/values-bg/strings.xml index 7a3073d77..1188d7959 100644 --- a/java/com/android/dialer/dialpadview/res/values-bg/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-bg/strings.xml @@ -22,4 +22,18 @@ "backspace" "плюс" "гласова поща" + "набиране" + "За да чуете гласовата си поща, първо изключете самолетния режим." + "За да настроите гласовата поща, отворете „Меню“ > „Настройки“." + "Добавяне на пауза от 2 сек" + "Добавяне на изчакване" + "Използване на тонова клавиатура" + "Назад към текущото обаждане" + "Добавяне на обаждане" + "IMEI" + "MEID" + "Зарежда се от SIM картата…" + "Контакти от SIM картата" + "Обаждане на %s" + "Не можете да се обадите на този номер" diff --git a/java/com/android/dialer/dialpadview/res/values-bn/strings.xml b/java/com/android/dialer/dialpadview/res/values-bn/strings.xml index 98171cfc2..9f3713f6e 100644 --- a/java/com/android/dialer/dialpadview/res/values-bn/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-bn/strings.xml @@ -22,4 +22,18 @@ "ব্যাক-স্পেস" "যোগ চিহ্ন" "ভয়েসমেল" + "ডায়াল করুন" + "ভয়েসমেলে কল করতে, সবার আগে বিমানমোড বন্ধ করুন৷" + "ভয়েসমেল সেট-আপ করতে, মেনু > সেটিংসে যান৷" + "২-সেকেন্ড বিরতি যোগ করুন" + "অপেক্ষা যোগ করুন" + "টাচ-টোন কীপ্যাড ব্যবহার করুন" + "আগের কলে ফিরে যান" + "কল যোগ করুন" + "IMEI" + "MEID" + "সিম কার্ড থেকে লোড করা হচ্ছে…" + "সিম কার্ডের পরিচিতিগুলি" + "%s নম্বরে কল করুন" + "এই নম্বরে কল করা যাবে না" diff --git a/java/com/android/dialer/dialpadview/res/values-bs/strings.xml b/java/com/android/dialer/dialpadview/res/values-bs/strings.xml index 976866285..4c0527b59 100644 --- a/java/com/android/dialer/dialpadview/res/values-bs/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-bs/strings.xml @@ -22,4 +22,18 @@ "tipka za brisanje" "plus" "govorna pošta" + "biranje" + "Da pozovete govornu poštu, isključite Način rada u avionu." + "Da postavite govornu poštu, idite na Meni > Postavke." + "Dodajte pauzu od 2 sekunde" + "Dodajte čekanje" + "Korištenje tastature za tonsko biranje" + "Povratak na poziv" + "Dodajte poziv" + "IMEI" + "MEID" + "Učitavanje sa SIM kartice…" + "Kontakti sa SIM kartice" + "Pozivanje broja %s" + "Nije moguće pozvati ovaj broj" diff --git a/java/com/android/dialer/dialpadview/res/values-ca/strings.xml b/java/com/android/dialer/dialpadview/res/values-ca/strings.xml index 2bd6c711c..eda95b474 100644 --- a/java/com/android/dialer/dialpadview/res/values-ca/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-ca/strings.xml @@ -22,4 +22,18 @@ "retrocés" "més" "missatge de veu" + "marca" + "Per trucar a la bústia de veu, primer has de desactivar el mode d\'avió." + "Per configurar la bústia de veu, ves a Menú > Configuració." + "Afegeix una pausa de 2 segons" + "Afegeix una espera" + "Utilitza el teclat de tons" + "Torna a la trucada en curs" + "Afegeix una trucada" + "IMEI" + "MEID" + "S\'està carregant des de la targeta SIM..." + "Contactes de la targeta SIM" + "Truca al %s" + "No es pot trucar a aquest número" diff --git a/java/com/android/dialer/dialpadview/res/values-cs/strings.xml b/java/com/android/dialer/dialpadview/res/values-cs/strings.xml index 6c13e1c47..a97d2132b 100644 --- a/java/com/android/dialer/dialpadview/res/values-cs/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-cs/strings.xml @@ -22,4 +22,18 @@ "Backspace" "plus" "hlasová zpráva" + "vytočit" + "Pokud chcete volat do hlasové schránky, vypněte nejdříve režim letadla." + "Pokud chcete nastavit hlasovou schránku, přejděte na nabídku > Nastavení." + "Přidat pauzu 2 s" + "Přidat čekání" + "Použít dotykovou tónovou klávesnici" + "Vrátit se k probíhajícímu hovoru" + "Přidat hovor" + "IMEI" + "MEID" + "Načítání ze SIM karty…" + "Kontakty na SIM kartě" + "Zavolat %s" + "Na toto číslo není možné zavolat" diff --git a/java/com/android/dialer/dialpadview/res/values-da/strings.xml b/java/com/android/dialer/dialpadview/res/values-da/strings.xml index 1df734896..45eb87238 100644 --- a/java/com/android/dialer/dialpadview/res/values-da/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-da/strings.xml @@ -22,4 +22,18 @@ "tilbagetast" "plus" "telefonsvarer" + "ring op" + "Hvis du vil ringe til telefonsvareren, skal du først slå Flytilstand fra." + "Gå til Menu > Indstillinger for at konfigurere telefonsvareren." + "Tilføj pause på 2 sek." + "Tilføj ventetid" + "Brug trykknaptastatur" + "Vend tilbage til igangværende opkald" + "Tilføj opkald" + "IMEI-nummer" + "MEID-nummer" + "Der indlæses fra SIM-kortet…" + "Kontaktpersoner på SIM-kortet" + "Ring til %s" + "Det er ikke muligt at ringe til dette nummer" diff --git a/java/com/android/dialer/dialpadview/res/values-de/strings.xml b/java/com/android/dialer/dialpadview/res/values-de/strings.xml index c93ce4d4f..c350c9484 100644 --- a/java/com/android/dialer/dialpadview/res/values-de/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-de/strings.xml @@ -22,4 +22,18 @@ "Rücktaste" "Plus" "Mailboxnachricht" + "Wählen" + "Deaktiviere zunächst den Flugmodus, um die Mailbox anzurufen." + "Konfiguriere deine Mailbox unter \"Menü\" > \"Einstellungen\"." + "2 Sekunden Pause hinzufügen" + "Warten hinzufügen" + "Tonwahltasten verwenden" + "Zurück zum aktuellen Anruf" + "Anruf hinzufügen" + "IMEI" + "MEID" + "Ladevorgang von SIM-Karte läuft…" + "Kontakte auf SIM-Karte" + "%s anrufen" + "Diese Nummer kann nicht angerufen werden" diff --git a/java/com/android/dialer/dialpadview/res/values-el/strings.xml b/java/com/android/dialer/dialpadview/res/values-el/strings.xml index 1bce64b93..0205f7694 100644 --- a/java/com/android/dialer/dialpadview/res/values-el/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-el/strings.xml @@ -22,4 +22,18 @@ "backspace" "συν" "αυτόματος τηλεφωνητής" + "κλήση" + "Για κλήση αυτόματου τηλεφωνητή, πρώτα απενεργοποιήστε τη λειτουργία πτήσης." + "Για τη ρύθμιση του αυτόματου τηλεφωνητή, μεταβείτε στο στοιχείο Μενού > Ρυθμίσεις." + "Προσθήκη παύσης 2 δευτερολέπτων" + "Προσθήκη αναμονής" + "Χρησιμοποιήστε το πληκτρολόγιο αφής ηχητικών τόνων" + "Επιστροφή στην κλήση που βρίσκεται σε εξέλιξη" + "Προσθήκη κλήσης" + "IMEI" + "MEID" + "Φόρτωση από κάρτα SIM…" + "Επαφές στην κάρτα SIM" + "Κλήση %s" + "Δεν μπορείτε να καλέσετε αυτόν τον αριθμό" diff --git a/java/com/android/dialer/dialpadview/res/values-en-rAU/strings.xml b/java/com/android/dialer/dialpadview/res/values-en-rAU/strings.xml index 62fc54747..3f16055d7 100644 --- a/java/com/android/dialer/dialpadview/res/values-en-rAU/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-en-rAU/strings.xml @@ -22,4 +22,18 @@ "backspace" "plus" "voicemail" + "dial" + "To call voicemail, first turn off Aeroplane mode." + "To set up voicemail, go to Menu > Settings." + "Add 2-sec pause" + "Add wait" + "Use touch tone keypad" + "Return to call in progress" + "Add call" + "IMEI" + "MEID" + "Loading from SIM card…" + "SIM card contacts" + "Call %s" + "Can\'t call this number" diff --git a/java/com/android/dialer/dialpadview/res/values-en-rGB/strings.xml b/java/com/android/dialer/dialpadview/res/values-en-rGB/strings.xml index 62fc54747..3f16055d7 100644 --- a/java/com/android/dialer/dialpadview/res/values-en-rGB/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-en-rGB/strings.xml @@ -22,4 +22,18 @@ "backspace" "plus" "voicemail" + "dial" + "To call voicemail, first turn off Aeroplane mode." + "To set up voicemail, go to Menu > Settings." + "Add 2-sec pause" + "Add wait" + "Use touch tone keypad" + "Return to call in progress" + "Add call" + "IMEI" + "MEID" + "Loading from SIM card…" + "SIM card contacts" + "Call %s" + "Can\'t call this number" diff --git a/java/com/android/dialer/dialpadview/res/values-en-rIN/strings.xml b/java/com/android/dialer/dialpadview/res/values-en-rIN/strings.xml index 62fc54747..3f16055d7 100644 --- a/java/com/android/dialer/dialpadview/res/values-en-rIN/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-en-rIN/strings.xml @@ -22,4 +22,18 @@ "backspace" "plus" "voicemail" + "dial" + "To call voicemail, first turn off Aeroplane mode." + "To set up voicemail, go to Menu > Settings." + "Add 2-sec pause" + "Add wait" + "Use touch tone keypad" + "Return to call in progress" + "Add call" + "IMEI" + "MEID" + "Loading from SIM card…" + "SIM card contacts" + "Call %s" + "Can\'t call this number" diff --git a/java/com/android/dialer/dialpadview/res/values-es-rUS/strings.xml b/java/com/android/dialer/dialpadview/res/values-es-rUS/strings.xml index 4c2908852..5bf2ae8bd 100644 --- a/java/com/android/dialer/dialpadview/res/values-es-rUS/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-es-rUS/strings.xml @@ -22,4 +22,18 @@ "retroceso" "más" "buzón de voz" + "marcar" + "Para escuchar los mensajes de tu buzón de voz, desactiva primero el modo avión." + "Para configurar el buzón de voz, ve a Menú > Configuración." + "Agregar pausa de 2 segundos" + "Agregar espera" + "Usar teclado numérico" + "Regresar a la llamada en curso" + "Agregar llamada" + "IMEI" + "MEID" + "Cargando desde tarjeta SIM…" + "Contactos de la tarjeta SIM" + "Llamar al %s" + "No se puede llamar a este número" diff --git a/java/com/android/dialer/dialpadview/res/values-es/strings.xml b/java/com/android/dialer/dialpadview/res/values-es/strings.xml index 7fd6355b2..af3590874 100644 --- a/java/com/android/dialer/dialpadview/res/values-es/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-es/strings.xml @@ -22,4 +22,18 @@ "retroceso" "más" "mensaje de voz" + "marcar" + "Para llamar al buzón de voz, debes desactivar el modo avión." + "Para configurar el buzón de voz, ve a Menú > Ajustes." + "Añadir pausa de 2 segundos" + "Añadir espera" + "Usar teclado táctil" + "Volver a la llamada en curso" + "Añadir llamada" + "IMEI" + "MEID" + "Cargando el número de teléfono de la tarjeta SIM…" + "Contactos de la tarjeta SIM" + "Llamar al %s" + "No se puede llamar a este número" diff --git a/java/com/android/dialer/dialpadview/res/values-et/strings.xml b/java/com/android/dialer/dialpadview/res/values-et/strings.xml index e71bd717b..c5e4f5f38 100644 --- a/java/com/android/dialer/dialpadview/res/values-et/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-et/strings.xml @@ -22,4 +22,18 @@ "tagasilüke" "pluss" "kõnepostisõnum" + "helista" + "Kõnepostisõnumite kuulamiseks lülitage esmalt välja lennukirežiim." + "Kõneposti seadistamiseks tehke valikud Menüü > Seaded." + "Lisa kahesekundiline paus" + "Lisa ootamine" + "Kasuta puutetooniga klahvistikku" + "Naase käimasolevale kõnele" + "Lisa kõne" + "IMEI" + "MEID" + "Laadimine SIM-kaardilt …" + "SIM-kaardi kontaktid" + "Helistamine numbrile %s" + "Sellele numbrile ei saa helistada" diff --git a/java/com/android/dialer/dialpadview/res/values-eu/strings.xml b/java/com/android/dialer/dialpadview/res/values-eu/strings.xml index c70948b2e..778b199f8 100644 --- a/java/com/android/dialer/dialpadview/res/values-eu/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-eu/strings.xml @@ -22,4 +22,18 @@ "atzera tekla" "gehi" "erantzungailua" + "markatu" + "Ahots-mezuak entzuteko, Hegaldi modua desaktibatu behar duzu." + "Erantzungailua konfiguratzeko, joan Menua > Ezarpenak atalera." + "Gehitu 2 segundoko pausa" + "Gehitu itxaronaldia" + "Erabili ukipen-tonuak dituen teklatua" + "Itzuli abian den deira" + "Gehitu deia" + "IMEI" + "MEID" + "SIM txarteletik kargatzen…" + "SIM txarteleko kontaktuak" + "Deitu %s zenbakira" + "Ezin da deitu zenbaki honetara" diff --git a/java/com/android/dialer/dialpadview/res/values-fa/strings.xml b/java/com/android/dialer/dialpadview/res/values-fa/strings.xml index 716360f99..070ca0059 100644 --- a/java/com/android/dialer/dialpadview/res/values-fa/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-fa/strings.xml @@ -22,4 +22,18 @@ "برگشت به عقب" "به‌علاوه" "پست صوتی" + "شماره‌گیری" + "برای تماس با پست صوتی، ابتدا حالت هواپیما را غیرفعال کنید." + "برای راه‌اندازی پست صوتی به منو > تنظیمات بروید." + "افزودن یک مکث ۲ ثانیه‌ای" + "افزودن انتظار" + "استفاده از صفحه‌کلید لمسی" + "برگشت به تماس درحال انجام" + "افزودن تماس" + "IMEI" + "MEID" + "در حال بارگیری سیم کارت..." + "مخاطبین سیم‌کارت" + "تماس با %s" + "تماس با این شماره ممکن نیست" diff --git a/java/com/android/dialer/dialpadview/res/values-fi/strings.xml b/java/com/android/dialer/dialpadview/res/values-fi/strings.xml index 63e96f639..0a7a7912b 100644 --- a/java/com/android/dialer/dialpadview/res/values-fi/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-fi/strings.xml @@ -22,4 +22,18 @@ "askelpalautin" "plus" "ääniviesti" + "soita" + "Poista lentokonetila käytöstä ennen vastaajaan soittamista." + "Määritä puhelinvastaajan asetukset kohdassa Valikko > Asetukset." + "Lisää 2 sekunnin tauko" + "Lisää tauko" + "Käytä näppäimistöä" + "Palaa meneillään olevaan puheluun" + "Lisää puhelu" + "IMEI-koodi" + "MEID" + "Ladataan SIM-kortilta…" + "SIM-kortin yhteystiedot" + "Soita %s" + "Numeroon ei voi soittaa." diff --git a/java/com/android/dialer/dialpadview/res/values-fr-rCA/strings.xml b/java/com/android/dialer/dialpadview/res/values-fr-rCA/strings.xml index bb0454552..3080169ac 100644 --- a/java/com/android/dialer/dialpadview/res/values-fr-rCA/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-fr-rCA/strings.xml @@ -22,4 +22,18 @@ "retour arrière" "plus" "messagerie vocale" + "composer" + "Veuillez désactiver le mode Avion avant d\'appeler la messagerie vocale." + "Pour configurer la messagerie vocale, accédez à Menu > Paramètres." + "Ajouter une pause de 2 s" + "Ajouter une attente" + "Utiliser le clavier DTMF" + "Reprendre l\'appel en cours" + "Ajouter un appel" + "IIEM" + "IDEM" + "Chargement à partir de la carte SIM en cours…" + "Contacts de la carte SIM" + "Appeler le %s" + "Vous ne pouvez pas appeler ce numéro" diff --git a/java/com/android/dialer/dialpadview/res/values-fr/strings.xml b/java/com/android/dialer/dialpadview/res/values-fr/strings.xml index ea3e67c61..b4fc15222 100644 --- a/java/com/android/dialer/dialpadview/res/values-fr/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-fr/strings.xml @@ -22,4 +22,18 @@ "retour arrière" "plus" "message vocal" + "composer" + "Pour pouvoir appeler la messagerie vocale, vous devez désactiver le mode Avion." + "Pour configurer la messagerie vocale, accédez à Menu > Paramètres." + "Ajouter une pause de 2 s" + "Ajouter une attente" + "Utiliser le clavier DTMF" + "Reprendre l\'appel en cours" + "Ajouter un appel" + "Code IMEI" + "Code MEID" + "Chargement depuis la carte SIM..." + "Contacts de la carte SIM" + "Appeler le %s" + "Impossible d\'appeler ce numéro" diff --git a/java/com/android/dialer/dialpadview/res/values-gl/strings.xml b/java/com/android/dialer/dialpadview/res/values-gl/strings.xml index d3901949b..25ffc278d 100644 --- a/java/com/android/dialer/dialpadview/res/values-gl/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-gl/strings.xml @@ -22,4 +22,18 @@ "retroceso" "máis" "correo de voz" + "marca" + "Para chamar ao correo de voz, primeiro desactiva o modo avión." + "Para configurar o correo de voz, accede a Menú > Configuración." + "Engadir pausa de 2 segundos" + "Engadir espera" + "Usar teclado de tons táctiles" + "Volver á chamada en curso" + "Engadir chamada" + "IMEI" + "MEID" + "Cargando número da tarxeta SIM…" + "Contactos da tarxeta SIM" + "Chamar ao %s" + "Non é posible chamar a este número" diff --git a/java/com/android/dialer/dialpadview/res/values-gu/strings.xml b/java/com/android/dialer/dialpadview/res/values-gu/strings.xml index 8962694f9..e4e13b3eb 100644 --- a/java/com/android/dialer/dialpadview/res/values-gu/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-gu/strings.xml @@ -22,4 +22,18 @@ "backspace" "પ્લસ" "વૉઇસમેઇલ" + "ડાયલ કરો" + "વૉઇસમેઇલ પર કૉલ કરવા માટે, પહેલાં એરપ્લેન મોડને બંધ કરો." + "વૉઇસમેઇલ સેટ કરવા માટે, મેનૂ > સેટિંગ્સ પર જાઓ." + "2-સેકંડનો વિરામ ઉમેરો" + "પ્રતીક્ષા ઉમેરો" + "ટચ ટોન કીપેડનો ઉપયોગ કરો" + "કૉલ પર પાછા આવવું પ્રગતિ પર છે" + "કૉલ ઉમેરો" + "IMEI" + "MEID" + "SIM કાર્ડમાંથી લોડ કરી રહ્યાં છીએ…" + "SIM કાર્ડ સંપર્કો" + "%s પર કૉલ કરો" + "આ નંબર પર કૉલ કરી શકાતો નથી" diff --git a/java/com/android/dialer/dialpadview/res/values-hi/strings.xml b/java/com/android/dialer/dialpadview/res/values-hi/strings.xml index 4388ec2fa..529f8c729 100644 --- a/java/com/android/dialer/dialpadview/res/values-hi/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-hi/strings.xml @@ -22,4 +22,18 @@ "backspace" "धन का चिह्न" "वॉइसमेल" + "डायल करें" + "वॉइसमेल कॉल करने के लिए, पहले हवाई जहाज़ मोड बंद करें." + "वॉइसमेल सेट अप करने के लिए, मेनू > सेटिंग पर जाएं." + "2-सेकंड का विराम जोड़ें" + "प्रतीक्षा का समय बढ़ाएं" + "टच टोन कीपैड का उपयोग करें" + "कॉल पर लौटने का कार्य प्रगति पर" + "कॉल जोड़ें" + "IMEI" + "MEID" + "SIM कार्ड से लोड हो रहा है…" + "SIM कार्ड के संपर्क" + "%s पर कॉल करें" + "इस नंबर पर कॉल नहीं किया जा सकता" diff --git a/java/com/android/dialer/dialpadview/res/values-hr/strings.xml b/java/com/android/dialer/dialpadview/res/values-hr/strings.xml index b904d2303..6ec34d29e 100644 --- a/java/com/android/dialer/dialpadview/res/values-hr/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-hr/strings.xml @@ -22,4 +22,18 @@ "povratna tipka" "plus" "govorna pošta" + "biraj" + "Da biste nazvali govornu poštu, najprije isključite način rada u zrakoplovu." + "Da biste postavili govornu poštu, idite na Izbornik > Postavke." + "Dodaj pauzu od 2 s." + "Dodaj čekanje" + "Koristite dodirnu zvučnu tipkovnicu" + "Natrag na poziv u tijeku" + "Dodaj poziv" + "IMEI" + "MEID" + "Učitavanje sa SIM kartice..." + "Kontakti na SIM kartici" + "Nazovite %s" + "Nije moguće nazvati taj broj" diff --git a/java/com/android/dialer/dialpadview/res/values-hu/strings.xml b/java/com/android/dialer/dialpadview/res/values-hu/strings.xml index 4b1c854bc..7ef242410 100644 --- a/java/com/android/dialer/dialpadview/res/values-hu/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-hu/strings.xml @@ -22,4 +22,18 @@ "Backspace" "plusz" "hangposta" + "tárcsázás" + "Hangposta hívásához kapcsolja ki a Repülőgép üzemmódot." + "A hangposta beállításához válassza a Menü > Beállítások pontot." + "2 mp-es szünet hozzáadása" + "Várakozás hozzáadása" + "Hangkódos telefonbillentyűzet használata" + "Vissza a folyamatban lévő híváshoz" + "Hívás hozzáadása" + "IMEI" + "MEID" + "Betöltés a SIM-kártyáról…" + "Névjegyek a SIM-kártyán" + "Hívás: %s" + "Nem lehet felhívni ezt a számot" diff --git a/java/com/android/dialer/dialpadview/res/values-hy/strings.xml b/java/com/android/dialer/dialpadview/res/values-hy/strings.xml index 4433c7016..0839922ec 100644 --- a/java/com/android/dialer/dialpadview/res/values-hy/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-hy/strings.xml @@ -22,4 +22,18 @@ "հետշարժ" "գումարում" "ձայնային փոստ" + "համարհավաքել" + "Ձայնային փոստին զանգելու համար նախ անջատեք Ինքնաթիռի ռեժիմը:" + "Ձայնային փոստը կարգավորելու համար անցեք Ընտրացնակ > Կարգավորումներ:" + "Ավելացնել 2 վայրկյան դադար" + "Ավելացնել սպասելաժամանակ" + "Օգտագործել տոնային ստեղնաշարը" + "Վերադառնալ ընթացիկ զանգին" + "Ավելացնել զանգ" + "IMEI" + "MEID" + "Բեռնվում է SIM քարտից…" + "SIM քարտի կոնտակտներ" + "Զանգել %s համարին" + "Հնարավոր չէ զանգել այս համարին" diff --git a/java/com/android/dialer/dialpadview/res/values-in/strings.xml b/java/com/android/dialer/dialpadview/res/values-in/strings.xml index 7aa47580a..4f7a05fc1 100644 --- a/java/com/android/dialer/dialpadview/res/values-in/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-in/strings.xml @@ -22,4 +22,18 @@ "backspace" "tambah" "pesan suara" + "panggil" + "Untuk memanggil pesan suara, nonaktifkan mode Pesawat terlebih dahulu." + "Untuk menyiapkan pesan suara, buka Menu > Setelan." + "Tambahkan jeda 2 dtk" + "Tambahkan tunggu" + "Gunakan keypad nada sentuh" + "Kembali ke panggilan sedang berlangsung" + "Tambahkan panggilan" + "IMEI" + "MEID" + "Memuat dari kartu SIM…" + "Kontak di kartu SIM" + "Telepon %s" + "Tidak dapat menelepon nomor ini" diff --git a/java/com/android/dialer/dialpadview/res/values-is/strings.xml b/java/com/android/dialer/dialpadview/res/values-is/strings.xml index 00f7cefe0..de6b9a239 100644 --- a/java/com/android/dialer/dialpadview/res/values-is/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-is/strings.xml @@ -22,4 +22,18 @@ "bakklykill" "plús" "talhólfsskilaboð" + "hringja" + "Til að hringja í talhólfið þarftu fyrst að slökkva á flugstillingu." + "Til að setja upp talhólf þarftu að opna valmyndina og velja Stillingar." + "Bæta við 2 sekúndna töf" + "Bæta töf við" + "Nota snertitónatakkaborð" + "Fara aftur í símtal í gangi" + "Bæta símtali við" + "IMEI" + "MEID" + "Hleður af SIM-kortinu…" + "Tengiliðir á SIM-korti" + "Hringja í %s" + "Ekki er hægt að hringja í þetta númer" diff --git a/java/com/android/dialer/dialpadview/res/values-it/strings.xml b/java/com/android/dialer/dialpadview/res/values-it/strings.xml index 9c4302af3..cb1b75216 100644 --- a/java/com/android/dialer/dialpadview/res/values-it/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-it/strings.xml @@ -22,4 +22,18 @@ "backspace" "più" "messaggio vocale" + "componi" + "Per chiamare la segreteria, disattiva la modalità aereo." + "Per configurare la segreteria, seleziona Menu > Impostazioni." + "Aggiungi pausa 2 sec" + "Aggiungi attesa" + "Usa tastierino per selezione a toni" + "Torna alla chiamata in corso" + "Aggiungi chiamata" + "IMEI" + "MEID" + "Caricamento da SIM..." + "Contatti della scheda SIM" + "Chiama %s" + "Impossibile chiamare questo numero" diff --git a/java/com/android/dialer/dialpadview/res/values-iw/strings.xml b/java/com/android/dialer/dialpadview/res/values-iw/strings.xml index c27af37cb..a8e784e97 100644 --- a/java/com/android/dialer/dialpadview/res/values-iw/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-iw/strings.xml @@ -22,4 +22,18 @@ "Backspace" "פלוס" "דואר קולי" + "חיוג" + "כדי להתקשר לתא הקולי, קודם עליך להשבית את מצב הטיסה." + "כדי להגדיר את התא הקולי, עליך להיכנס לתפריט > הגדרות." + "הוספת השהיה של 2 שניות" + "הוספת השהיה" + "שימוש במקלדת עם צלילי חיוג" + "חזרה לשיחה הפעילה" + "הוספת שיחה" + "IMEI" + "MEID" + "‏אנחנו טוענים מכרטיס ה-SIM…" + "‏אנשי הקשר בכרטיס ה-SIM" + "התקשרות אל %s" + "לא ניתן להתקשר אל המספר הזה" diff --git a/java/com/android/dialer/dialpadview/res/values-ja/strings.xml b/java/com/android/dialer/dialpadview/res/values-ja/strings.xml index d560c88b2..78ab67a4c 100644 --- a/java/com/android/dialer/dialpadview/res/values-ja/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-ja/strings.xml @@ -22,4 +22,18 @@ "Backspace" "足す" "ボイスメール" + "発信" + "機内モードを OFF にしてからボイスメールを呼び出してください。" + "ボイスメールを設定するには、[メニュー] > [設定] の順に開いてください。" + "2 秒間の停止を追加" + "待機を追加" + "プッシュホン式キーパッドを使う" + "通話に戻る" + "通話を追加" + "IMEI" + "MEID" + "SIM カードから読み込み中…" + "SIM カードの連絡先" + "%s に発信" + "この番号に発信できません" diff --git a/java/com/android/dialer/dialpadview/res/values-ka/strings.xml b/java/com/android/dialer/dialpadview/res/values-ka/strings.xml index 28e0319fd..2e3b25bf7 100644 --- a/java/com/android/dialer/dialpadview/res/values-ka/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-ka/strings.xml @@ -22,4 +22,18 @@ "უკუშლა" "პლუსი" "ხმოვანი ფოსტა" + "აკრეფა" + "ხმოვან ფოსტასთან დასაკავშირებლად, პირველ რიგში, გამორთეთ თვითმფრინავის რეჟიმი." + "ხმოვანი ფოსტის დასაყენებლად გადადით: მენიუ > პარამეტრები." + "ორწამიანი პაუზის დამატება" + "ლოდინის დამატება" + "ტონური რეჟიმის კლავიატურის გამოყენება" + "მიმდინარე ზარზე დაბრუნება" + "ზარის დამატება" + "IMEI" + "MEID" + "მიმდინარეობს ჩატვირთვა SIM ბარათიდან…" + "SIM ბარათის კონტაქტები" + "დარეკვა %s-ზე" + "ამ ნომერზე დარეკვა შეუძლებელია" diff --git a/java/com/android/dialer/dialpadview/res/values-kk/strings.xml b/java/com/android/dialer/dialpadview/res/values-kk/strings.xml index 902a41f59..3906017af 100644 --- a/java/com/android/dialer/dialpadview/res/values-kk/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-kk/strings.xml @@ -22,4 +22,18 @@ "Backspace пернесі" "қосу" "дауыстық пошта" + "теру" + "Дауыстық поштаға қоңырау шалу мүмкін болуы үшін, ұшақ режимін өшіру қажет." + "Дауыстық поштаны орнату үшін, \"Mәзір > Параметрлер\" тармағына өтіңіз." + "2 секундтық үзіліс қосу" + "\"Күту\" мүмкіндігін қосу" + "Сенсорлы және дыбысты пернетақта" + "Басталған қоңырауға оралу" + "Жаңа қоңырау қосу" + "IMEI" + "MEID" + "SIM картасынан жүктелуде..." + "SIM контактілері" + "%s нөміріне қоңырау шалу" + "Бұл нөмірге қоңырау шалу мүмкін емес" diff --git a/java/com/android/dialer/dialpadview/res/values-km/strings.xml b/java/com/android/dialer/dialpadview/res/values-km/strings.xml index be9483ef9..12b04a579 100644 --- a/java/com/android/dialer/dialpadview/res/values-km/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-km/strings.xml @@ -22,4 +22,18 @@ "លុប​ថយក្រោយ" "plus" "សារ​ជា​សំឡេង" + "ចុច" + "ដើម្បី​ហៅ​សារ​ជា​សំឡេង ដំបូង​ត្រូវ​បិទ​​មុខងារ​​ពេល​ជិះ​យន្តហោះ។" + "ដើម្បី​កំណត់​សារ​ជា​សំឡេង ចូល​ម៉ឺនុយ > ការ​កំណត់។" + "បញ្ចូល​ការផ្អាក 2 វិនាទី" + "បញ្ចូល​ការ​រង់ចាំ" + "ប្រើ​សំឡេង​ប៉ះ​បន្ទះ​លេខ" + "កំពុង​ត្រឡប់​ទៅកាន់​ការ​ហៅ" + "បញ្ចូល​ការហៅទូរសព្ទ" + "IMEI" + "MEID" + "កំពុង​ផ្ទុក​ពី​ស៊ីម​កាត..." + "ទំនាក់ទំនង​នៅ​ក្នុង​ស៊ីម​កាត" + "ហៅ​ទៅ​កាន់ %s" + "មិនអាចហៅ​ទៅ​កាន់​លេខនេះបានទេ" diff --git a/java/com/android/dialer/dialpadview/res/values-kn/strings.xml b/java/com/android/dialer/dialpadview/res/values-kn/strings.xml index 843058026..afc99b62b 100644 --- a/java/com/android/dialer/dialpadview/res/values-kn/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-kn/strings.xml @@ -22,4 +22,18 @@ "backspace" "ಸಂಕಲನ" "ಧ್ವನಿಮೇಲ್" + "ಡಯಲ್" + "ಧ್ವನಿಮೇಲ್‌ಗೆ ಕರೆ ಮಾಡಲು, ಮೊದಲು ಏರ್‌ಪ್ಲೇನ್‌‌ ಮೋಡ್‌‌ ಆಫ್‌ ಮಾಡಿ." + "ಧ್ವನಿಮೇಲ್‌ ಹೊಂದಿಸಲು, ಮೆನು > ಸೆಟ್ಟಿಂಗ್‌ಗಳುಗೆ ಹೋಗಿ." + "2-ಸೆ ವಿರಾಮವನ್ನು ಸೇರಿಸಿ" + "ನಿರೀಕ್ಷೆಯನ್ನು ಸೇರಿಸಿ" + "ಸ್ಪರ್ಶ ಟೋನ್ ಕೀಪ್ಯಾಡ್ ಬಳಸಿ" + "ಪ್ರತ್ಯತ್ತರ ಕರೆಯು ಪ್ರಗತಿಯಲ್ಲಿದೆ" + "ಕರೆಯನ್ನು ಸೇರಿಸಿ" + "IMEI" + "MEID" + "ಸಿಮ್‌ ಕಾರ್ಡ್‌ನಿಂದ ಲೋಡ್‌ ಮಾಡಲಾಗುತ್ತಿದೆ…" + "ಸಿಮ್‌ ಕಾರ್ಡ್‌ ಸಂಪರ್ಕಗಳು" + "%s ಕರೆ ಮಾಡಿ" + "ಈ ಸಂಖ್ಯೆಗೆ ಕರೆ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ" diff --git a/java/com/android/dialer/dialpadview/res/values-ko/strings.xml b/java/com/android/dialer/dialpadview/res/values-ko/strings.xml index 748843c60..8366ec5f6 100644 --- a/java/com/android/dialer/dialpadview/res/values-ko/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-ko/strings.xml @@ -22,4 +22,18 @@ "백스페이스" "더하기" "음성사서함" + "전화걸기" + "음성사서함 메시지를 확인하려면 먼저 비행기 모드를 해제하세요." + "음성사서함을 설정하려면 메뉴 > 설정으로 이동하세요." + "2초간 일시중지 추가" + "대기 시간 추가" + "터치톤 키패드 사용" + "진행 중인 통화로 돌아가기" + "통화 추가" + "IMEI" + "MEID" + "SIM 카드에서 로딩 중…" + "SIM 카드 연락처" + "%s에 전화걸기" + "이 번호에 전화를 걸 수 없습니다." diff --git a/java/com/android/dialer/dialpadview/res/values-ky/strings.xml b/java/com/android/dialer/dialpadview/res/values-ky/strings.xml index 703abdb1c..8ce17279e 100644 --- a/java/com/android/dialer/dialpadview/res/values-ky/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-ky/strings.xml @@ -22,4 +22,18 @@ "артка карай өчүрүү" "кошуу" "үн почтасы" + "терүү" + "Үн почтасын текшерүү үчүн, алгач Учак режимин өчүрүңүз." + "Үн почтасын жөндөө үчүн Меню > Жөндөөлөргө кириңиз." + "2-сек. тыныгууну кошуңуз" + "Тыныгуу кошуу" + "Тоналдык терүү тактасын колдонуу" + "Аткарылып жаткан чалууга кайтуу" + "Чалууну кошуу" + "IMEI" + "MEID" + "SIM-картадан жүктөлүүдө…" + "SIM картадагы байланыштар" + "%s номерине чалуу" + "Бул номерге чалуу мүмкүн болбой жатат" diff --git a/java/com/android/dialer/dialpadview/res/values-lo/strings.xml b/java/com/android/dialer/dialpadview/res/values-lo/strings.xml index aefc70199..a69e28e99 100644 --- a/java/com/android/dialer/dialpadview/res/values-lo/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-lo/strings.xml @@ -22,4 +22,18 @@ "ປຸ່ມ backspace" "ບວກ" "ຂໍ້ຄວາມສຽງ" + "ໂທ" + "ທ່ານຕ້ອງປິດໂໝດຢູ່ເທິງຍົນກ່ອນເພື່ອໂທຫາເບີຂໍ້ຄວາມສຽງ." + "ເພື່ອຕັ້ງຄ່າຂໍ້ຄວາມສຽງ ໃຫ້ໄປທີ່ ເມນູ > ການຕັ້ງຄ່າ." + "ເພີ່ມການຂັ້ນເວລາ 2 ວິນາທີ" + "ເພີ່ມການລໍຖ້າ" + "ໃຊ້ປຸ່ມກົດສັນຍານສຽງ" + "ກັບໄປການໂທທີ່ກຳລັງດຳເນີນຢູ່" + "ເພີ່ມການໂທ" + "IMEI" + "MEID" + "ກຳລັງໂຫລດຈາກ SIM card..." + "ລາຍຊື່ຜູ້ຕິດຕໍ່ SIM card" + "ໂທ​ຫາ %s" + "ບໍ່​ສາ​ມາດ​ໂທ​ຫາ​ເບີ​ນີ້​ໄດ້" diff --git a/java/com/android/dialer/dialpadview/res/values-lt/strings.xml b/java/com/android/dialer/dialpadview/res/values-lt/strings.xml index 0e352d032..3f09cdc78 100644 --- a/java/com/android/dialer/dialpadview/res/values-lt/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-lt/strings.xml @@ -22,4 +22,18 @@ "naikinimo klavišas" "sudėties ženklas" "balso pašto pranešimas" + "rinkti numerį" + "Jei norite skambinti į balso paštą, išjunkite lėktuvo režimą." + "Jei norite nustatyti balso paštą, eikite į meniu > „Nustatymai“." + "Pridėti 2 sek. pauzę" + "Pridėti laukimą" + "Naudoti jutiklinę tonų klaviatūrą" + "Grįžti prie vykdomo skambučio" + "Pridėti skambutį" + "IMEI" + "MEID" + "Įkeliama iš SIM kortelės..." + "SIM kortelės kontaktai" + "Skambinti %s" + "Negalima skambinti šiuo numeriu" diff --git a/java/com/android/dialer/dialpadview/res/values-lv/strings.xml b/java/com/android/dialer/dialpadview/res/values-lv/strings.xml index 4af53a3e5..bcc2039e6 100644 --- a/java/com/android/dialer/dialpadview/res/values-lv/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-lv/strings.xml @@ -22,4 +22,18 @@ "atpakaļatkāpe" "pluszīme" "balss pasts" + "sastādīt numuru" + "Lai piekļūtu balss pastam, vispirms izslēdziet lidojuma režīmu." + "Lai iestatītu balss pastu, atveriet sadaļu Izvēlne > Iestatījumi." + "Pievienot 2 sekundes ilgu pauzi" + "Pievienot gaidīšanas funkciju" + "Izmantot skārientastatūru" + "Atgriezties pie pašreizējā zvana" + "Pievienot zvanu" + "IMEI" + "MEID" + "Notiek ielāde no SIM kartes..." + "SIM kartes kontaktpersonas" + "Zvanīt: %s" + "Uz šo numuru nevar piezvanīt." diff --git a/java/com/android/dialer/dialpadview/res/values-mk/strings.xml b/java/com/android/dialer/dialpadview/res/values-mk/strings.xml index 2780e8aff..f98deb479 100644 --- a/java/com/android/dialer/dialpadview/res/values-mk/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-mk/strings.xml @@ -22,4 +22,18 @@ "избриши" "плус" "говорна пошта" + "бирај" + "За да се јавите во говорна пошта, исклучете го авионскиот режим." + "За поставување говорна пошта, одете во Мени > Поставки." + "Додај пауза од 2 сек." + "Додај чекање" + "Користете тастатура со тонско бирање" + "Вратете се на повик во тек" + "Додај повик" + "IMEI" + "MEID" + "Се вчитува од SIM-картичка…" + "Контакти од SIM-картичка" + "Повикај %s" + "Бројот не може да се повика" diff --git a/java/com/android/dialer/dialpadview/res/values-ml/strings.xml b/java/com/android/dialer/dialpadview/res/values-ml/strings.xml index 7ef8313d6..77033aa48 100644 --- a/java/com/android/dialer/dialpadview/res/values-ml/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-ml/strings.xml @@ -22,4 +22,18 @@ "ബാക്ക്‌സ്‌പെയ്‌സ്" "പ്ലസ്" "വോയ്‌സ്‌മെയിൽ" + "ഡയൽ ചെയ്യുക" + "വോയ്‌സ്‌മെയിൽ വിളിക്കാൻ ആദ്യം ഫ്ലൈറ്റ് മോഡ് ഓഫാക്കുക." + "വോയ്‌സ്‌മെയിൽ സജ്ജീകരിക്കുന്നതിന്, മെനു > ക്രമീകരണങ്ങൾ എന്നതിലേക്ക് പോകുക." + "2 സെക്കൻഡ് താൽക്കാലികമായി നിർത്തൽ ചേർക്കുക" + "കാത്തിരിക്കൽ ചേർക്കുക" + "ടച്ച് ടോൺ കീപാഡ് ഉപയോഗിക്കുക" + "വിളിച്ചുകൊണ്ടിരിക്കുന്ന കോളിലേക്ക് മടങ്ങുക" + "കോൾ ചേർക്കുക" + "IMEI" + "MEID" + "സിം കാർഡിൽ നിന്നും ലോഡുചെയ്യുന്നു…" + "സിം കാർഡ് കോൺടാക്റ്റുകൾ" + "വിളിക്കുക %s" + "ഈ നമ്പറിലേക്ക് കോൾ ചെയ്യാനാവില്ല" diff --git a/java/com/android/dialer/dialpadview/res/values-mn/strings.xml b/java/com/android/dialer/dialpadview/res/values-mn/strings.xml index 5bc3bb7db..d03bb9379 100644 --- a/java/com/android/dialer/dialpadview/res/values-mn/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-mn/strings.xml @@ -22,4 +22,18 @@ "ухраах" "нэмэх" "дуут шуудан" + "залгах" + "Дуут шуудан руу залгахын тулд эхлээд Нислэгийн горимыг идэвхгүй болгоно уу." + "Дуут шууданг тохируулахын тулд Цэс > Тохиргоо руу очно уу." + "2-сек зогсолт нэмэх" + "Хүлээлт нэмэх" + "Хүрэлтээр дуугардаг гар ашиглах" + "Үргэлжилж буй дуудлага руу буцах" + "Дуудлага нэмэх" + "IMEI" + "MEID" + "SIM картаас ачаалж байна…" + "SIM картны харилцагч" + "%s руу залгах" + "Энэ дугаар руу залгах боломжгүй" diff --git a/java/com/android/dialer/dialpadview/res/values-mr/strings.xml b/java/com/android/dialer/dialpadview/res/values-mr/strings.xml index 6f629e1a8..7b466a426 100644 --- a/java/com/android/dialer/dialpadview/res/values-mr/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-mr/strings.xml @@ -22,4 +22,18 @@ "backspace" "अधिक" "व्हॉइसमेल" + "डायल" + "व्हॉइसमेलला कॉल करण्यासाठी, प्रथम विमान मोड बंद करा." + "व्हॉइसमेल सेट करण्‍यासाठी, मेनू > सेटिंग्‍ज वर जा." + "2-सेकंदांचा विराम जोडा" + "वाट पाहणे जोडा" + "स्‍पर्श टोन कीपॅडचा वापर करा" + "चालू असलेल्या कॉलवर परत जा" + "कॉल जोडा" + "IMEI" + "MEID" + "सिम कार्ड मधून लोड करत आहे…" + "सिम कार्ड संपर्क" + "%s वर कॉल करा" + "या नंबरवर कॉल करू शकत नाही" diff --git a/java/com/android/dialer/dialpadview/res/values-ms/strings.xml b/java/com/android/dialer/dialpadview/res/values-ms/strings.xml index f767a2587..a3cbbea88 100644 --- a/java/com/android/dialer/dialpadview/res/values-ms/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-ms/strings.xml @@ -22,4 +22,18 @@ "undur ruang" "tambah" "mel suara" + "dail" + "Untuk membuat panggilan ke mel suara, mula-mula matikan mod Pesawat." + "Untuk menyediakan mel suara, pergi ke Menu > Tetapan." + "Tambah jeda 2 saat" + "Tambah penungguan" + "Gunakan pad kekunci nada sentuh" + "Kembali ke panggilan yang sedang berlangsung" + "Tambah panggilan" + "IMEI" + "MEID" + "Memuatkan daripada kad SIM…" + "Kenalan kad SIM" + "Panggil %s" + "Tidak dapat menghubungi nombor ini" diff --git a/java/com/android/dialer/dialpadview/res/values-my/strings.xml b/java/com/android/dialer/dialpadview/res/values-my/strings.xml index 877805680..4ece9fa18 100644 --- a/java/com/android/dialer/dialpadview/res/values-my/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-my/strings.xml @@ -22,4 +22,18 @@ "နောက်ပြန်ဖျက်ခလုတ်" "အပေါင်း လက္ခဏာ" "အသံမေးလ်" + "ဖုန်းခေါ်ရန်" + "အသံမေးလ်ခေါ်ဆိုရန်အတွက် လေယာဉ်ပျံမုဒ်ကို ဦးစွာပိတ်ပါ။" + "အသံမေးလ်စနစ်ကို စီစဉ်သတ်မှတ်ရန် မီနူး > ဆက်တင်များသို့ သွားပါ။" + "၂-စက္ကန့် ခဏရပ်ရန်" + "စောင့်ဆိုင်းရန်" + "အသံမြည်ခလုတ်ခုံကို အသုံးပြုရန်" + "လက်ရှိဖုန်းပြောနေမှုသို့ ပြန်သွားရန်" + "နောက်ထပ်ဖုန်းတစ်ခု ခေါ်ဆိုရန်" + "IMEI" + "MEID" + "ဆင်းမ်ကဒ်မှ ဖွင့်နေသည်…" + "ဆင်းမ်ကဒ်အဆက်အသွယ်များ" + "%s ကို ဖုန်းခေါ်ရန်" + "ဤနံပါတ်ကို မခေါ်ဆိုနိုင်ပါ" diff --git a/java/com/android/dialer/dialpadview/res/values-nb/strings.xml b/java/com/android/dialer/dialpadview/res/values-nb/strings.xml index c0756b25d..0f78eb7cf 100644 --- a/java/com/android/dialer/dialpadview/res/values-nb/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-nb/strings.xml @@ -22,4 +22,18 @@ "tilbaketast" "pluss" "talepost" + "ring" + "Du må slå av flymodus før du kan sjekke talepostkassen." + "For å konfigurere talepostfunksjonen, gå til Meny > Innstillinger." + "Legg til pause på 2 sek." + "Legg til Vent" + "Bruk tonetastatur" + "Gå tilbake til aktiv samtale" + "Nytt anrop" + "IMEI" + "MEID" + "Henter fra SIM-kort …" + "Kontakter på SIM-kort" + "Ring %s" + "Kan ikke ringe dette nummeret" diff --git a/java/com/android/dialer/dialpadview/res/values-ne/strings.xml b/java/com/android/dialer/dialpadview/res/values-ne/strings.xml index 713c6ad96..6369eb7fd 100644 --- a/java/com/android/dialer/dialpadview/res/values-ne/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-ne/strings.xml @@ -22,4 +22,18 @@ "ब्याकस्पेस" "जोड" "भ्वाइसमेल" + "डायल गर्नुहोस्" + "भ्वाइसमेल जाँच गर्न पहिले हवाइजहाज मोडलाई निष्क्रिय पार्नुहोस्।" + "भ्वाइसमेल सेट गर्न मेनु > सेटिङहरूमा जानुहोस्।" + "२ सेकन्डको पज थप्नुहोस्" + "प्रतीक्षाको समय थप्नुहोस्" + "टच टोन किप्याड प्रयोग गर्नुहोस्" + "जारी रहेको कलमा फर्किनुहोस्" + "कल थप्नुहोस्" + "IMEI" + "MEID" + "SIM कार्डबाट लोड हुँदै" + "SIM कार्डका सम्पर्क ठेगानाहरू" + "%s मा कल गर्नुहोस्" + "यस नम्बरमा कल गर्न सकिँदैन" diff --git a/java/com/android/dialer/dialpadview/res/values-nl/strings.xml b/java/com/android/dialer/dialpadview/res/values-nl/strings.xml index c7e058409..19911a1fc 100644 --- a/java/com/android/dialer/dialpadview/res/values-nl/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-nl/strings.xml @@ -22,4 +22,18 @@ "backspace" "plus" "voicemail" + "bellen" + "Als je je voicemail wilt bellen, moet je eerst de vliegtuigmodus uitschakelen." + "Voor het instellen van voicemail ga je naar Menu > Instellingen." + "Pauze van 2 seconden toevoegen" + "Wachten toevoegen" + "Toetsenblok voor toetsgeluid gebruiken" + "Terug naar actieve oproep" + "Oproep toevoegen" + "IMEI" + "MEID" + "Laden vanaf simkaart…" + "Contacten op simkaart" + "%s bellen" + "Kan dit nummer niet bellen" diff --git a/java/com/android/dialer/dialpadview/res/values-no/strings.xml b/java/com/android/dialer/dialpadview/res/values-no/strings.xml index c0756b25d..0f78eb7cf 100644 --- a/java/com/android/dialer/dialpadview/res/values-no/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-no/strings.xml @@ -22,4 +22,18 @@ "tilbaketast" "pluss" "talepost" + "ring" + "Du må slå av flymodus før du kan sjekke talepostkassen." + "For å konfigurere talepostfunksjonen, gå til Meny > Innstillinger." + "Legg til pause på 2 sek." + "Legg til Vent" + "Bruk tonetastatur" + "Gå tilbake til aktiv samtale" + "Nytt anrop" + "IMEI" + "MEID" + "Henter fra SIM-kort …" + "Kontakter på SIM-kort" + "Ring %s" + "Kan ikke ringe dette nummeret" diff --git a/java/com/android/dialer/dialpadview/res/values-pa/strings.xml b/java/com/android/dialer/dialpadview/res/values-pa/strings.xml index 66378e238..be5dc626f 100644 --- a/java/com/android/dialer/dialpadview/res/values-pa/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-pa/strings.xml @@ -22,4 +22,18 @@ "ਬੈਕਸਪੇਸ" "ਪਲਸ" "ਵੌਇਸਮੇਲ" + "ਡਾਇਲ ਕਰੋ" + "ਵੌਇਸਮੇਲ ਨੂੰ ਕਾਲ ਕਰਨ ਲਈ, ਪਹਿਲਾਂ ਜਹਾਜ਼ ਮੋਡ ਬੰਦ ਕਰੋ।" + "ਵੌਇਸਮੇਲ ਸਥਾਪਤ ਕਰਨ ਲਈ, ਮੀਨੂ > ਸੈਟਿੰਗਾਂ \'ਤੇ ਜਾਓ।" + "2-ਸਕਿੰਟ ਦਾ ਵਿਰਾਮ ਸ਼ਾਮਲ ਕਰੋ" + "ਉਡੀਕ ਦਾ ਸਮਾਂ ਸ਼ਾਮਲ ਕਰੋ" + "ਸਪਰੱਸ਼ ਧੁਨੀ ਕੀ-ਪੈਡ ਵਰਤੋ" + "ਜਾਰੀ ਕਾਲ \'ਤੇ ਵਾਪਸ ਜਾਓ" + "ਕਾਲ ਸ਼ਾਮਲ ਕਰੋ" + "IMEI" + "MEID" + "ਸਿਮ ਕਾਰਡ ਤੋਂ ਲੋਡ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…" + "ਸਿਮ ਕਾਰਡ ਸੰਪਰਕ" + "%s ਨੂੰ ਕਾਲ ਕਰੋ" + "ਇਸ ਨੰਬਰ \'ਤੇ ਕਾਲ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ" diff --git a/java/com/android/dialer/dialpadview/res/values-pl/strings.xml b/java/com/android/dialer/dialpadview/res/values-pl/strings.xml index b91c2c3d4..e3045b32f 100644 --- a/java/com/android/dialer/dialpadview/res/values-pl/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-pl/strings.xml @@ -22,4 +22,18 @@ "usuń" "plus" "poczta głosowa" + "wybierz numer" + "Aby połączyć się z pocztą głosową, najpierw wyłącz tryb samolotowy." + "Aby skonfigurować pocztę głosową, kliknij Menu > Ustawienia." + "Dodaj 2-sekundową pauzę" + "Dodaj oczekiwanie" + "Użyj klawiatury tonowej" + "Wróć do aktywnego połączenia" + "Dodaj połączenie" + "IMEI" + "MEID" + "Wczytuję z karty SIM…" + "Kontakty z karty SIM" + "Zadzwoń: %s" + "Nie można zadzwonić pod ten numer" diff --git a/java/com/android/dialer/dialpadview/res/values-pt-rBR/strings.xml b/java/com/android/dialer/dialpadview/res/values-pt-rBR/strings.xml index f5d6b9767..dc530fbd7 100644 --- a/java/com/android/dialer/dialpadview/res/values-pt-rBR/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-pt-rBR/strings.xml @@ -22,4 +22,18 @@ "voltar" "mais" "correio de voz" + "discar" + "Para ligar para o correio de voz, primeiro desative o modo avião." + "Para configurar o correio de voz, acesse Menu > Configurações." + "Adicionar pausa de 2 segundos" + "Adicionar espera" + "Usar teclado multifrequencial" + "Retornar para a chamada em espera" + "Adicionar chamada" + "IMEI" + "MEID" + "Carregando do cartão SIM..." + "Contatos do cartão SIM" + "Ligar para %s" + "Não é possível ligar para este número" diff --git a/java/com/android/dialer/dialpadview/res/values-pt-rPT/strings.xml b/java/com/android/dialer/dialpadview/res/values-pt-rPT/strings.xml index 8d98b07ba..aa3989272 100644 --- a/java/com/android/dialer/dialpadview/res/values-pt-rPT/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-pt-rPT/strings.xml @@ -22,4 +22,18 @@ "retrocesso" "mais" "mensagem de correio de voz" + "marcar" + "Para efetuar uma chamada para o correio de voz, desative primeiro o modo de avião." + "Para configurar o correio de voz, aceda a Menu > Definições." + "Adicionar pausa de 2 seg." + "Adicionar espera" + "Utilizar teclado numérico com tons de toque" + "Voltar à chamada em curso" + "Adic. cham." + "IMEI" + "MEID" + "A carregar a partir do cartão SIM..." + "Contactos do cartão SIM" + "Telefonar para %s" + "Não é possível ligar para este número" diff --git a/java/com/android/dialer/dialpadview/res/values-pt/strings.xml b/java/com/android/dialer/dialpadview/res/values-pt/strings.xml index f5d6b9767..dc530fbd7 100644 --- a/java/com/android/dialer/dialpadview/res/values-pt/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-pt/strings.xml @@ -22,4 +22,18 @@ "voltar" "mais" "correio de voz" + "discar" + "Para ligar para o correio de voz, primeiro desative o modo avião." + "Para configurar o correio de voz, acesse Menu > Configurações." + "Adicionar pausa de 2 segundos" + "Adicionar espera" + "Usar teclado multifrequencial" + "Retornar para a chamada em espera" + "Adicionar chamada" + "IMEI" + "MEID" + "Carregando do cartão SIM..." + "Contatos do cartão SIM" + "Ligar para %s" + "Não é possível ligar para este número" diff --git a/java/com/android/dialer/dialpadview/res/values-ro/strings.xml b/java/com/android/dialer/dialpadview/res/values-ro/strings.xml index 96075062e..87f48361d 100644 --- a/java/com/android/dialer/dialpadview/res/values-ro/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-ro/strings.xml @@ -22,4 +22,18 @@ "tasta backspace" "plus" "mesaj vocal" + "apelați" + "Pentru a apela mesageria vocală, mai întâi dezactivați modul Avion." + "Pentru a configura mesageria vocală, accesați Meniu > Setări." + "Adăugați o pauză de 2 secunde" + "Adăugați interval de așteptare" + "Tastatura tactilă cu sunet" + "Reveniți la apelul în curs" + "Adăugați un apel" + "IMEI" + "MEID" + "Se încarcă de pe cardul SIM…" + "Agenda de pe cardul SIM" + "Apelați %s" + "Nu puteți apela acest număr" diff --git a/java/com/android/dialer/dialpadview/res/values-ru/strings.xml b/java/com/android/dialer/dialpadview/res/values-ru/strings.xml index 5f1721d0b..24dd23c44 100644 --- a/java/com/android/dialer/dialpadview/res/values-ru/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-ru/strings.xml @@ -22,4 +22,18 @@ "клавиша Backspace" "плюс" "голосовая почта" + "набор номера" + "Сначала отключите режим полета." + "Чтобы настроить голосовую почту, выберите \"Меню > Настройки\"." + "Добавить двухсекундную паузу" + "Добавить паузу" + "Открыть панель тонального набора" + "Вернуться к текущему вызову" + "Добавить вызов" + "IMEI" + "MEID" + "Загрузка с SIM-карты…" + "Контакты на SIM-карте" + "Позвонить: %s" + "На этот номер нельзя позвонить" diff --git a/java/com/android/dialer/dialpadview/res/values-si/strings.xml b/java/com/android/dialer/dialpadview/res/values-si/strings.xml index 54ba2d712..f9c65b2a0 100644 --- a/java/com/android/dialer/dialpadview/res/values-si/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-si/strings.xml @@ -22,4 +22,18 @@ "backspace බොත්තම" "ධන" "හඬ තැපෑල" + "අමතන්න" + "හඬ තැපෑල ඇමතීමට, මුලින්ම ගුවන්යානා ප්‍රකාරය වසන්න." + "හඬ තැපෑල පිහිටුවීමට, මෙනුව > සැකසීම් වෙත යන්න." + "තත්පර 2ක විරාමයක් එක් කරන්න" + "රැඳී සිටීම එක් කරන්න" + "ස්පර්ශ නාද යතුරුපෑඩය භාවිතා කරන්න" + "පවතින ඇමතුමට නැවත යන්න" + "ඇමතුම එක් කරන්න" + "IMEI" + "MEID" + "SIM කාඩ්පතෙන් පූරණය කරමින්…" + "SIM කාඩ්පත් සම්බන්ධතා" + "%s අමතන්න" + "මෙම අංකයට ඇමතිය නොහැකිය" diff --git a/java/com/android/dialer/dialpadview/res/values-sk/strings.xml b/java/com/android/dialer/dialpadview/res/values-sk/strings.xml index ed584ce82..f8d2ae63c 100644 --- a/java/com/android/dialer/dialpadview/res/values-sk/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-sk/strings.xml @@ -22,4 +22,18 @@ "spätné mazanie" "plus" "hlasová správa" + "vytáčanie" + "Ak chcete volať hlasovú schránku, najprv vypnite režim v lietadle." + "Ak chcete nastaviť hlasovú schránku, prejdite na ponuku > Nastavenia." + "Pridať dvojsekundovú pauzu" + "Pridať čakanie" + "Použiť dotykovú tónovú klávesnicu" + "Vrátiť sa k prebiehajúcemu hovoru" + "Pridať hovor" + "IMEI" + "MEID" + "Načítava sa zo SIM karty..." + "Kontakty na SIM karte" + "Volať na číslo %s" + "Na toto číslo sa nedá zavolať" diff --git a/java/com/android/dialer/dialpadview/res/values-sl/strings.xml b/java/com/android/dialer/dialpadview/res/values-sl/strings.xml index 795a023a7..e406034bb 100644 --- a/java/com/android/dialer/dialpadview/res/values-sl/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-sl/strings.xml @@ -22,4 +22,18 @@ "vračalka" "plus" "sporočilo v odzivniku" + "pokliči" + "Če želite poklicati odzivnik, najprej izklopite način za letalo." + "Če želite nastaviti odzivnik, odprite »Meni« > »Nastavitve«." + "Dodaj 2 sekundi premora" + "Dodaj čakanje" + "Uporabi številčnico za tonsko izbiranje" + "Nazaj na klic, ki poteka" + "Dodaj klic" + "IMEI" + "MEID" + "Nalaganje s kartice SIM …" + "Stiki na kartici SIM" + "Pokliči %s" + "Te številke ni mogoče poklicati" diff --git a/java/com/android/dialer/dialpadview/res/values-sq/strings.xml b/java/com/android/dialer/dialpadview/res/values-sq/strings.xml index 7eb6af5c6..fd112593d 100644 --- a/java/com/android/dialer/dialpadview/res/values-sq/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-sq/strings.xml @@ -22,4 +22,18 @@ "kthim prapa" "plus" "postë zanore" + "formo numrin" + "Për të telefonuar postën zanore, në fillim çaktivizo modalitetin \"në aeroplan\"." + "Për të konfiguruar postën zanore, shko te \"Menyja\" > \"Cilësimet\"." + "Shto një ndërprerje 2-sekondëshe" + "Shto një pritje" + "Përdor bllokun e tasteve me prekje" + "Kthehu te telefonata në vazhdim" + "Shto telefonatë" + "IMEI" + "MEID" + "Po ngarkon nga karta SIM…" + "Kontaktet e kartës SIM" + "Telefono %s" + "Ky numër nuk mund të telefonohet" diff --git a/java/com/android/dialer/dialpadview/res/values-sr/strings.xml b/java/com/android/dialer/dialpadview/res/values-sr/strings.xml index fc9d941c9..706881309 100644 --- a/java/com/android/dialer/dialpadview/res/values-sr/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-sr/strings.xml @@ -22,4 +22,18 @@ "backspace" "плус" "говорна пошта" + "бирајте број" + "Да бисте позвали говорну пошту, прво искључите режим рада у авиону." + "Да бисте подесили говорну пошту, идите у Мени > Подешавања." + "Додај паузу од 2 секунде" + "Додај чекање" + "Користи тастатуру за тонско бирање" + "Назад у позив који је у току" + "Додај позив" + "IMEI" + "MEID" + "Учитава се са SIM картице…" + "Контакти на SIM картици" + "Позови %s" + "Није могуће позвати овај број" diff --git a/java/com/android/dialer/dialpadview/res/values-sv/strings.xml b/java/com/android/dialer/dialpadview/res/values-sv/strings.xml index 7554b522f..00524a89d 100644 --- a/java/com/android/dialer/dialpadview/res/values-sv/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-sv/strings.xml @@ -22,4 +22,18 @@ "backsteg" "plus" "röstbrevlåda" + "ring" + "Om du vill ringa röstbrevlådan måste du först inaktivera flygplansläget." + "Välj Meny > Inställningar om du vill konfigurera röstbrevlådan." + "Lägg till en paus på 2 sek." + "Lägg till väntetid" + "Använd tonvalstelefon" + "Återvänd till pågående samtal" + "Lägg till samtal" + "IMEI-kod" + "MEID" + "Läser in från SIM-kort …" + "Kontakter från SIM-kort" + "Ring %s" + "Det går inte att ringa det här numret" diff --git a/java/com/android/dialer/dialpadview/res/values-sw/strings.xml b/java/com/android/dialer/dialpadview/res/values-sw/strings.xml index 84479f0fa..98ed9cea8 100644 --- a/java/com/android/dialer/dialpadview/res/values-sw/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-sw/strings.xml @@ -22,4 +22,18 @@ "nafasi ya nyuma" "jumlisha" "ujumbe wa sauti" + "piga simu" + "Ili usikilize ujumbe wa sauti, kwanza zima Hali ya Ndegeni." + "Ili uweke mipangilio ya ujumbe wa sauti, nenda kwenye Menyu > Mipangilio." + "Ongeza usitishaji wa sekunde 2" + "Ongeza muda wa kusubiri" + "Tumia kibao cha kuchapa cha sauti na kugusa" + "Rudi kwenye simu inayoendelea" + "Ongeza simu" + "IMEI" + "MEID" + "Inapakia kutoka kwenye SIM kadi…" + "Anwani za SIM kadi" + "Piga simu %s" + "Haiwezi kupiga simu kwa nambari hii" diff --git a/java/com/android/dialer/dialpadview/res/values-ta/strings.xml b/java/com/android/dialer/dialpadview/res/values-ta/strings.xml index aad784b58..667010db6 100644 --- a/java/com/android/dialer/dialpadview/res/values-ta/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-ta/strings.xml @@ -22,4 +22,18 @@ "பேக்ஸ்பேஸ்" "பிளஸ்" "குரலஞ்சல்" + "டயல் பொத்தான்" + "குரலஞ்சலை அழைக்க, முதலில் விமானப் பயன்முறையை முடக்கவும்." + "குரலஞ்சலை அமைக்க, மெனு > அமைப்புகள் என்பதற்குச் செல்லவும்." + "2 வினாடி இடைநிறுத்தத்தைச் சேர்" + "காத்திருப்பைச் சேர்" + "டச் டோன் விசைத்தளத்தைப் பயன்படுத்து" + "செயலிலுள்ள அழைப்பிற்குத் திரும்பு" + "அழைப்பைச் சேர்" + "IMEI" + "MEID" + "சிம் கார்டிலிருந்து ஏற்றுகிறது…" + "சிம் கார்டு தொடர்புகள்" + "%s எண்ணை அழை" + "இந்த எண்ணை அழைக்க முடியாது" diff --git a/java/com/android/dialer/dialpadview/res/values-te/strings.xml b/java/com/android/dialer/dialpadview/res/values-te/strings.xml index eced150a0..5e24667aa 100644 --- a/java/com/android/dialer/dialpadview/res/values-te/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-te/strings.xml @@ -22,4 +22,18 @@ "బ్యాక్‌స్పేస్" "కూడిక" "వాయిస్ మెయిల్" + "డయల్ చేయండి" + "వాయిస్ మెయిల్ కాల్ చేయడానికి, మొదట విమానం మోడ్‌ను ఆపివేయండి." + "వాయిస్ మెయిల్ సెటప్ చేయడానికి, మెను > సెట్టింగ్‌లకు వెళ్లండి." + "2-సెకన్ల పాజ్‌ను జోడించండి" + "నిరీక్షణ సమయాన్ని జోడించండి" + "టచ్ టోన్ కీప్యాడ్‌ను ఉపయోగించండి" + "ప్రస్తుతం నడుస్తున్న కాల్‌కు తిరిగి వెళ్లండి" + "కాల్ జోడించండి" + "IMEI" + "MEID" + "సిమ్ కార్డు నుండి లోడ్ చేస్తోంది…" + "SIM కార్డ్ పరిచయాలు" + "%sకు కాల్ చేయండి" + "ఈ నంబర్‌కు కాల్ చేయలేరు" diff --git a/java/com/android/dialer/dialpadview/res/values-th/strings.xml b/java/com/android/dialer/dialpadview/res/values-th/strings.xml index db2c4959e..bb4cabd70 100644 --- a/java/com/android/dialer/dialpadview/res/values-th/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-th/strings.xml @@ -22,4 +22,18 @@ "ลบถอยหลัง" "บวก" "ข้อความเสียง" + "หมุนหมายเลข" + "หากต้องการฟังข้อความเสียง ให้ปิดโหมดใช้งานบนเครื่องบินก่อน" + "หากต้องการตั้งค่าข้อความเสียง ให้ไปที่เมนู > การตั้งค่า" + "เพิ่มช่วงคั่น 2 วินาที" + "เพิ่มการรอ" + "ใช้ปุ่มกดสัญญาณเสียง" + "กลับไปคุยสายต่อ" + "เพิ่มการโทร" + "IMEI" + "MEID" + "กำลังโหลดจากซิมการ์ด…" + "รายชื่อติดต่อในซิมการ์ด" + "โทร %s" + "ไม่สามารถโทรไปยังหมายเลขนี้" diff --git a/java/com/android/dialer/dialpadview/res/values-tl/strings.xml b/java/com/android/dialer/dialpadview/res/values-tl/strings.xml index 223f81e06..d23823e16 100644 --- a/java/com/android/dialer/dialpadview/res/values-tl/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-tl/strings.xml @@ -22,4 +22,18 @@ "backspace" "plus" "voicemail" + "mag-dial" + "Upang tumawag sa voicemail, i-off muna ang Airplane mode." + "Upang mag-set up ng voicemail, pumunta sa Menu > Mga Setting." + "Magdagdag ng pag-pause na 2-seg" + "Magdagdag ng paghihintay" + "Gumamit ng touch tone na keypad" + "Bumalik sa kasalukuyang tawag" + "Magdagdag ng tawag" + "IMEI" + "MEID" + "Naglo-load mula sa SIM card…" + "Mga contact sa SIM card" + "Tawagan ang %s" + "Hindi matawagan ang numerong ito" diff --git a/java/com/android/dialer/dialpadview/res/values-tr/strings.xml b/java/com/android/dialer/dialpadview/res/values-tr/strings.xml index ae8151178..b7b85013c 100644 --- a/java/com/android/dialer/dialpadview/res/values-tr/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-tr/strings.xml @@ -22,4 +22,18 @@ "geri tuşu" "artı" "sesli mesaj" + "telefonu arar" + "Sesli mesajı aramak için öncelikle Uçak modunu kapatın." + "Sesli mesajı yapılandırmak için Menü > Ayarlar\'a gidin." + "2 saniyelik duraklama ekle" + "Bekleme ekle" + "Telefon tuş takımını kullan" + "Devam eden çağrıya dön" + "Çağrı ekle" + "IMEI" + "MEID" + "SIM karttan yükleniyor…" + "SIM kart kişileri" + "Telefon et: %s" + "Bu numara aranamaz" diff --git a/java/com/android/dialer/dialpadview/res/values-uk/strings.xml b/java/com/android/dialer/dialpadview/res/values-uk/strings.xml index 7841c4ca6..c862fcedf 100644 --- a/java/com/android/dialer/dialpadview/res/values-uk/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-uk/strings.xml @@ -22,4 +22,18 @@ "видалення символів перед курсором" "плюс" "голосова пошта" + "дзвонити" + "Щоб перевірити голосову пошту, спочатку вимкніть режим польоту." + "Щоб налаштувати голосову пошту, перейдіть у Меню > Налаштування." + "Додати 2-секундну паузу" + "Додати паузу" + "Використовувати тональний набір" + "Повернутися до поточного виклику" + "Додати виклик" + "IMEI" + "MEID" + "Завантаження із SIM-карти…" + "Контакти із SIM-карти" + "Зателефонувати на номер %s" + "Не можна телефонувати на цей номер" diff --git a/java/com/android/dialer/dialpadview/res/values-ur/strings.xml b/java/com/android/dialer/dialpadview/res/values-ur/strings.xml index 6a537be9b..a7db8ec2b 100644 --- a/java/com/android/dialer/dialpadview/res/values-ur/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-ur/strings.xml @@ -22,4 +22,18 @@ "بیک اسپیس" "جمع" "صوتی میل" + "ڈائل کریں" + "صوتی میل کو کال کرنے کیلئے، پہلے ہوائی جہاز طرز آف کریں۔" + "صوتی میل سیٹ کرنے کے لئے، مینو > ترتیبات میں جائیں۔" + "2 سیکنڈ کا توقف شامل کریں" + "انتظار شامل کریں" + "ٹچ ٹون کی پیڈ کا استعمال کریں" + "جاری کال پر واپس لوٹیں" + "کال شامل کریں" + "IMEI" + "MEID" + "‏SIM کارڈ سے لوڈ ہو رہا ہے…" + "‏SIM کارڈ کے رابطے" + "%s کو کال کریں" + "اس نمبر پر کال نہیں کر سکتے" diff --git a/java/com/android/dialer/dialpadview/res/values-uz/strings.xml b/java/com/android/dialer/dialpadview/res/values-uz/strings.xml index 6985893d7..2230c2c1e 100644 --- a/java/com/android/dialer/dialpadview/res/values-uz/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-uz/strings.xml @@ -22,4 +22,18 @@ "orqaga" "qo‘shuv belgisi" "ovozli pochta" + "raqam terish" + "Ovozli pochtaga qo‘ng‘iroq qilish uchun parvoz rejimidan chiqing." + "Ovozli pochtani sozlab olish uchun Menyu > Sozlamalarga o‘ting." + "2 soniyalik pauza qo‘shish" + "Pauza qo‘shish" + "Tovushli raqam tergichni ochish" + "Davom etayotgan chaqiruvga qaytish" + "Chaqiruv qo‘shish" + "IMEI" + "MEID" + "SIM kartadan yuklanmoqda…" + "SIM kartadagi kontaktlar" + "%s raqamiga qo‘ng‘iroq qilish" + "Bu raqamga qo‘ng‘iroq qilib bo‘lmaydi" diff --git a/java/com/android/dialer/dialpadview/res/values-vi/strings.xml b/java/com/android/dialer/dialpadview/res/values-vi/strings.xml index e68a0b5da..5022e79ec 100644 --- a/java/com/android/dialer/dialpadview/res/values-vi/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-vi/strings.xml @@ -22,4 +22,18 @@ "phím lùi" "cộng" "thư thoại" + "quay số" + "Để gọi thư thoại, trước tiên hãy tắt Chế độ trên máy bay." + "Để thiết lập thư thoại, hãy đi tới Menu > Cài đặt." + "Thêm tạm dừng 2 giây" + "Thêm chờ" + "Sử dụng bàn phím số cảm ứng có âm" + "Quay lại cuộc gọi đang thực hiện" + "Thêm cuộc gọi" + "IMEI" + "MEID" + "Đang tải từ thẻ SIM…" + "Danh bạ trên thẻ SIM" + "Gọi %s" + "Không thể gọi số này" diff --git a/java/com/android/dialer/dialpadview/res/values-zh-rCN/strings.xml b/java/com/android/dialer/dialpadview/res/values-zh-rCN/strings.xml index 262362dd9..8d50e8ec3 100644 --- a/java/com/android/dialer/dialpadview/res/values-zh-rCN/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-zh-rCN/strings.xml @@ -22,4 +22,18 @@ "删除" "加号" "语音邮件" + "拨号" + "要呼叫语音信箱,请先关闭飞行模式。" + "要设置语音信箱,请转到“菜单”>“设置”。" + "加入 2 秒暂停时间" + "加入等待时间" + "使用按键式键盘" + "返回正在进行的通话" + "添加通话" + "IMEI" + "MEID" + "正从 SIM 卡中加载…" + "SIM 卡联系人" + "拨打 %s" + "无法拨打此号码" diff --git a/java/com/android/dialer/dialpadview/res/values-zh-rHK/strings.xml b/java/com/android/dialer/dialpadview/res/values-zh-rHK/strings.xml index e7bc60682..320217b3e 100644 --- a/java/com/android/dialer/dialpadview/res/values-zh-rHK/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-zh-rHK/strings.xml @@ -22,4 +22,18 @@ "退格鍵" "加號" "留言" + "撥號" + "如要致電留言信箱,請先關閉飛行模式。" + "如要設定留言信箱,請移至 [選單] > [設定]。" + "新增 2 秒暫停功能" + "新增插播" + "使用觸控音頻鍵盤" + "返回進行中的通話" + "新增通話" + "IMEI" + "MEID" + "正在從 SIM 卡載入…" + "SIM 卡聯絡人" + "撥打 %s" + "無法撥打此號碼" diff --git a/java/com/android/dialer/dialpadview/res/values-zh-rTW/strings.xml b/java/com/android/dialer/dialpadview/res/values-zh-rTW/strings.xml index 21d2b8b1b..b87048f3c 100644 --- a/java/com/android/dialer/dialpadview/res/values-zh-rTW/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-zh-rTW/strings.xml @@ -22,4 +22,18 @@ "Backspace 鍵" "加號" "語音留言" + "撥號" + "如要撥打語音信箱聽取留言,請先關閉飛航模式。" + "如要設定語音信箱,請依序前往 [選單] > [設定]。" + "新增 2 秒暫停功能" + "新增插播功能" + "使用觸控音鍵盤" + "返回進行中的通話" + "新增通話" + "IMEI" + "MEID" + "正在從 SIM 卡載入…" + "SIM 卡聯絡人" + "撥打 %s" + "無法撥打這個號碼" diff --git a/java/com/android/dialer/dialpadview/res/values-zu/strings.xml b/java/com/android/dialer/dialpadview/res/values-zu/strings.xml index 458781f4a..6b1c5f5d7 100644 --- a/java/com/android/dialer/dialpadview/res/values-zu/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values-zu/strings.xml @@ -22,4 +22,18 @@ "i-backspace" "hlanganisa" "ivoyisimeyili" + "dayela" + "Ukushayela i-voicemail, vala kuqala imodi Yendiza." + "Ukuya emyalezweni wephimbo, yana ezisethweni > zemenyu." + "Faka ukumisa okwesikhashana kwamasekhondi angu-2" + "Yengeza ukulinda" + "Sebenzisa ikhiphedi yethoni yokuthinta" + "Buyela kukholi eqhubekayo" + "Engeza ikholi" + "IMEI" + "MEID" + "Ilayisha kusuka ekhadini le-SIM..." + "Othintana nabo bekhadi le-SIM" + "Shayela %s" + "Ayikwazi ukushayela le nombolo" diff --git a/java/com/android/dialer/dialpadview/res/values/colors.xml b/java/com/android/dialer/dialpadview/res/values/colors.xml index d27468db7..8bea35710 100644 --- a/java/com/android/dialer/dialpadview/res/values/colors.xml +++ b/java/com/android/dialer/dialpadview/res/values/colors.xml @@ -17,11 +17,9 @@ #fcfcfc - #ececec @color/dialer_theme_color #737373 #333 - #dadada #89000000 #919191 diff --git a/java/com/android/dialer/dialpadview/res/values/dimens.xml b/java/com/android/dialer/dialpadview/res/values/dimens.xml index 210c81697..1e5880a3e 100644 --- a/java/com/android/dialer/dialpadview/res/values/dimens.xml +++ b/java/com/android/dialer/dialpadview/res/values/dimens.xml @@ -16,7 +16,7 @@ - 36sp + 36dp 12sp 23sp 36sp @@ -25,17 +25,13 @@ 1dp 13dp - 18sp - 5dp 34sp 24sp 60dp 16dp 8dp 10dp - 3dp - 2dp - 2dp + 18dp 100dp 8dp 14dp @@ -45,4 +41,7 @@ 10dp + + + 10dp diff --git a/java/com/android/dialer/dialpadview/res/values/strings.xml b/java/com/android/dialer/dialpadview/res/values/strings.xml index 920e6e25c..b3e92f1d9 100644 --- a/java/com/android/dialer/dialpadview/res/values/strings.xml +++ b/java/com/android/dialer/dialpadview/res/values/strings.xml @@ -14,7 +14,7 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License --> - + * # @@ -50,4 +50,61 @@ --> voicemail + + dial + + + To call voicemail, first turn off Airplane mode. + + + To set up voicemail, go to Menu > Settings. + + + Add 2-sec pause + Add wait + + + Use touch tone keypad + + + Return to call in progress + + + Add call + + + IMEI + + + MEID + + + Loading from SIM card\u2026 + + + SIM card contacts + + + Call %s + + + + + + + Can\'t call this number -- cgit v1.2.3