Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 297a33dc authored by android-build-team Robot's avatar android-build-team Robot
Browse files

release-request-b1bd0f0e-f3c4-414e-8f22-d9235831ae23-for-git_oc-mr1-release-40...

release-request-b1bd0f0e-f3c4-414e-8f22-d9235831ae23-for-git_oc-mr1-release-4099045 snap-temp-L41300000074003051

Change-Id: Ib46cef1e17966fd2e99d105fa959fbb5915ba661
parents bd98582f 7340606d
Loading
Loading
Loading
Loading
+75 −0
Original line number Diff line number Diff line
@@ -19,18 +19,23 @@ package com.android.contacts;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.PersistableBundle;
import android.telecom.PhoneAccount;
import android.telecom.PhoneAccountHandle;
import android.telecom.TelecomManager;
import android.telecom.VideoProfile;
import android.telephony.CarrierConfigManager;
import android.telephony.PhoneNumberUtils;
import android.text.TextUtils;
import android.util.Log;

import com.android.contacts.compat.CompatUtils;
import com.android.contacts.compat.PhoneAccountSdkCompat;
import com.android.contacts.util.PermissionsUtil;
import com.android.contacts.util.PhoneNumberHelper;
import com.android.contactsbind.FeedbackHelper;
import com.android.contactsbind.experiments.Flags;
import com.android.phone.common.PhoneConstants;

import java.util.List;
@@ -61,6 +66,14 @@ public class CallUtil {
     */
    public static final int VIDEO_CALLING_PRESENCE = 2;

    /** {@link PhoneAccount#EXTRA_SUPPORTS_VIDEO_CALLING_FALLBACK} */
    private static final String EXTRA_SUPPORTS_VIDEO_CALLING_FALLBACK =
            "android.telecom.extra.SUPPORTS_VIDEO_CALLING_FALLBACK";

    /** {@link CarrierConfigManager#CONFIG_ALLOW_VIDEO_CALLING_FALLBACK} */
    private static final String CONFIG_ALLOW_VIDEO_CALLING_FALLBACK =
            "allow_video_calling_fallback_bool";

    /**
     * Return an Intent for making a phone call. Scheme (e.g. tel, sip) will be determined
     * automatically.
@@ -210,4 +223,66 @@ public class CallUtil {
        }

    }

    /**
     * Determines if we're able to use Tachyon as a fallback for video calling.
     *
     * @param context The context.
     * @return {@code true} if there exists a call capable phone account which supports using a
     * fallback for video calling, the carrier configuration supports a fallback, and the
     * experiment for using a fallback is enabled. Otherwise {@code false} is returned.
     */
    public static boolean isTachyonEnabled(Context context) {
        // Need to be able to read phone state, and be on at least N to check PhoneAccount extras.
        if (!PermissionsUtil.hasPermission(context, android.Manifest.permission.READ_PHONE_STATE)
                || !CompatUtils.isNCompatible()) {
            return false;
        }
        TelecomManager telecommMgr = (TelecomManager)
                context.getSystemService(Context.TELECOM_SERVICE);
        if (telecommMgr == null) {
            return false;
        }
        try {
            List<PhoneAccountHandle> accountHandles = telecommMgr.getCallCapablePhoneAccounts();
            for (PhoneAccountHandle accountHandle : accountHandles) {
                PhoneAccount account = telecommMgr.getPhoneAccount(accountHandle);
                if (account == null) {
                    continue;
                }
                // Check availability for the device config.
                final Bundle accountExtras = account.getExtras();
                final boolean deviceEnabled = accountExtras != null && accountExtras.getBoolean(
                        EXTRA_SUPPORTS_VIDEO_CALLING_FALLBACK);
                if (Log.isLoggable(TAG, Log.DEBUG)) {
                    Log.d(TAG, "Device video fallback config: " + deviceEnabled);
                }

                // Check availability from carrier config.
                final PersistableBundle carrierConfig = context.getSystemService(
                        CarrierConfigManager.class).getConfig();
                final boolean carrierEnabled =
                        carrierConfig != null && carrierConfig.getBoolean(
                                CONFIG_ALLOW_VIDEO_CALLING_FALLBACK);
                if (Log.isLoggable(TAG, Log.DEBUG)) {
                    Log.d(TAG, "Carrier video fallback config: " + carrierEnabled);
                }

                // Check experiment value.
                final boolean experimentEnabled = Flags.getInstance().getBoolean(
                        Experiments.QUICK_CONTACT_VIDEO_CALL);
                if (Log.isLoggable(TAG, Log.DEBUG)) {
                    Log.d(TAG, "Experiment video fallback config: " + experimentEnabled);
                }

                // All three checks above must be true to enable Tachyon calling.
                return deviceEnabled && carrierEnabled && experimentEnabled;
            }
            return false;
        } catch (SecurityException e) {
            FeedbackHelper.sendFeedback(context, TAG,
                    "Security exception when getting call capable phone accounts", e);
            return false;
        }
    }
}
+4 −0
Original line number Diff line number Diff line
@@ -297,6 +297,7 @@ public class DynamicShortcuts {
        final ShortcutInfo.Builder builder = new ShortcutInfo.Builder(mContext, id)
                .setIntent(action)
                .setIcon(icon)
                .setExtras(extras)
                .setDisabledMessage(mContext.getString(R.string.dynamic_shortcut_disabled_message));

        setLabel(builder, label);
@@ -305,6 +306,9 @@ public class DynamicShortcuts {

    public ShortcutInfo getQuickContactShortcutInfo(long id, String lookupKey, String displayName) {
        final ShortcutInfo.Builder builder = builderForContactShortcut(id, lookupKey, displayName);
        if (builder == null) {
            return null;
        }
        addIconForContact(id, lookupKey, displayName, builder);
        return builder.build();
    }
+9 −5
Original line number Diff line number Diff line
@@ -276,6 +276,9 @@ public class ShortcutIntentBuilder {
    private void createContactShortcutIntent(Uri contactUri, String contentType, String displayName,
            String lookupKey, byte[] bitmapData) {
        Intent intent = null;
        if (TextUtils.isEmpty(displayName)) {
            displayName = mContext.getResources().getString(R.string.missing_name);
        }
        if (BuildCompat.isAtLeastO()) {
            final long contactId = ContentUris.parseId(contactUri);
            final ShortcutManager sm = (ShortcutManager)
@@ -283,12 +286,11 @@ public class ShortcutIntentBuilder {
            final DynamicShortcuts dynamicShortcuts = new DynamicShortcuts(mContext);
            final ShortcutInfo shortcutInfo = dynamicShortcuts.getQuickContactShortcutInfo(
                    contactId, lookupKey, displayName);
            if (shortcutInfo != null) {
                intent = sm.createShortcutResultIntent(shortcutInfo);
            }
        final Drawable drawable = getPhotoDrawable(bitmapData, displayName, lookupKey);
        if (TextUtils.isEmpty(displayName)) {
            displayName = mContext.getResources().getString(R.string.missing_name);
        }
        final Drawable drawable = getPhotoDrawable(bitmapData, displayName, lookupKey);

        final Intent shortcutIntent = ImplicitIntentsUtil.getIntentForQuickContactLauncherShortcut(
                mContext, contactUri);
@@ -346,8 +348,10 @@ public class ShortcutIntentBuilder {
            final DynamicShortcuts dynamicShortcuts = new DynamicShortcuts(mContext);
            final ShortcutInfo shortcutInfo = dynamicShortcuts.getActionShortcutInfo(
                    id, displayName, shortcutIntent, compatAdaptiveIcon.toIcon());
            if (shortcutInfo != null) {
                intent = sm.createShortcutResultIntent(shortcutInfo);
            }
        }

        intent = intent == null ? new Intent() : intent;
        // This will be non-null in O and above.
+31 −22
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ import android.content.IntentFilter;
import android.content.Loader;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutManager;
import android.content.res.Resources;
import android.graphics.Bitmap;
@@ -105,7 +106,6 @@ import com.android.contacts.ContactSaveService;
import com.android.contacts.ContactsActivity;
import com.android.contacts.ContactsUtils;
import com.android.contacts.DynamicShortcuts;
import com.android.contacts.Experiments;
import com.android.contacts.NfcHandler;
import com.android.contacts.R;
import com.android.contacts.ShortcutIntentBuilder;
@@ -176,7 +176,6 @@ import com.android.contacts.widget.MultiShrinkScroller;
import com.android.contacts.widget.MultiShrinkScroller.MultiShrinkScrollerListener;
import com.android.contacts.widget.QuickContactImageView;
import com.android.contactsbind.HelpUtils;
import com.android.contactsbind.experiments.Flags;

import com.google.common.collect.Lists;

@@ -1457,6 +1456,7 @@ public class QuickContactActivity extends ContactsActivity {
        Trace.beginSection("Build data items map");

        final Map<String, List<DataItem>> dataItemsMap = new HashMap<>();
        final boolean tachyonEnabled = CallUtil.isTachyonEnabled(this);

        for (RawContact rawContact : data.getRawContacts()) {
            for (DataItem dataItem : rawContact.getDataItems()) {
@@ -1466,6 +1466,7 @@ public class QuickContactActivity extends ContactsActivity {
                if (mimeType == null) continue;

                if (!MIMETYPE_TACHYON.equals(mimeType)) {
                    // Only validate non-Tachyon mimetypes.
                    final AccountType accountType = rawContact.getAccountType(this);
                    final DataKind dataKind = AccountTypeManager.getInstance(this)
                            .getKindOrFallback(accountType, mimeType);
@@ -1477,6 +1478,9 @@ public class QuickContactActivity extends ContactsActivity {
                            dataKind));

                    if (isMimeExcluded(mimeType) || !hasData) continue;
                } else if (!tachyonEnabled) {
                    // If tachyon isn't enabled, skip its mimetypes.
                    continue;
                }

                List<DataItem> dataItemListByType = dataItemsMap.get(mimeType);
@@ -1820,7 +1824,7 @@ public class QuickContactActivity extends ContactsActivity {
                    thirdIntent.putExtra(EXTRA_ACTION_TYPE, ActionType.VIDEOCALL);
                    thirdContentDescription =
                            res.getString(R.string.description_video_call);
                } else if (Flags.getInstance().getBoolean(Experiments.QUICK_CONTACT_VIDEO_CALL)
                } else if (CallUtil.isTachyonEnabled(context)
                        && ((PhoneDataItem) dataItem).isTachyonReachable()) {
                    thirdIcon = res.getDrawable(R.drawable.quantum_ic_videocam_vd_theme_24);
                    thirdAction = Entry.ACTION_INTENT;
@@ -1915,8 +1919,8 @@ public class QuickContactActivity extends ContactsActivity {
                    aboutCardName.value = res.getString(R.string.about_card_title);
                }
            }
        } else if (Flags.getInstance().getBoolean(Experiments.QUICK_CONTACT_VIDEO_CALL)
                && MIMETYPE_TACHYON.equals(dataItem.getMimeType())) {
        } else if (CallUtil.isTachyonEnabled(context) && MIMETYPE_TACHYON.equals(
                dataItem.getMimeType())) {
            // Skip these actions. They will be placed by the phone number.
            return null;
        } else {
@@ -2694,21 +2698,26 @@ public class QuickContactActivity extends ContactsActivity {
     * Creates a launcher shortcut with the current contact.
     */
    private void createLauncherShortcutWithContact() {
        final ShortcutIntentBuilder builder = new ShortcutIntentBuilder(this,
                new OnShortcutIntentCreatedListener() {

                    @Override
                    public void onShortcutIntentCreated(Uri uri, Intent shortcutIntent) {
        if (BuildCompat.isAtLeastO()) {
            final ShortcutManager shortcutManager = (ShortcutManager)
                    getSystemService(SHORTCUT_SERVICE);
            final DynamicShortcuts shortcuts =
                    new DynamicShortcuts(QuickContactActivity.this);
                            shortcutManager.requestPinShortcut(
                                    shortcuts.getQuickContactShortcutInfo(
                                            mContactData.getId(), mContactData.getLookupKey(),
                                            mContactData.getDisplayName()), null);
            String displayName = mContactData.getDisplayName();
            if (displayName == null) {
                displayName = getString(R.string.missing_name);
            }
            final ShortcutInfo shortcutInfo = shortcuts.getQuickContactShortcutInfo(
                    mContactData.getId(), mContactData.getLookupKey(), displayName);
            if (shortcutInfo != null) {
                shortcutManager.requestPinShortcut(shortcutInfo, null);
            }
        } else {
            final ShortcutIntentBuilder builder = new ShortcutIntentBuilder(this,
                    new OnShortcutIntentCreatedListener() {

                        @Override
                        public void onShortcutIntentCreated(Uri uri, Intent shortcutIntent) {
                            // Broadcast the shortcutIntent to the launcher to create a
                            // shortcut to this contact
                            shortcutIntent.setAction(ACTION_INSTALL_SHORTCUT);
@@ -2724,10 +2733,10 @@ public class QuickContactActivity extends ContactsActivity {
                            Toast.makeText(QuickContactActivity.this, toastMessage,
                                    Toast.LENGTH_SHORT).show();
                        }
                    }
                    });
            builder.createContactShortcutIntent(mContactData.getLookupUri());
        }
    }

    private boolean isShortcutCreatable() {
        if (mContactData == null || mContactData.isUserProfile() ||