From c63122fda124c28721cacca96facb930cd9dd074 Mon Sep 17 00:00:00 2001 From: wangqi Date: Mon, 20 Nov 2017 11:09:02 -0800 Subject: Add more Cequint provider and signature check. This change expands Cequint Caller ID to more provider name and adds signature check to avoid fake provider fraud. Bug: 69061848,69310040 Test: CequintPackageUtilsTest PiperOrigin-RevId: 176386836 Change-Id: I02bb3f67d74f7cccbf99b0967e517595c6c2033b --- .../android/dialer/oem/CequintCallerIdManager.java | 39 +-- .../android/dialer/oem/CequintPackageUtils.java | 286 +++++++++++++++++++++ .../dialer/oem/res/values/motorola_config.xml | 6 + 3 files changed, 314 insertions(+), 17 deletions(-) create mode 100644 java/com/android/dialer/oem/CequintPackageUtils.java diff --git a/java/com/android/dialer/oem/CequintCallerIdManager.java b/java/com/android/dialer/oem/CequintCallerIdManager.java index df624e06a..48a5985ce 100644 --- a/java/com/android/dialer/oem/CequintCallerIdManager.java +++ b/java/com/android/dialer/oem/CequintCallerIdManager.java @@ -46,17 +46,10 @@ public class CequintCallerIdManager { private static final String CONFIG_CALLER_ID_ENABLED = "config_caller_id_enabled"; - private static final String PROVIDER_NAME = "com.cequint.ecid"; - - private static final Uri CONTENT_URI = Uri.parse("content://" + PROVIDER_NAME + "/lookup"); - private static final int CALLER_ID_LOOKUP_USER_PROVIDED_CID = 0x0001; private static final int CALLER_ID_LOOKUP_SYSTEM_PROVIDED_CID = 0x0002; private static final int CALLER_ID_LOOKUP_INCOMING_CALL = 0x0020; - private static final Uri CONTENT_URI_FOR_INCALL = - Uri.parse("content://" + PROVIDER_NAME + "/incalllookup"); - private static final String[] EMPTY_PROJECTION = new String[] {}; // Column names in Cequint provider. @@ -72,7 +65,7 @@ public class CequintCallerIdManager { private static final String DISPLAY_NAME = "cid_pDisplayName"; private static boolean hasAlreadyCheckedCequintCallerIdPackage; - private static boolean isCequintCallerIdEnabled; + private static String cequintProviderAuthority; // TODO(wangqi): Revisit it and maybe remove it if it's not necessary. private final ConcurrentHashMap callLogCache; @@ -98,16 +91,20 @@ public class CequintCallerIdManager { } if (!hasAlreadyCheckedCequintCallerIdPackage) { hasAlreadyCheckedCequintCallerIdPackage = true; - isCequintCallerIdEnabled = false; - try { - context.getPackageManager().getPackageInfo(PROVIDER_NAME, 0); - isCequintCallerIdEnabled = true; - } catch (PackageManager.NameNotFoundException e) { - isCequintCallerIdEnabled = false; + String[] providerNames = context.getResources().getStringArray(R.array.cequint_providers); + PackageManager packageManager = context.getPackageManager(); + for (String provider : providerNames) { + if (CequintPackageUtils.isCallerIdInstalled(packageManager, provider)) { + cequintProviderAuthority = provider; + LogUtil.i( + "CequintCallerIdManager.isCequintCallerIdEnabled", "found provider: %s", provider); + return true; + } } + LogUtil.d("CequintCallerIdManager.isCequintCallerIdEnabled", "no provider found"); } - return isCequintCallerIdEnabled; + return cequintProviderAuthority != null; } public static CequintCallerIdManager createInstanceForCallLog() { @@ -133,7 +130,7 @@ public class CequintCallerIdManager { flag |= CALLER_ID_LOOKUP_USER_PROVIDED_CID; } String[] flags = {cnapName, String.valueOf(flag)}; - return lookup(context, CONTENT_URI_FOR_INCALL, number, flags); + return lookup(context, getIncallLookupUri(), number, flags); } @WorkerThread @@ -150,7 +147,7 @@ public class CequintCallerIdManager { CequintCallerIdContact cequintCallerIdContact = lookup( context, - CONTENT_URI, + getLookupUri(), PhoneNumberUtils.stripSeparators(number), new String[] {"system"}); if (cequintCallerIdContact != null) { @@ -267,6 +264,14 @@ public class CequintCallerIdManager { return geoDescription; } + private static Uri getLookupUri() { + return Uri.parse("content://" + cequintProviderAuthority + "/lookup"); + } + + private static Uri getIncallLookupUri() { + return Uri.parse("content://" + cequintProviderAuthority + "/incalllookup"); + } + private CequintCallerIdManager() { callLogCache = new ConcurrentHashMap<>(); } diff --git a/java/com/android/dialer/oem/CequintPackageUtils.java b/java/com/android/dialer/oem/CequintPackageUtils.java new file mode 100644 index 000000000..66c900e8b --- /dev/null +++ b/java/com/android/dialer/oem/CequintPackageUtils.java @@ -0,0 +1,286 @@ +/* + * Copyright (C) 2017 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.oem; + +import android.annotation.SuppressLint; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.content.pm.ProviderInfo; +import android.content.pm.Signature; +import android.support.annotation.Nullable; +import com.android.dialer.common.LogUtil; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** Utility class to verify Cequint package information. */ +final class CequintPackageUtils { + + private static final int SIGNED_1024 = 0; + private static final int SIGNED_2048 = 1; + private static final int SIGNED_VZW = 2; + private static final int SIGNED_SPRINT = 3; + + // Known Caller Name ID fingerprints + private static final List callerIdFingerprints = new ArrayList<>(); + + static { + // 1024 signed + callerIdFingerprints.add( + SIGNED_1024, + new byte[] { + 0x1A, + 0x0C, + (byte) 0xF8, + (byte) 0x8D, + 0x5B, + (byte) 0xE2, + 0x6A, + (byte) 0xED, + 0x50, + (byte) 0x85, + (byte) 0xFE, + (byte) 0x88, + (byte) 0xA0, + (byte) 0x9E, + (byte) 0xEC, + 0x25, + 0x1E, + (byte) 0xCA, + 0x16, + (byte) 0x97, + 0x50, + (byte) 0xDA, + 0x21, + (byte) 0xCC, + 0x18, + (byte) 0xC9, + (byte) 0x98, + (byte) 0xAF, + 0x26, + (byte) 0xCD, + 0x06, + 0x71 + }); + // 2048 signed + callerIdFingerprints.add( + SIGNED_2048, + new byte[] { + (byte) 0xCA, + 0x2F, + (byte) 0xAE, + (byte) 0xF4, + 0x09, + (byte) 0xEF, + 0x4C, + 0x79, + (byte) 0xF8, + 0x4C, + (byte) 0xD8, + (byte) 0x97, + (byte) 0xBF, + 0x1A, + 0x15, + 0x0F, + (byte) 0xF0, + 0x5E, + 0x54, + 0x74, + (byte) 0xB6, + 0x4A, + (byte) 0xCA, + (byte) 0xCD, + 0x05, + 0x7E, + 0x1E, + (byte) 0x98, + (byte) 0xC6, + 0x1F, + 0x5C, + 0x45 + }); + // VZW Package + callerIdFingerprints.add( + SIGNED_VZW, + new byte[] { + (byte) 0xE6, + 0x7A, + 0x0E, + (byte) 0xB0, + 0x76, + 0x4E, + (byte) 0xC3, + 0x28, + (byte) 0xB7, + (byte) 0xC1, + 0x1B, + 0x1B, + (byte) 0xD0, + (byte) 0x84, + 0x28, + (byte) 0xA6, + 0x16, + (byte) 0xD9, + (byte) 0xF3, + (byte) 0xEB, + (byte) 0xB0, + 0x20, + (byte) 0xA7, + (byte) 0xD8, + (byte) 0xDF, + 0x14, + 0x72, + (byte) 0x81, + 0x4C, + 0x13, + (byte) 0xF3, + (byte) 0xC9 + }); + + // Sprint Package + callerIdFingerprints.add( + SIGNED_SPRINT, + new byte[] { + 0x1A, + (byte) 0xBA, + (byte) 0xA2, + (byte) 0x84, + 0x0C, + 0x61, + (byte) 0x96, + 0x09, + (byte) 0x91, + 0x5E, + (byte) 0x91, + (byte) 0x95, + 0x3D, + 0x29, + 0x3C, + (byte) 0x90, + (byte) 0xEC, + (byte) 0xB4, + (byte) 0x89, + 0x1D, + (byte) 0xC0, + (byte) 0xB1, + 0x23, + 0x58, + (byte) 0x98, + (byte) 0xEB, + (byte) 0xE6, + (byte) 0xD4, + 0x09, + (byte) 0xE5, + (byte) 0x8E, + (byte) 0x9D + }); + } + + @SuppressLint("PackageManagerGetSignatures") + static boolean isCallerIdInstalled( + @Nullable PackageManager packageManager, @Nullable String authority) { + if (packageManager == null) { + LogUtil.i("CequintPackageUtils.isCallerIdInstalled", "failed to get PackageManager!"); + return false; + } + + ProviderInfo providerInfo = + packageManager.resolveContentProvider(authority, PackageManager.GET_META_DATA); + if (providerInfo == null) { + LogUtil.d( + "CequintPackageUtils.isCallerIdInstalled", + "no content provider with '%s' authority", + authority); + return false; + } + + String packageName = providerInfo.packageName; + if (packageName == null) { + LogUtil.w("CequintPackageUtils.isCallerIdInstalled", "can't get valid package name."); + return false; + } + + LogUtil.i( + "CequintPackageUtils.isCallerIdInstalled", + "content provider package name : " + packageName); + + try { + PackageInfo packageInfo = + packageManager.getPackageInfo(packageName, PackageManager.GET_SIGNATURES); + + Signature[] signatures = packageInfo.signatures; + if (signatures.length > 1) { + LogUtil.w( + "CequintPackageUtils.isCallerIdInstalled", "package has more than one signature."); + return false; + } + byte[] sha256Bytes = getSHA256(signatures[0].toByteArray()); + + for (int i = 0; i < callerIdFingerprints.size(); i++) { + if (Arrays.equals(callerIdFingerprints.get(i), sha256Bytes)) { + LogUtil.i( + "CequintPackageUtils.isCallerIdInstalled", + "this is %s Caller Name ID APK.", + getApkTypeString(i)); + return true; + } + } + } catch (PackageManager.NameNotFoundException e) { + LogUtil.e( + "CequintPackageUtils.isCallerIdInstalled", + "couldn't find package info for the package: %s", + packageName, + e); + } + LogUtil.w( + "CequintPackageUtils.isCallerIdInstalled", + "signature check failed for package: %s", + packageName); + return false; + } + + // Returns sha256 hash of the signature + @Nullable + private static byte[] getSHA256(byte[] sig) { + MessageDigest digest; + try { + digest = MessageDigest.getInstance("SHA256", "BC"); + } catch (NoSuchAlgorithmException | NoSuchProviderException e) { + LogUtil.e("CequintPackageUtils.getSHA256", "", e); + return null; + } + + digest.update(sig); + return digest.digest(); + } + + private static String getApkTypeString(int index) { + switch (index) { + case SIGNED_1024: + return "1024-signed"; + case SIGNED_2048: + return "2048-signed"; + case SIGNED_VZW: + return "VZWPackage"; + case SIGNED_SPRINT: + default: + return "SprintPackage"; + } + } +} diff --git a/java/com/android/dialer/oem/res/values/motorola_config.xml b/java/com/android/dialer/oem/res/values/motorola_config.xml index 46e7a16b6..ba451e715 100644 --- a/java/com/android/dialer/oem/res/values/motorola_config.xml +++ b/java/com/android/dialer/oem/res/values/motorola_config.xml @@ -74,4 +74,10 @@ @string/motorola_hidden_menu_intent + + + + com.cequint.ecid + \ No newline at end of file -- cgit v1.2.3 From 28415da446a2a4d5748296a70ee515ad639346ed Mon Sep 17 00:00:00 2001 From: yueg Date: Mon, 20 Nov 2017 11:10:06 -0800 Subject: Cancel missed calls in call history when needed. Including when: - onStop() - switching tabs Also move old CallLogActivityTest to espresso directory. Test: CallLogActivityTest PiperOrigin-RevId: 176387019 Change-Id: Icbb77747882c8a5e35595557baa6917a4dc674b6 --- .../dialer/app/calllog/CallLogActivity.java | 50 ++++++++++++++++++++-- .../dialer/app/calllog/CallLogFragment.java | 10 +++++ 2 files changed, 57 insertions(+), 3 deletions(-) diff --git a/java/com/android/dialer/app/calllog/CallLogActivity.java b/java/com/android/dialer/app/calllog/CallLogActivity.java index c83d992ee..4b65ed934 100644 --- a/java/com/android/dialer/app/calllog/CallLogActivity.java +++ b/java/com/android/dialer/app/calllog/CallLogActivity.java @@ -21,6 +21,7 @@ import android.content.Intent; import android.os.Bundle; import android.provider.CallLog; import android.provider.CallLog.Calls; +import android.support.annotation.VisibleForTesting; import android.support.design.widget.Snackbar; import android.support.v13.app.FragmentPagerAdapter; import android.support.v4.view.ViewPager; @@ -33,6 +34,7 @@ import com.android.contacts.common.list.ViewPagerTabs; import com.android.dialer.app.DialtactsActivity; import com.android.dialer.app.R; import com.android.dialer.calldetails.CallDetailsActivity; +import com.android.dialer.common.Assert; import com.android.dialer.constants.ActivityRequestCodes; import com.android.dialer.database.CallLogQueryHandler; import com.android.dialer.logging.Logger; @@ -47,15 +49,17 @@ import com.android.dialer.util.ViewUtil; public class CallLogActivity extends TransactionSafeActivity implements ViewPager.OnPageChangeListener { - private static final int TAB_INDEX_ALL = 0; - private static final int TAB_INDEX_MISSED = 1; + @VisibleForTesting static final int TAB_INDEX_ALL = 0; + @VisibleForTesting static final int TAB_INDEX_MISSED = 1; private static final int TAB_INDEX_COUNT = 2; private ViewPager mViewPager; private ViewPagerTabs mViewPagerTabs; private ViewPagerAdapter mViewPagerAdapter; private CallLogFragment mAllCallsFragment; + private CallLogFragment mMissedCallsFragment; private String[] mTabTitles; private boolean mIsResumed; + private int selectedPageIndex; @Override protected void onCreate(Bundle savedInstanceState) { @@ -78,6 +82,7 @@ public class CallLogActivity extends TransactionSafeActivity startingTab = TAB_INDEX_MISSED; } } + selectedPageIndex = startingTab; mTabTitles = new String[TAB_INDEX_COUNT]; mTabTitles[0] = getString(R.string.call_log_all_title); @@ -116,6 +121,16 @@ public class CallLogActivity extends TransactionSafeActivity super.onPause(); } + @Override + protected void onStop() { + if (!isChangingConfigurations() && mViewPager != null) { + // Make sure current index != selectedPageIndex + selectedPageIndex = -1; + updateMissedCalls(mViewPager.getCurrentItem()); + } + super.onStop(); + } + @Override public boolean onCreateOptionsMenu(Menu menu) { final MenuInflater inflater = getMenuInflater(); @@ -160,6 +175,8 @@ public class CallLogActivity extends TransactionSafeActivity @Override public void onPageSelected(int position) { + updateMissedCalls(position); + selectedPageIndex = position; if (mIsResumed) { sendScreenViewForChildFragment(); } @@ -182,6 +199,26 @@ public class CallLogActivity extends TransactionSafeActivity return position; } + private void updateMissedCalls(int position) { + if (position == selectedPageIndex) { + return; + } + switch (getRtlPosition(position)) { + case TAB_INDEX_ALL: + if (mAllCallsFragment != null) { + mAllCallsFragment.markMissedCallsAsReadAndRemoveNotifications(); + } + break; + case TAB_INDEX_MISSED: + if (mMissedCallsFragment != null) { + mMissedCallsFragment.markMissedCallsAsReadAndRemoveNotifications(); + } + break; + default: + throw Assert.createIllegalStateFailException("Invalid position: " + position); + } + } + @Override public void onBackPressed() { PerformanceReport.recordClick(UiAction.Type.PRESS_ANDROID_BACK_BUTTON); @@ -216,8 +253,15 @@ public class CallLogActivity extends TransactionSafeActivity @Override public Object instantiateItem(ViewGroup container, int position) { final CallLogFragment fragment = (CallLogFragment) super.instantiateItem(container, position); - if (getRtlPosition(position) == TAB_INDEX_ALL) { + switch (getRtlPosition(position)) { + case TAB_INDEX_ALL: mAllCallsFragment = fragment; + break; + case TAB_INDEX_MISSED: + mMissedCallsFragment = fragment; + break; + default: + throw Assert.createIllegalStateFailException("Invalid position: " + position); } return fragment; } diff --git a/java/com/android/dialer/app/calllog/CallLogFragment.java b/java/com/android/dialer/app/calllog/CallLogFragment.java index 5e8da032b..6910f1918 100644 --- a/java/com/android/dialer/app/calllog/CallLogFragment.java +++ b/java/com/android/dialer/app/calllog/CallLogFragment.java @@ -20,6 +20,7 @@ import static android.Manifest.permission.READ_CALL_LOG; import android.app.Activity; import android.app.Fragment; +import android.app.KeyguardManager; import android.content.ContentResolver; import android.content.Context; import android.content.pm.PackageManager; @@ -602,6 +603,15 @@ public class CallLogFragment extends Fragment mDisplayUpdateHandler.removeMessages(EVENT_UPDATE_DISPLAY); } + /** Mark all missed calls as read if Keyguard not locked and possible. */ + void markMissedCallsAsReadAndRemoveNotifications() { + if (mCallLogQueryHandler != null + && !getContext().getSystemService(KeyguardManager.class).isKeyguardLocked()) { + mCallLogQueryHandler.markMissedCallsAsRead(); + CallLogNotificationsService.cancelAllMissedCalls(getContext()); + } + } + @CallSuper public void onVisible() { LogUtil.enterBlock("CallLogFragment.onPageSelected"); -- cgit v1.2.3 From 26dbd5e7eeabe7929e5ac639faa2969272f6f202 Mon Sep 17 00:00:00 2001 From: mdooley Date: Mon, 20 Nov 2017 11:26:47 -0800 Subject: Fixing verizon TOS text This was caused by cl/176065849 where we added a per carrier check to see if transcription is supported. new screenshot: https://drive.google.com/open?id=0B9o_KvtLkcuINkJ0R0JPTUZWSlpDMmlaRFdEUnJkY3pyTmxR Bug: 67457582 Test: manual and updated unit test PiperOrigin-RevId: 176389716 Change-Id: Ib41607a0ec6e9b40092d32fe055db80b6f9f8301 --- .../dialer/app/voicemail/error/VoicemailTosMessageCreator.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/java/com/android/dialer/app/voicemail/error/VoicemailTosMessageCreator.java b/java/com/android/dialer/app/voicemail/error/VoicemailTosMessageCreator.java index b7c8ed721..2787320fa 100644 --- a/java/com/android/dialer/app/voicemail/error/VoicemailTosMessageCreator.java +++ b/java/com/android/dialer/app/voicemail/error/VoicemailTosMessageCreator.java @@ -403,10 +403,6 @@ public class VoicemailTosMessageCreator { } private CharSequence getVvmDialerTos() { - if (!isVoicemailTranscriptionEnabled()) { - return ""; - } - return context.getString(R.string.dialer_terms_and_conditions_for_verizon_1_0); } -- cgit v1.2.3