summaryrefslogtreecommitdiffstats
path: root/src-ambient/com/android/phone/common/incall/utils
diff options
context:
space:
mode:
Diffstat (limited to 'src-ambient/com/android/phone/common/incall/utils')
-rw-r--r--src-ambient/com/android/phone/common/incall/utils/CallMethodFilters.java94
-rw-r--r--src-ambient/com/android/phone/common/incall/utils/CallMethodUtils.java220
-rw-r--r--src-ambient/com/android/phone/common/incall/utils/MimeTypeUtils.java143
3 files changed, 457 insertions, 0 deletions
diff --git a/src-ambient/com/android/phone/common/incall/utils/CallMethodFilters.java b/src-ambient/com/android/phone/common/incall/utils/CallMethodFilters.java
new file mode 100644
index 0000000..9a576b7
--- /dev/null
+++ b/src-ambient/com/android/phone/common/incall/utils/CallMethodFilters.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2016 The CyanogenMod 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.phone.common.incall.utils;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.text.TextUtils;
+
+import com.android.phone.common.ambient.AmbientDataSubscription;
+import com.android.phone.common.incall.CallMethodInfo;
+import com.android.phone.common.incall.api.ApiHelper;
+import com.cyanogen.ambient.plugin.PluginStatus;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Helper for filtering call method objects in various ways.
+ */
+public class CallMethodFilters extends ApiHelper {
+
+ /**
+ * Helper method for subscribed clients to remove any item that is not enabled from the hashmap
+ * @param input HashMap returned from a broadcast
+ * @param output HashMap with only enabled items
+ */
+ public static void removeDisabled(HashMap<ComponentName, CallMethodInfo> input,
+ HashMap<ComponentName, CallMethodInfo> output) {
+ for (Map.Entry<ComponentName, CallMethodInfo> entry : input.entrySet()) {
+ ComponentName key = entry.getKey();
+ CallMethodInfo value = entry.getValue();
+
+ if (value.mStatus == PluginStatus.ENABLED) {
+ output.put(key, value);
+ }
+ }
+ }
+
+ public static HashMap<ComponentName, CallMethodInfo> getAllEnabledCallMethods(
+ AmbientDataSubscription<CallMethodInfo> instance) {
+ HashMap<ComponentName, CallMethodInfo> cmi = new HashMap<>();
+ removeDisabled(instance.getPluginInfo(), cmi);
+ return cmi;
+ }
+
+ public static HashMap<ComponentName, CallMethodInfo> getAllEnabledAndHiddenCallMethods(
+ AmbientDataSubscription<CallMethodInfo> instance) {
+ HashMap<ComponentName, CallMethodInfo> cmi = new HashMap<>();
+ for (Map.Entry<ComponentName, CallMethodInfo> entry : instance.getPluginInfo().entrySet()) {
+ ComponentName key = entry.getKey();
+ CallMethodInfo value = entry.getValue();
+
+ if (value.mStatus == PluginStatus.ENABLED || value.mStatus == PluginStatus.HIDDEN) {
+ cmi.put(key, value);
+ }
+ }
+ return cmi;
+ }
+
+ public static CallMethodInfo getMethodForMimeType(String mimeType, boolean enableOnly,
+ AmbientDataSubscription<CallMethodInfo> instance) {
+
+ CallMethodInfo targetEntry = null;
+ for (CallMethodInfo entry : instance.getPluginInfo().values()) {
+ // During development, mimetype sometimes came back null
+ // find out why mimetype may be null
+ if (!TextUtils.isEmpty(entry.mMimeType)) {
+ if (enableOnly && entry.mStatus != PluginStatus.ENABLED) {
+ continue;
+ }
+ if (entry.mMimeType.equals(mimeType)) {
+ targetEntry = entry;
+ break;
+ }
+ }
+ }
+ return targetEntry;
+ }
+
+}
diff --git a/src-ambient/com/android/phone/common/incall/utils/CallMethodUtils.java b/src-ambient/com/android/phone/common/incall/utils/CallMethodUtils.java
new file mode 100644
index 0000000..d29f805
--- /dev/null
+++ b/src-ambient/com/android/phone/common/incall/utils/CallMethodUtils.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2016 The CyanogenMod 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.phone.common.incall.utils;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.telecom.PhoneAccount;
+import android.telecom.PhoneAccountHandle;
+import android.telecom.TelecomManager;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+import android.util.ArrayMap;
+import android.util.Log;
+
+import android.widget.Toast;
+import com.android.contacts.common.model.AccountTypeManager;
+import com.android.contacts.common.model.account.AccountType;
+import com.android.contacts.common.model.account.AccountWithDataSet;
+import com.android.phone.common.R;
+import com.android.phone.common.incall.CallMethodInfo;
+import com.android.phone.common.incall.StartInCallCallReceiver;
+import com.cyanogen.ambient.incall.extension.StatusCodes;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static com.cyanogen.ambient.incall.util.InCallHelper.NO_COLOR;
+
+/**
+ * Basic Utils for call method modifications
+ */
+public class CallMethodUtils {
+
+ private final static String TAG = CallMethodUtils.class.getSimpleName();
+ private final static boolean DEBUG = false;
+
+ public final static String PREF_SPINNER_COACHMARK_SHOW = "pref_spinner_coachmark_shown";
+ public final static String PREF_LAST_ENABLED_PROVIDER = "pref_last_enabled_provider";
+ public final static String PREF_INTERNATIONAL_CALLS = "pref_international_calls";
+ public final static String PREF_WIFI_CALL = "pref_wifi_call";
+
+ public static CallMethodInfo getDefaultSimInfo(Context context) {
+ final TelecomManager telecomMgr =
+ (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE);
+ PhoneAccountHandle handle =
+ telecomMgr.getDefaultOutgoingPhoneAccount(PhoneAccount.SCHEME_TEL);
+ if (handle == null) {
+ return null;
+ }
+ return phoneToCallMethod(context, handle);
+ }
+
+ public static List<CallMethodInfo> getSimInfoList(Context context) {
+ final TelecomManager telecomMgr =
+ (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE);
+ final List<PhoneAccountHandle> accountHandles = telecomMgr.getCallCapablePhoneAccounts();
+ ArrayList<CallMethodInfo> callMethodInfoList = new ArrayList<>();
+ for (PhoneAccountHandle accountHandle : accountHandles) {
+ CallMethodInfo info = phoneToCallMethod(context, accountHandle);
+ if (info != null) {
+ callMethodInfoList.add(info);
+ }
+ }
+ return callMethodInfoList;
+ }
+
+ private static String getPhoneAccountName(Context context, PhoneAccount phoneAccount,
+ int slotId) {
+ if (phoneAccount == null) {
+ // Slot IDs are zero based
+ return context.getString(R.string.call_method_spinner_item_unknown_sim, slotId + 1);
+ } else if (phoneAccount.getLabel() != null) {
+ return phoneAccount.getLabel().toString();
+ }
+ return null;
+ }
+
+ private static int getPhoneAccountColor(SubscriptionInfo info) {
+ if (info != null) {
+ return info.getIconTint();
+ } else {
+ return NO_COLOR;
+ }
+ }
+
+ private static CallMethodInfo phoneToCallMethod(Context context,
+ PhoneAccountHandle phoneAccountHandle) {
+ final SubscriptionManager subMgr = (SubscriptionManager) context
+ .getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
+ final TelecomManager telecomMgr =
+ (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE);
+ final TelephonyManager telephonyMgr =
+ (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
+ PhoneAccount phoneAccount = telecomMgr.getPhoneAccount(phoneAccountHandle);
+
+ if (phoneAccount == null) {
+ return null;
+ }
+
+ CallMethodInfo callMethodInfo = new CallMethodInfo();
+
+ callMethodInfo.mComponent = phoneAccountHandle.getComponentName();
+ callMethodInfo.mId = phoneAccountHandle.getId();
+ callMethodInfo.mUserHandle = phoneAccountHandle.getUserHandle();
+ callMethodInfo.mSubId = telephonyMgr.getSubIdForPhoneAccount(phoneAccount);
+ callMethodInfo.mSlotId = SubscriptionManager.getSlotId(callMethodInfo.mSubId);
+ callMethodInfo.mName = getPhoneAccountName(context, phoneAccount, callMethodInfo.mSlotId);
+ callMethodInfo.mColor =
+ getPhoneAccountColor(subMgr.getActiveSubscriptionInfo(callMethodInfo.mSubId));
+ callMethodInfo.mIsInCallProvider = false;
+
+ final int simState = telephonyMgr.getSimState(callMethodInfo.mSlotId);
+ if ((simState == TelephonyManager.SIM_STATE_ABSENT) ||
+ (simState == TelephonyManager.SIM_STATE_UNKNOWN)) {
+ return null;
+ }
+
+ return callMethodInfo;
+ }
+
+ /*
+ * Look up the currently logged in plugin account in case plugin fails to return a valid
+ * account handle
+ */
+ public static String lookupAccountHandle(Context context, String targetAccountType) {
+ // Gather account handles logged into the device as a backup, in case
+ // plugins fail to return the account handle even when it reports its
+ // state as authenticated
+ AccountTypeManager accountTypes = AccountTypeManager.getInstance(context);
+ List<AccountWithDataSet> accounts = accountTypes.getAccounts(false);
+ ArrayMap<String, String> accountMap = new ArrayMap<>();
+
+ for (AccountWithDataSet account : accounts) {
+ AccountType accountType =
+ accountTypes.getAccountType(account.type, account.dataSet);
+ if (accountType.isExtension() && !account.hasData(context)) {
+ // Hide extensions with no raw_contacts.
+ continue;
+ }
+ if (DEBUG) {
+ Log.d(TAG, "account.type: " + account.type + "account.name: " + account.name);
+ }
+ // currently only handle one account per account type use case
+ accountMap.put(account.type, account.name);
+ }
+ return accountMap.containsKey(targetAccountType) ? accountMap.get(targetAccountType) : "";
+ }
+
+ /*
+ * Return if the plugin is a soft logged-out state (authenticated is false and there's still
+ * an account saved in account manager)
+ */
+ public static boolean isSoftLoggedOut(Context context, CallMethodInfo cmi) {
+ return (!cmi.mIsAuthenticated && !TextUtils.isEmpty(lookupAccountHandle(context,
+ cmi.mAccountType)));
+ }
+
+
+ public static StartInCallCallReceiver getVoIPResultReceiver(Context context, CallMethodInfo cmi,
+ String originCode) {
+ return getVoIPResultReceiver(context, cmi, originCode, null);
+ }
+
+ public static StartInCallCallReceiver getVoIPResultReceiver(final Context context,
+ final CallMethodInfo cmi, final String originCode,
+ final StartInCallCallReceiver.InCallCallListener listener) {
+
+ StartInCallCallReceiver svcrr =
+ new StartInCallCallReceiver(new Handler(Looper.getMainLooper()));
+
+ svcrr.setReceiver(new StartInCallCallReceiver.Receiver() {
+
+ @Override
+ public void onReceiveResult(int resultCode, Bundle resultData) {
+ if (DEBUG) Log.i(TAG, "Got Start VoIP Call result callback code = " + resultCode);
+
+ switch (resultCode) {
+ case StatusCodes.StartCall.CALL_FAILURE_INSUFFICIENT_CREDITS:
+ case StatusCodes.StartCall.CALL_FAILURE_INVALID_NUMBER:
+ case StatusCodes.StartCall.CALL_FAILURE_TIMEOUT:
+ case StatusCodes.StartCall.CALL_FAILURE_UNAUTHENTICATED:
+ case StatusCodes.StartCall.CALL_FAILURE:
+ String text = context.getResources()
+ .getString(R.string.invalid_number_text);
+ text = String.format(text, cmi.mName);
+ Toast.makeText(context, text, Toast.LENGTH_LONG).show();
+ break;
+ default:
+ Log.i(TAG, "Nothing to do for this Start VoIP Call resultcode = "
+ + resultCode);
+ break;
+ }
+ if (listener != null) {
+ listener.onResult(resultCode);
+ }
+ }
+
+ });
+
+ return svcrr;
+ }
+}
diff --git a/src-ambient/com/android/phone/common/incall/utils/MimeTypeUtils.java b/src-ambient/com/android/phone/common/incall/utils/MimeTypeUtils.java
new file mode 100644
index 0000000..8f0c260
--- /dev/null
+++ b/src-ambient/com/android/phone/common/incall/utils/MimeTypeUtils.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2016 The CyanogenMod 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.phone.common.incall.utils;
+
+import android.content.Context;
+
+import com.android.phone.common.ambient.AmbientDataSubscription;
+import com.android.phone.common.incall.CallMethodInfo;
+import com.android.phone.common.incall.api.ApiHelper;
+import com.cyanogen.ambient.plugin.PluginStatus;
+import com.google.common.base.Joiner;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import static com.android.phone.common.ambient.TypedPendingResult.GENERAL_MIME_TYPE;
+import static com.android.phone.common.ambient.TypedPendingResult.IM_MIME_TYPE;
+import static com.android.phone.common.ambient.TypedPendingResult.VIDEO_MIME_TYPE;
+
+
+/**
+ * Class with logic to get mimes and mime types.
+ */
+public class MimeTypeUtils extends ApiHelper {
+
+ private static String getMimeTypes(AmbientDataSubscription<CallMethodInfo> instance,
+ boolean enabledOnly, int mimeID) {
+
+ String mimeTypes = "";
+ List<String> mimeTypesList = new ArrayList<>();
+ for (CallMethodInfo cmi : instance.getPluginInfo().values()) {
+ String mimeType = null;
+ switch(mimeID) {
+ case GENERAL_MIME_TYPE:
+ mimeType = cmi.mMimeType;
+ break;
+ case IM_MIME_TYPE:
+ mimeType = cmi.mVideoCallableMimeType;
+ break;
+ case VIDEO_MIME_TYPE:
+ mimeType = cmi.mImMimeType;
+ }
+
+ if (!enabledOnly) {
+ mimeTypesList.add(mimeType);
+ continue;
+ }
+
+ if (cmi.mStatus == PluginStatus.ENABLED) {
+ mimeTypesList.add(mimeType);
+ }
+ }
+
+ if (!mimeTypesList.isEmpty()) {
+ mimeTypes = Joiner.on(",").skipNulls().join(mimeTypesList);
+ }
+ return mimeTypes;
+ }
+
+
+ /**
+ * A few items need a list of mime types in a comma delimited list. Since we are already
+ * querying all the plugins. We can easily build this list ahead of time.
+ *
+ * Items that require this should subscribe and grab this updated list when needed.
+ * @return string of all (not limited to enabled) mime types
+ */
+ public static String getAllMimeTypes(AmbientDataSubscription<CallMethodInfo> instance) {
+ return getMimeTypes(instance, false, GENERAL_MIME_TYPE);
+ }
+
+ /**
+ * A few items need a list of mime types in a comma delimited list. Since we are already
+ * querying all the plugins. We can easily build this list ahead of time.
+ *
+ * Items that require this should subscribe and grab this updated list when needed.
+ * @return string of enabled mime types
+ */
+ public static String getAllEnabledMimeTypes(AmbientDataSubscription<CallMethodInfo> instance) {
+ return getMimeTypes(instance, true, GENERAL_MIME_TYPE);
+ }
+
+ /**
+ * A few items need a list of video callable mime types in a comma delimited list.
+ * Since we are already querying all the plugins. We can easily build this list ahead of time.
+ *
+ * Items that require this should subscribe and grab this updated list when needed.
+ * @return string of enabled video callable mime types
+ */
+ public static String getAllEnabledVideoCallableMimeTypes(
+ AmbientDataSubscription<CallMethodInfo> instance) {
+ return getMimeTypes(instance, true, VIDEO_MIME_TYPE);
+ }
+
+ public static String getAllEnabledImMimeTypes(
+ AmbientDataSubscription<CallMethodInfo> instance) {
+ return getMimeTypes(instance, true, IM_MIME_TYPE);
+ }
+
+ public static Set<String> getAllEnabledVideoImMimeSet(
+ AmbientDataSubscription<CallMethodInfo> instance) {
+ String[] videoMimes = getAllEnabledVideoCallableMimeTypes(instance).split(",");
+ String[] imMimes = getAllEnabledImMimeTypes(instance).split(",");
+ HashSet<String> mimeSet = new HashSet<>();
+
+ if (videoMimes != null) {
+ mimeSet.addAll(Arrays.asList(videoMimes));
+ }
+ if (imMimes != null) {
+ mimeSet.addAll(Arrays.asList(imMimes));
+ }
+ return mimeSet;
+ }
+
+ public static Set<String> getAllEnabledVoiceMimeSet(
+ AmbientDataSubscription<CallMethodInfo> instance) {
+ String[] mimes = getAllEnabledMimeTypes(instance).split(",");
+ HashSet<String> mimeSet = new HashSet<>();
+ if (mimes != null) {
+ mimeSet.addAll(Arrays.asList(mimes));
+ }
+ return mimeSet;
+ }
+
+
+}