summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Bird <sbird@cyngn.com>2016-03-31 15:03:11 -0700
committerErica Chang <echang@cyngn.com>2016-04-26 22:38:42 -0700
commitecc708d3c1417b60f316a0387d17f2cf4c67c2b1 (patch)
treefefb202fcf37bb15e301a821b206e02cf0a0e16e
parent33beb0a0b887dbfa9797f7fa97f3cd715bb71a74 (diff)
downloadandroid_packages_apps_PhoneCommon-ecc708d3c1417b60f316a0387d17f2cf4c67c2b1.tar.gz
android_packages_apps_PhoneCommon-ecc708d3c1417b60f316a0387d17f2cf4c67c2b1.tar.bz2
android_packages_apps_PhoneCommon-ecc708d3c1417b60f316a0387d17f2cf4c67c2b1.zip
[1/4] Refactor CallMethodHelper
Change-Id: I3b24eedffddbf0960023dc2f1429038e5353de2f
-rw-r--r--src-ambient/com/android/phone/common/ambient/AmbientConnection.java (renamed from src-ambient/ambient/AmbientConnection.java)11
-rw-r--r--src-ambient/com/android/phone/common/ambient/AmbientDataSubscription.java326
-rw-r--r--src-ambient/com/android/phone/common/ambient/SingletonHolder.java (renamed from src-ambient/ambient/SingletonHolder.java)6
-rw-r--r--src-ambient/com/android/phone/common/ambient/TypedPendingResult.java53
-rw-r--r--src-ambient/com/android/phone/common/ambient/utils/PluginUtils.java26
-rw-r--r--src-ambient/com/android/phone/common/incall/CallMethodInfo.java (renamed from src-ambient/incall/CallMethodInfo.java)92
-rw-r--r--src-ambient/com/android/phone/common/incall/CallMethodSpinnerAdapter.java (renamed from src-ambient/incall/CallMethodSpinnerAdapter.java)1
-rw-r--r--src-ambient/com/android/phone/common/incall/ContactsDataSubscription.java123
-rw-r--r--src-ambient/com/android/phone/common/incall/CreditBarHelper.java (renamed from src-ambient/incall/CreditBarHelper.java)2
-rw-r--r--src-ambient/com/android/phone/common/incall/DialerDataSubscription.java193
-rw-r--r--src-ambient/com/android/phone/common/incall/StartInCallCallReceiver.java (renamed from src/com/android/phone/common/util/StartInCallCallReceiver.java)24
-rw-r--r--src-ambient/com/android/phone/common/incall/api/ApiHelper.java38
-rw-r--r--src-ambient/com/android/phone/common/incall/api/InCallListeners.java84
-rw-r--r--src-ambient/com/android/phone/common/incall/api/InCallQueries.java230
-rw-r--r--src-ambient/com/android/phone/common/incall/api/InCallResults.java283
-rw-r--r--src-ambient/com/android/phone/common/incall/listeners/AuthenticationListenerImpl.java58
-rw-r--r--src-ambient/com/android/phone/common/incall/listeners/CallCreditListenerImpl.java53
-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.java (renamed from src-ambient/incall/CallMethodUtils.java)77
-rw-r--r--src-ambient/com/android/phone/common/incall/utils/MimeTypeUtils.java143
-rw-r--r--src-ambient/com/android/phone/common/nudge/api/ApiHelper.java31
-rw-r--r--src-ambient/com/android/phone/common/nudge/api/NudgeQueries.java55
-rw-r--r--src-ambient/com/android/phone/common/nudge/api/NudgeTypedResult.java51
-rw-r--r--src-ambient/com/android/phone/common/nudge/utils/NudgeUtils.java47
-rw-r--r--src-ambient/incall/AuthenticationListenerImpl.java27
-rw-r--r--src-ambient/incall/CallCreditListenerImpl.java28
-rw-r--r--src-ambient/incall/CallMethodHelper.java1250
27 files changed, 2043 insertions, 1363 deletions
diff --git a/src-ambient/ambient/AmbientConnection.java b/src-ambient/com/android/phone/common/ambient/AmbientConnection.java
index ed4c0c0..04fe63a 100644
--- a/src-ambient/ambient/AmbientConnection.java
+++ b/src-ambient/com/android/phone/common/ambient/AmbientConnection.java
@@ -19,7 +19,7 @@ public class AmbientConnection {
public static final SingletonHolder<AmbientApiClient, Context> CLIENT =
new SingletonHolder<AmbientApiClient, Context>() {
- private static final String TAG = "Dialer.AmbientSingletonHolder";
+ private static final String TAG = "PhoneCommon.AmbientSingletonHolder";
@Override
protected AmbientApiClient create(Context context) {
@@ -35,26 +35,26 @@ public class AmbientConnection {
new AmbientApiClient.OnConnectionFailedListener() {
@Override
public void onConnectionFailed(ConnectionResult result) {
- Log.w(TAG, "Ambient connection failed: " + result);
+ Log.w(TAG, "Connection failed: " + result);
}
});
client.registerDisconnectionListener(
new AmbientApiClient.OnDisconnectionListener() {
@Override
public void onDisconnection() {
- Log.d(TAG, "Ambient connection disconnected");
+ Log.d(TAG, "Connection disconnected");
}
});
client.registerConnectionCallbacks(
new AmbientApiClient.ConnectionCallbacks() {
@Override
public void onConnected(Bundle connectionHint) {
- Log.d(TAG, "Ambient connection established");
+ Log.d(TAG, "Connection established");
}
@Override
public void onConnectionSuspended(int cause) {
- Log.d(TAG, "Ambient connection suspended");
+ Log.d(TAG, "Connection suspended");
}
});
client.connect();
@@ -62,5 +62,4 @@ public class AmbientConnection {
}
};
-
}
diff --git a/src-ambient/com/android/phone/common/ambient/AmbientDataSubscription.java b/src-ambient/com/android/phone/common/ambient/AmbientDataSubscription.java
new file mode 100644
index 0000000..3b30ccb
--- /dev/null
+++ b/src-ambient/com/android/phone/common/ambient/AmbientDataSubscription.java
@@ -0,0 +1,326 @@
+/*
+ * 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.ambient;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.os.Handler;
+import android.util.Log;
+
+import com.cyanogen.ambient.common.api.AmbientApiClient;
+import com.cyanogen.ambient.common.api.PendingResult;
+import com.cyanogen.ambient.common.api.Result;
+import com.cyanogen.ambient.common.api.ResultCallback;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Helper method for holding and broadcasting updated plugin data
+ *
+ */
+public abstract class AmbientDataSubscription<M> {
+
+ private static final String TAG = AmbientDataSubscription.class.getSimpleName();
+ private static final boolean DEBUG = false;
+
+ // Our ambient client
+ public AmbientApiClient mClient;
+ public Context mContext;
+
+ // The handler that processes broadcasts
+ private Handler mMainHandler;
+
+ // Holder for plugin object
+ private HashMap<ComponentName, M> mPluginInfo;
+
+ private static boolean mDataHasBeenBroadcastPreviously = false;
+
+ // A list of our registered clients, who all register with the CallMethodReceiver
+ private static HashMap<String, PluginChanged> mRegisteredClients = new HashMap<>();
+
+ // A map of our components and if they have have enabled IInterface listeners. This is to keep
+ // track of if listeners should be added or removed.
+ private static HashMap<ComponentName, Boolean> mEnabledListeners = new HashMap<>();
+
+ // Wait up to 60 seconds for data to return. Mimicks what PluginBinderManager does.
+ private static final long TIMEOUT_MILLISECONDS = 60000L;
+
+ // Bootstrap is the initial callback to get your installed plugins.
+ // this is the only item that executes ASAP and has no componentname tied to it
+ public ResultCallback BOOTSTRAP = new ResultCallback<Result>() {
+
+ @Override
+ public void onResult(Result result) {
+ List<ComponentName> installedPlugins = getPluginComponents(result);
+ for (ComponentName cn : installedPlugins) {
+ ArrayList<TypedPendingResult> apiCallbacks = new ArrayList<>();
+ getPluginInfo().put(cn, getNewModObject(cn));
+ requestedModInfo(apiCallbacks, cn);
+ executeAll(apiCallbacks, cn);
+ }
+ }
+
+ };
+
+ public AmbientDataSubscription(Context context) {
+ mContext = context;
+ mClient = AmbientConnection.CLIENT.get(context);
+ mMainHandler = new Handler(context.getMainLooper());
+ mPluginInfo = new HashMap<>();
+ }
+
+ public interface PluginChanged<M> {
+ void onChanged(HashMap<ComponentName, M> pluginInfo);
+ }
+
+ /**
+ * OnPostResult is always called on the main thread (like onPostExecute in an asynctask)
+ *
+ * @param plugin The object that represents the plugin
+ * @param result the result of the resultCallback
+ * @param type the type defined by the TypedPendingResult that was sent to the apiexecutor
+ */
+ protected abstract void onPostResult(M plugin, Result result, int type);
+
+ /**
+ * Callback that gets the initial list of componentnames that are valid plugin for us to query
+ *
+ * @param result result of the initial call
+ * @return list of componentnames
+ */
+ protected abstract List<ComponentName> getPluginComponents(Result result);
+
+ /**
+ * Gets the required queries for all our plugins
+ *
+ * @param queries ArrayList for us to add TypedPendingResults to
+ * @param componentName ComponentName of the plugin we will be querying
+ */
+ protected abstract void requestedModInfo(ArrayList<TypedPendingResult> queries,
+ ComponentName componentName);
+
+
+ /**
+ * Action that takes place when a refresh is requested.
+ */
+ protected abstract void onRefreshRequested();
+
+ /**
+ * Called when dynamic items need to be refreshed. Dynamic items being things that may change
+ * over time in a plugin.
+ *
+ * @param apiCallbacks callbacks to add to the queue
+ * @param componentName of plugin that needs to be updated
+ */
+ protected abstract void onDynamicRefreshRequested(ArrayList<TypedPendingResult> apiCallbacks,
+ ComponentName componentName);
+
+ /**
+ * Methods to enable and disable listeners on a plugin
+ *
+ * @param plugin object that needs to be listened to.
+ */
+ protected abstract void enableListeners(M plugin);
+ protected abstract void disableListeners(M plugin);
+
+ /**
+ * Gets a new plugin object
+ *
+ * @param componentName of the plugin
+ * @return M object
+ */
+ protected abstract M getNewModObject(ComponentName componentName);
+
+ private void enablePluginListeners(ComponentName cn) {
+ if (!mEnabledListeners.containsKey(cn) || !mEnabledListeners.get(cn)) {
+ M plugin = getPluginIfExists(cn);
+ if (plugin != null) {
+ enableListeners(plugin);
+ mEnabledListeners.put(cn, true);
+ }
+
+ }
+ }
+
+ private void disablePluginListeners(ComponentName cn) {
+ if (mEnabledListeners.containsKey(cn) && mEnabledListeners.get(cn)) {
+ M plugin = getPluginIfExists(cn);
+ disableListeners(plugin);
+ mEnabledListeners.put(cn, false);
+ }
+ }
+
+ /**
+ * Broadcasts mModInfo to all registered clients on the Main thread.
+ */
+ public void broadcast() {
+ mMainHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ if (DEBUG) Log.d(TAG, "broadcast");
+ for (PluginChanged client : mRegisteredClients.values()) {
+ client.onChanged(mPluginInfo);
+ }
+ }
+ });
+ }
+
+ /***
+ * Registers the client, on register returns boolean if plugin info is already collected
+ * and the initial broadcast has been sent.
+ *
+ * @param id unique string for the client
+ * @param cmr client receiver
+ * @return boolean isempty
+ */
+ public boolean subscribe(String id, PluginChanged cmr) {
+ mRegisteredClients.put(id, cmr);
+ if (DEBUG) Log.v("TAG", "subscribed: " + id);
+ return mDataHasBeenBroadcastPreviously;
+ }
+
+ /**
+ * Unsubscribes the client. All clients must unsubscribe when the client ends.
+ *
+ * @param id of the client to remove
+ */
+ public void unsubscribe(String id) {
+ mRegisteredClients.remove(id);
+ if (mRegisteredClients.isEmpty()) {
+ for (ComponentName cn : mPluginInfo.keySet()) {
+ disablePluginListeners(cn);
+ }
+ }
+ }
+
+ /**
+ * Refreshes certain items that can constantly change.
+ */
+ public void refreshDynamicItems() {
+ for (ComponentName cn : mPluginInfo.keySet()) {
+ ArrayList<TypedPendingResult> apiCallbacks = new ArrayList<>();
+ onDynamicRefreshRequested(apiCallbacks, cn);
+ executeAll(apiCallbacks, cn);
+ }
+ }
+
+ private void executeAll(final ArrayList<TypedPendingResult> apiCallbacks,
+ final ComponentName componentName) {
+
+ final ArrayList<PendingResult> pendingResults = new ArrayList<>();
+
+ for (final TypedPendingResult pendingResult : apiCallbacks) {
+ pendingResult.setResultCallback(new ResultCallback() {
+ @Override
+ public void onResult(Result result) {
+ pendingResults.remove(pendingResult.mPendingResult);
+ if (result == null) {
+ // Our plugin failed to make this call, log out what and why
+ Log.e(TAG, "Result from: " + componentName.getPackageName() + " failed");
+ } else {
+ if (result.getStatus().isSuccess()) {
+ M plugin = getPluginIfExists(componentName);
+ onPostResult(plugin, result, pendingResult.mType);
+
+ // check to see if our onPostResult removed the plugin.
+ if (!getPluginInfo().containsKey(componentName)) {
+ // Our plugin no longer exists for some reason, clear other callbacks
+ // and broadcast changes.
+ for (PendingResult pr : pendingResults) {
+ pr.cancel();
+ }
+ pendingResults.clear();
+ }
+ } else if (result.getStatus().isCanceled()) {
+ // Our plugin was found invalid or no longer exists.
+ Log.e(TAG, "Queries to: " + componentName.getPackageName()
+ + " are cancelled");
+ } else {
+ Log.e(TAG, "Query to: " + componentName.getPackageName() + " "
+ + result.getClass().getSimpleName() + " failed. Code: " +
+ result.getStatus().getStatusMessage());
+ }
+ }
+ maybeBroadcastToSubscribers(pendingResults);
+
+ }
+ }, TIMEOUT_MILLISECONDS, TimeUnit.MILLISECONDS);
+
+ // Add items that we've already added to our queue for so we can cancel them if
+ // need be. Set resultcallback will return instantly but onResult will not.
+ // So we can use this as our "counter" to determine if we should broadcast
+ pendingResults.add(pendingResult.mPendingResult);
+ }
+ enablePluginListeners(componentName);
+ }
+
+ public void refresh() {
+ onRefreshRequested();
+ }
+
+ public static boolean infoReady() {
+ return mDataHasBeenBroadcastPreviously;
+ }
+
+ private void maybeBroadcastToSubscribers(ArrayList<PendingResult> apiCallbacks) {
+ maybeBroadcastToSubscribers(apiCallbacks, false);
+ }
+
+ /**
+ * Broadcast to subscribers once we know we've gathered all our data. Do not do this until we
+ * have everything we need for sure.
+ *
+ * This method is called after every callback from ModCore. We will keep track of all of
+ * the callbacks, once we have accounted for all callbacks from all plugins, we can go ahead
+ * and update subscribers.
+ *
+ * @param apiCallbacks hashmap of our callbacks and pendingresults
+ * @param critical marks this call as critical to shortcircut our general broadcast and
+ * broadcast right away.
+ */
+ private void maybeBroadcastToSubscribers(ArrayList<PendingResult> apiCallbacks,
+ boolean critical) {
+
+ if (apiCallbacks.isEmpty() || critical) {
+ // we are on the last item or we are a critical item. broadcast updated hashmap
+ broadcast();
+ // We don't want to tell providers that our main data has already been broadcast
+ // if it's just a critical broadcast to prevent extra work from our subscribers
+ // once our long running calls are broadcast then this will be true.
+ if (!critical) {
+ mDataHasBeenBroadcastPreviously = true;
+ }
+ }
+ }
+
+ /**
+ * In order to speed up the process we make calls for providers that may be invalid
+ * To prevent this, make sure every resultcallback uses this before filling in the hashmap.
+ * @param cn componentname
+ * @return M if valid, otherwise null
+ */
+ public M getPluginIfExists(ComponentName cn) {
+ return getPluginInfo().get(cn);
+ }
+
+ public HashMap<ComponentName, M> getPluginInfo() {
+ return mPluginInfo;
+ }
+}
diff --git a/src-ambient/ambient/SingletonHolder.java b/src-ambient/com/android/phone/common/ambient/SingletonHolder.java
index 52890fc..bca6023 100644
--- a/src-ambient/ambient/SingletonHolder.java
+++ b/src-ambient/com/android/phone/common/ambient/SingletonHolder.java
@@ -46,5 +46,11 @@ public abstract class SingletonHolder<E, I> {
return mInstance;
}
+ public final boolean isCreated() {
+ synchronized (LOCK) {
+ return mInstance != null;
+ }
+ }
+
protected abstract E create(I initializer);
}
diff --git a/src-ambient/com/android/phone/common/ambient/TypedPendingResult.java b/src-ambient/com/android/phone/common/ambient/TypedPendingResult.java
new file mode 100644
index 0000000..783b519
--- /dev/null
+++ b/src-ambient/com/android/phone/common/ambient/TypedPendingResult.java
@@ -0,0 +1,53 @@
+package com.android.phone.common.ambient;
+
+import com.cyanogen.ambient.common.api.PendingResult;
+import com.cyanogen.ambient.common.api.ResultCallback;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * PendingResult wrapped with a Type
+ *
+ * Some queries return the same pending result type. We need a way to differentiate these items to
+ * know how to process them.
+ */
+public class TypedPendingResult {
+
+ PendingResult mPendingResult;
+ int mType;
+
+ // None should be used when a unique Result will be returned from our ResultCallback.
+ public static final int NONE = 0;
+
+ // 1 - 1000 Reserved for INCALL API
+ public static final int GENERAL_MIME_TYPE = 1;
+ public static final int IM_MIME_TYPE = 2;
+ public static final int VIDEO_MIME_TYPE = 3;
+
+ public static final int SETTINGS_INTENT = 4;
+ public static final int CREDIT_INTENT = 5;
+ public static final int LOGIN_INTENT = 6;
+ public static final int DEFAULT_DIRECTORY_SEARCH_INTENT = 7;
+
+ public static final int GENERAL_DATA = 8;
+ public static final int STATUS = 9;
+ public static final int AUTHENTICATION = 10;
+ public static final int CREDIT_INFO = 11;
+ public static final int ACCOUNT_HANDLE = 12;
+ public static final int HINT_TEXT = 13;
+
+ // 1001 - 2000 Reserved for Nudges
+ public static final int INCALL_CREDIT_NUDGE = 1001;
+ public static final int INCALL_CONTACT_CARD_LOGIN = 1002;
+ public static final int INCALL_CONTACT_CARD_DOWNLOAD = 1003;
+ public static final int INCALL_CONTACT_FRAGMENT_LOGIN = 1004;
+
+ public TypedPendingResult(PendingResult pendingResult, int type) {
+ this.mPendingResult = pendingResult;
+ this.mType = type;
+ }
+
+ public void setResultCallback(ResultCallback resultCallback, long length, TimeUnit unit) {
+ this.mPendingResult.setResultCallback(resultCallback, length, unit);
+ }
+}
diff --git a/src-ambient/com/android/phone/common/ambient/utils/PluginUtils.java b/src-ambient/com/android/phone/common/ambient/utils/PluginUtils.java
new file mode 100644
index 0000000..471457b
--- /dev/null
+++ b/src-ambient/com/android/phone/common/ambient/utils/PluginUtils.java
@@ -0,0 +1,26 @@
+package com.android.phone.common.ambient.utils;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.util.Log;
+
+/**
+ * Utilites for Plugins
+ */
+public class PluginUtils {
+
+ private static final String TAG = PluginUtils.class.getSimpleName();
+
+ public static Resources getPluginResources(Context context, ComponentName componentName) {
+ PackageManager packageManager = context.getPackageManager();
+ try {
+ return packageManager.getResourcesForApplication(componentName.getPackageName());
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.e(TAG, "Plugin isn't installed: " + componentName.flattenToShortString());
+ return null;
+ }
+ }
+
+}
diff --git a/src-ambient/incall/CallMethodInfo.java b/src-ambient/com/android/phone/common/incall/CallMethodInfo.java
index 7c6ec96..cbc5242 100644
--- a/src-ambient/incall/CallMethodInfo.java
+++ b/src-ambient/com/android/phone/common/incall/CallMethodInfo.java
@@ -29,9 +29,10 @@ import android.telephony.SubscriptionManager;
import android.text.TextUtils;
import android.util.Log;
import com.android.phone.common.ambient.AmbientConnection;
-import com.android.phone.common.incall.CallMethodHelper.InCallCallListener;
import com.android.phone.common.R;
-import com.android.phone.common.util.StartInCallCallReceiver;
+import com.android.phone.common.incall.listeners.AuthenticationListenerImpl;
+import com.android.phone.common.incall.listeners.CallCreditListenerImpl;
+import com.android.phone.common.incall.utils.CallMethodUtils;
import com.cyanogen.ambient.incall.InCallServices;
import com.cyanogen.ambient.incall.extension.CreditBalance;
import com.cyanogen.ambient.incall.extension.CreditInfo;
@@ -54,6 +55,7 @@ public class CallMethodInfo {
public int mSubId;
public int mColor;
public int mStatus;
+ public boolean mIsInCallProvider;
public boolean mIsAuthenticated;
public String mMimeType;
public String mVideoCallableMimeType;
@@ -62,7 +64,6 @@ public class CallMethodInfo {
public String mCreditButtonText;
public String mT9HintDescriptionNoCreditOrSub;
public String mT9HintDescriptionHasCreditOrSub;
- public PendingIntent mSettingsIntent;
/* Plugin's simple brand icon (24dp x 24dp)
Expected format: Vector Drawable (.xml)
2 colors allowed. */
@@ -85,58 +86,44 @@ public class CallMethodInfo {
Expected format: Vector Drawable (.xml)
1 color allowed. */
public Drawable mLoginIcon;
- /* Plugin's first action icon (24dp x 24dp)
- This icon is used in conjunction with pluginActionOneTitle.
+ /* Plugin's video call action icon (24dp x 24dp)
Expected format: Vector Drawable (.xml)
- 2 colors allowed. */
- public Drawable mActionOneIcon;
- /* Plugin's second action icon (24dp x 24dp)
- This icon is used in conjunction with pluginActionTwoTitle.
+ 1 color allowed. */
+ public Drawable mVideoIcon;
+ /* Plugin's IM action icon (24dp x 24dp)
Expected format: Vector Drawable (.xml)
- 2 colors allowed. */
- public Drawable mActionTwoIcon;
- public String mActionOneText;
- public String mActionTwoText;
- public boolean mIsInCallProvider;
- public PendingIntent mManageCreditIntent;
+ 1 color allowed. */
+ public Drawable mImIcon;
+ /* Plugin's voice call action icon (24dp x 24dp)
+ Expected format: Vector Drawable (.xml)
+ 1 color allowed. */
+ public Drawable mVoiceIcon;
public CreditInfo mProviderCreditInfo;
public float mCreditWarn = 0.0f;
+ private int mCurrencyAmount;
+ private CallCreditListenerImpl mCreditListener;
+ public PendingIntent mManageCreditIntent;
public PendingIntent mLoginIntent;
public PendingIntent mDefaultDirectorySearchIntent; // empty contact Uri
public PendingIntent mDirectorySearchIntent;
public PendingIntent mInviteIntent;
+ public PendingIntent mSettingsIntent;
+ private static CallMethodInfo sEmergencyCallMethod;
+ private AuthenticationListenerImpl mAuthListener;
public String mAccountType;
- private int mCurrencyAmount;
+ public String mDependentPackage;
+ public String mLoginSubtitle;
public String mAccountHandle;
+ public int mLoginIconId; // resource ID
public int mBrandIconId; // resource ID
- public int mLoginIconId;
-
- public ComponentName mNudgeComponent;
- public String mLoginSubtitle;
- // Contact login nudge
- public boolean mLoginNudgeEnable;
- public String mLoginNudgeTitle;
- public String mLoginNudgeSubtitle;
- public String mLoginNudgeActionText;
// Contact install nudge
public boolean mInstallNudgeEnable;
- public String mInstallNudgeTitle;
public String mInstallNudgeSubtitle;
public String mInstallNudgeActionText;
- public String mDependentPackage;
- /* Plugin's IM action icon (24dp x 24dp)
- Expected format: Vector Drawable (.xml)
- 1 color allowed. */
- public Drawable mImIcon;
- /* Plugin's video call action icon (24dp x 24dp)
- Expected format: Vector Drawable (.xml)
- 1 color allowed. */
- public Drawable mVideoIcon;
- /* Plugin's voice call action icon (24dp x 24dp)
- Expected format: Vector Drawable (.xml)
- 1 color allowed. */
- public Drawable mVoiceIcon;
- private static CallMethodInfo sEmergencyCallMethod;
+ // Contact login nudge
+ public boolean mLoginNudgeEnable;
+ public String mLoginNudgeSubtitle;
+ public String mLoginNudgeActionText;
@Override
public int hashCode() {
@@ -212,7 +199,7 @@ public class CallMethodInfo {
}
public void placeCall(String origin, String number, Context c, boolean isVideoCall, boolean
- forcePSTN, InCallCallListener listener) {
+ forcePSTN, StartInCallCallReceiver.InCallCallListener listener) {
placeCall(origin, number, c, isVideoCall, forcePSTN, null, listener);
}
@@ -222,10 +209,11 @@ public class CallMethodInfo {
}
public void placeCall(String origin, String number, Context c, boolean isVideoCall,
- boolean forcePSTN, String numberMimeType, InCallCallListener listener) {
+ boolean forcePSTN, String numberMimeType,
+ StartInCallCallReceiver.InCallCallListener listener) {
StartInCallCallReceiver svcrr
- = CallMethodHelper.getVoIPResultReceiver(this, origin, listener);
+ = CallMethodUtils.getVoIPResultReceiver(c, this, origin, listener);
StartCallRequest request = new StartCallRequest(number, origin, 0, svcrr);
if (isVideoCall) {
@@ -244,7 +232,6 @@ public class CallMethodInfo {
}
public String getCreditsDescriptionText(Resources r) {
- String ret = null;
CreditInfo ci = this.mProviderCreditInfo;
List<SubscriptionInfo> subscriptionInfos = ci.subscriptions;
@@ -350,4 +337,21 @@ public class CallMethodInfo {
}
return hintText;
}
+
+ public CallCreditListenerImpl getCreditListener() {
+ return mCreditListener;
+ }
+
+ public AuthenticationListenerImpl getAuthListener() {
+ return mAuthListener;
+ }
+
+ public void setCreditListener(CallCreditListenerImpl creditListener) {
+ mCreditListener = creditListener;
+ }
+
+ public void setAuthListener(AuthenticationListenerImpl authListener) {
+ mAuthListener = authListener;
+ }
+
}
diff --git a/src-ambient/incall/CallMethodSpinnerAdapter.java b/src-ambient/com/android/phone/common/incall/CallMethodSpinnerAdapter.java
index c3a61d3..cb3a8fe 100644
--- a/src-ambient/incall/CallMethodSpinnerAdapter.java
+++ b/src-ambient/com/android/phone/common/incall/CallMethodSpinnerAdapter.java
@@ -41,6 +41,7 @@ import static com.cyanogen.ambient.incall.util.InCallHelper.NO_COLOR;
public class CallMethodSpinnerAdapter extends ArrayAdapter<CallMethodInfo>
implements SpinnerAdapter {
+
private static final String TAG = CallMethodSpinnerAdapter.class.getSimpleName();
public static final int POSITION_UNKNOWN = -1;
diff --git a/src-ambient/com/android/phone/common/incall/ContactsDataSubscription.java b/src-ambient/com/android/phone/common/incall/ContactsDataSubscription.java
new file mode 100644
index 0000000..2b38b1e
--- /dev/null
+++ b/src-ambient/com/android/phone/common/incall/ContactsDataSubscription.java
@@ -0,0 +1,123 @@
+/*
+ * 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;
+
+import android.content.ComponentName;
+import android.content.Context;
+
+import com.android.phone.common.ambient.SingletonHolder;
+import com.android.phone.common.ambient.TypedPendingResult;
+import com.android.phone.common.incall.api.InCallListeners;
+import com.android.phone.common.incall.api.InCallQueries;
+import com.android.phone.common.nudge.api.NudgeQueries;
+import com.cyanogen.ambient.discovery.util.NudgeKey;
+import com.cyanogen.ambient.incall.extension.InCallContactInfo;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Set;
+
+public class ContactsDataSubscription extends DialerDataSubscription {
+
+ public ContactsDataSubscription(Context context) {
+ super(context);
+ }
+
+ private static final SingletonHolder<ContactsDataSubscription, Context> sInstance =
+ new SingletonHolder<ContactsDataSubscription, Context>() {
+
+ @Override
+ protected ContactsDataSubscription create(Context context) {
+ // Let's get started here.
+ return new ContactsDataSubscription(context);
+ }
+ };
+
+
+ public static ContactsDataSubscription get(Context context) {
+ return sInstance.get(context);
+ }
+
+ public static boolean isCreated() {
+ return sInstance.isCreated();
+ }
+
+ public static void init(Context context) {
+ ContactsDataSubscription.get(context).refresh();
+ }
+
+ @Override
+ public void onDynamicRefreshRequested(ArrayList<TypedPendingResult> queries,
+ ComponentName componentName) {
+ queries.add(InCallQueries.getCallMethodAuthenticated(mClient, componentName));
+ queries.add(InCallQueries.getCallMethodAccountHandle(mClient, componentName));
+ }
+
+ @Override
+ protected void enableListeners(CallMethodInfo mod) {
+ InCallListeners.enableAuthListener(this, mod);
+ }
+
+ @Override
+ protected void disableListeners(CallMethodInfo mod) {
+ InCallListeners.disableAuthListener(this, mod);
+ }
+
+ @Override
+ protected void requestedModInfo(ArrayList<TypedPendingResult> queries,
+ ComponentName componentName) {
+
+ queries.add(InCallQueries.getCallMethodInfo(mClient, componentName));
+ queries.add(InCallQueries.getCallMethodStatus(mClient, componentName));
+ queries.add(InCallQueries.getCallMethodMimeType(mClient, componentName));
+ queries.add(InCallQueries.getCallMethodVideoCallableMimeType(mClient, componentName));
+ queries.add(InCallQueries.getCallMethodAuthenticated(mClient, componentName));
+ queries.add(InCallQueries.getLoginIntent(mClient, componentName));
+ queries.add(InCallQueries.getDefaultDirectorySearchIntent(mClient, componentName));
+ queries.add(InCallQueries.getCallMethodImMimeType(mClient, componentName));
+
+ TypedPendingResult fragLogin = NudgeQueries.getNudgeConfig(mClient, mContext, componentName,
+ NudgeKey.INCALL_CONTACT_FRAGMENT_LOGIN);
+ if (fragLogin != null) {
+ queries.add(fragLogin);
+ }
+ TypedPendingResult cardLogin = NudgeQueries.getNudgeConfig(mClient, mContext, componentName,
+ NudgeKey.INCALL_CONTACT_CARD_LOGIN);
+ if (cardLogin != null) {
+ queries.add(cardLogin);
+ }
+ TypedPendingResult cardDownload = NudgeQueries.getNudgeConfig(mClient, mContext,
+ componentName, NudgeKey.INCALL_CONTACT_CARD_DOWNLOAD);
+ if (cardDownload != null) {
+ queries.add(cardDownload);
+ }
+ }
+
+ public static void refreshPendingIntents(InCallContactInfo contactInfo) {
+ // TODO: implement
+ }
+
+ public Set<String> getAllPluginComponentNames() {
+ Set<String> names = new HashSet<String>();
+ HashMap<ComponentName, CallMethodInfo> plugins = this.getPluginInfo();
+ for (ComponentName cn : plugins.keySet()) {
+ names.add(cn.flattenToString());
+ }
+ return names;
+ }
+}
diff --git a/src-ambient/incall/CreditBarHelper.java b/src-ambient/com/android/phone/common/incall/CreditBarHelper.java
index 7a8eedc..7ef7584 100644
--- a/src-ambient/incall/CreditBarHelper.java
+++ b/src-ambient/com/android/phone/common/incall/CreditBarHelper.java
@@ -6,11 +6,9 @@ import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.ImageView;
import android.widget.TextView;
import com.android.phone.common.R;
-import com.android.phone.common.incall.CallMethodInfo;
/**
* Helper method used to handle incall credit bars
diff --git a/src-ambient/com/android/phone/common/incall/DialerDataSubscription.java b/src-ambient/com/android/phone/common/incall/DialerDataSubscription.java
new file mode 100644
index 0000000..d4b6071
--- /dev/null
+++ b/src-ambient/com/android/phone/common/incall/DialerDataSubscription.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2015 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;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.util.Log;
+
+import com.android.phone.common.ambient.SingletonHolder;
+import com.android.phone.common.ambient.TypedPendingResult;
+import com.android.phone.common.incall.api.InCallListeners;
+import com.android.phone.common.incall.api.InCallQueries;
+import com.android.phone.common.incall.api.InCallResults;
+import com.android.phone.common.nudge.api.NudgeQueries;
+import com.cyanogen.ambient.common.api.Result;
+import com.cyanogen.ambient.discovery.results.BundleResult;
+import com.cyanogen.ambient.discovery.util.NudgeKey;
+import com.cyanogen.ambient.incall.extension.GetCreditInfoResult;
+import com.cyanogen.ambient.incall.results.AccountHandleResult;
+import com.cyanogen.ambient.incall.results.AuthenticationStateResult;
+import com.cyanogen.ambient.incall.results.GetCreditInfoResultResult;
+import com.cyanogen.ambient.incall.results.HintTextResultResult;
+import com.cyanogen.ambient.incall.results.InCallProviderInfoResult;
+import com.cyanogen.ambient.incall.results.InstalledPluginsResult;
+import com.cyanogen.ambient.incall.results.MimeTypeResult;
+import com.cyanogen.ambient.incall.results.PendingIntentResult;
+import com.cyanogen.ambient.incall.results.PluginStatusResult;
+import com.android.phone.common.ambient.AmbientDataSubscription;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static com.cyanogen.ambient.incall.util.InCallHelper.NO_COLOR;
+
+/**
+ * Call Method Helper - In charge of loading InCall Mod Data
+ *
+ * Fragments and Activities can subscribe to changes with subscribe.
+ */
+public class DialerDataSubscription extends AmbientDataSubscription<CallMethodInfo> {
+
+ protected static final String TAG = DialerDataSubscription.class.getSimpleName();
+
+ private static final int CALL_METHOD_TYPE = -1;
+
+ public DialerDataSubscription(Context context) {
+ super(context);
+ }
+
+ public static final SingletonHolder<DialerDataSubscription, Context> sInstance =
+ new SingletonHolder<DialerDataSubscription, Context>() {
+
+ @Override
+ protected DialerDataSubscription create(Context context) {
+ return new DialerDataSubscription(context);
+ }
+
+ };
+
+ public static DialerDataSubscription get(Context context) {
+ return sInstance.get(context);
+ }
+
+ public static boolean isCreated() {
+ return sInstance.isCreated();
+ }
+
+ public static void init(Context context) {
+ sInstance.get(context).refresh();
+ }
+
+ @Override
+ protected void onRefreshRequested() {
+ InCallQueries.updateCallPlugins(this);
+ }
+
+ @Override
+ protected List<ComponentName> getPluginComponents(Result result) {
+ return InCallResults.gotInstalledPlugins((InstalledPluginsResult)result);
+ }
+
+ @Override
+ protected void requestedModInfo(ArrayList<TypedPendingResult> queries,
+ ComponentName componentName) {
+
+ queries.add(InCallQueries.getCallMethodInfo(mClient, componentName));
+ queries.add(InCallQueries.getCallMethodStatus(mClient, componentName));
+ queries.add(InCallQueries.getCallMethodMimeType(mClient, componentName));
+ queries.add(InCallQueries.getCallMethodVideoCallableMimeType(mClient, componentName));
+ queries.add(InCallQueries.getCallMethodAuthenticated(mClient, componentName));
+ queries.add(InCallQueries.getLoginIntent(mClient, componentName));
+ queries.add(InCallQueries.getSettingsIntent(mClient, componentName));
+ queries.add(InCallQueries.getCreditInfo(mClient, componentName));
+ queries.add(InCallQueries.getHintText(mClient, componentName));
+ queries.add(InCallQueries.getManageCreditsIntent(mClient, componentName));
+
+ TypedPendingResult creditQuery = NudgeQueries.getNudgeConfig(mClient, mContext,
+ componentName, NudgeKey.INCALL_CREDIT_NUDGE);
+ if (creditQuery != null) {
+ queries.add(creditQuery);
+ }
+ }
+
+ @Override
+ protected CallMethodInfo getNewModObject(ComponentName componentName) {
+ CallMethodInfo callMethodInfo = new CallMethodInfo();
+ callMethodInfo.mComponent = componentName;
+ callMethodInfo.mSlotId = CALL_METHOD_TYPE;
+ callMethodInfo.mSubId = CALL_METHOD_TYPE;
+ callMethodInfo.mColor = NO_COLOR;
+ callMethodInfo.mIsInCallProvider = true;
+ return callMethodInfo;
+ }
+
+ @Override
+ protected void onDynamicRefreshRequested(ArrayList<TypedPendingResult> queries,
+ ComponentName componentName) {
+
+ queries.add(InCallQueries.getCallMethodAuthenticated(mClient, componentName));
+ queries.add(InCallQueries.getCreditInfo(mClient, componentName));
+ }
+
+ @Override
+ protected void enableListeners(CallMethodInfo cn) {
+ InCallListeners.enableCreditListener(this, cn);
+ InCallListeners.enableAuthListener(this, cn);
+ }
+
+ @Override
+ protected void disableListeners(CallMethodInfo cn) {
+ InCallListeners.disableCreditListener(this, cn);
+ InCallListeners.disableAuthListener(this, cn);
+ }
+
+ @Override
+ protected void onPostResult(CallMethodInfo cmi, Result r, int type) {
+ switch (type) {
+ case TypedPendingResult.GENERAL_MIME_TYPE:
+ case TypedPendingResult.IM_MIME_TYPE:
+ case TypedPendingResult.VIDEO_MIME_TYPE:
+ InCallResults.gotMimeType(cmi, (MimeTypeResult)r, type);
+ break;
+ case TypedPendingResult.SETTINGS_INTENT:
+ case TypedPendingResult.CREDIT_INTENT:
+ case TypedPendingResult.LOGIN_INTENT:
+ case TypedPendingResult.DEFAULT_DIRECTORY_SEARCH_INTENT:
+ InCallResults.gotIntent(cmi, (PendingIntentResult)r, type);
+ break;
+ case TypedPendingResult.GENERAL_DATA:
+ InCallResults.gotGeneralInfo(cmi, this, (InCallProviderInfoResult)r);
+ break;
+ case TypedPendingResult.STATUS:
+ InCallResults.gotStatus(cmi, (PluginStatusResult)r);
+ break;
+ case TypedPendingResult.AUTHENTICATION:
+ InCallResults.gotAuthenticationState(cmi, (AuthenticationStateResult)r);
+ break;
+ case TypedPendingResult.CREDIT_INFO:
+ GetCreditInfoResult gcir = ((GetCreditInfoResultResult)r).result;
+ InCallResults.gotCreditData(cmi, gcir);
+ break;
+ case TypedPendingResult.ACCOUNT_HANDLE:
+ InCallResults.gotAccountHandle(cmi, mContext, (AccountHandleResult)r);
+ break;
+ case TypedPendingResult.HINT_TEXT:
+ InCallResults.gotHintText(cmi, (HintTextResultResult)r);
+ break;
+ case TypedPendingResult.INCALL_CONTACT_CARD_DOWNLOAD:
+ case TypedPendingResult.INCALL_CONTACT_CARD_LOGIN:
+ case TypedPendingResult.INCALL_CONTACT_FRAGMENT_LOGIN:
+ case TypedPendingResult.INCALL_CREDIT_NUDGE:
+ InCallResults.gotNudgeData(mContext, cmi, (BundleResult)r, type);
+ break;
+ default:
+ Log.e(TAG, "Unhandled result type!");
+ break;
+ }
+ }
+}
diff --git a/src/com/android/phone/common/util/StartInCallCallReceiver.java b/src-ambient/com/android/phone/common/incall/StartInCallCallReceiver.java
index c2dd3c0..52bfdd0 100644
--- a/src/com/android/phone/common/util/StartInCallCallReceiver.java
+++ b/src-ambient/com/android/phone/common/incall/StartInCallCallReceiver.java
@@ -1,4 +1,20 @@
-package com.android.phone.common.util;
+/*
+ * Copyright (C) 2015 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;
import android.os.Bundle;
import android.os.Handler;
@@ -13,6 +29,10 @@ public class StartInCallCallReceiver extends ResultReceiver {
private WeakReference<Receiver> mReceiver;
+ public interface InCallCallListener {
+ void onResult(int resultCode);
+ }
+
public StartInCallCallReceiver(Handler handler) {
super(handler);
}
@@ -32,7 +52,7 @@ public class StartInCallCallReceiver extends ResultReceiver {
}
public interface Receiver {
- public void onReceiveResult(int resultCode, Bundle resultData);
+ void onReceiveResult(int resultCode, Bundle resultData);
}
public void setReceiver(Receiver receiver) {
diff --git a/src-ambient/com/android/phone/common/incall/api/ApiHelper.java b/src-ambient/com/android/phone/common/incall/api/ApiHelper.java
new file mode 100644
index 0000000..8a20aa2
--- /dev/null
+++ b/src-ambient/com/android/phone/common/incall/api/ApiHelper.java
@@ -0,0 +1,38 @@
+/*
+ * 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.api;
+
+import android.content.Context;
+import android.util.Log;
+
+import com.android.phone.common.ambient.AmbientDataSubscription;
+import com.android.phone.common.incall.DialerDataSubscription;
+import com.android.phone.common.incall.CallMethodInfo;
+import com.android.phone.common.incall.ContactsDataSubscription;
+import com.cyanogen.ambient.incall.InCallApi;
+import com.cyanogen.ambient.incall.InCallServices;
+
+/**
+ * Helper for getting instance and InCall Api
+ */
+public class ApiHelper {
+
+ static InCallApi thisApi() {
+ return InCallServices.getInstance();
+ }
+
+}
diff --git a/src-ambient/com/android/phone/common/incall/api/InCallListeners.java b/src-ambient/com/android/phone/common/incall/api/InCallListeners.java
new file mode 100644
index 0000000..a25c1e1
--- /dev/null
+++ b/src-ambient/com/android/phone/common/incall/api/InCallListeners.java
@@ -0,0 +1,84 @@
+/*
+ * 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.api;
+
+import android.content.Context;
+
+import com.android.phone.common.ambient.AmbientDataSubscription;
+import com.android.phone.common.incall.listeners.AuthenticationListenerImpl;
+import com.android.phone.common.incall.listeners.CallCreditListenerImpl;
+import com.android.phone.common.incall.CallMethodInfo;
+
+/**
+ * Data Listeners that incall implements.
+ */
+public class InCallListeners extends ApiHelper {
+
+ /**
+ * Enables credit listener on a Mod.
+ * @param instance us
+ * @param callMethodInfo CallMethod to add listener to
+ */
+ public static void enableCreditListener(AmbientDataSubscription<CallMethodInfo> instance,
+ CallMethodInfo callMethodInfo) {
+ CallCreditListenerImpl listener = CallCreditListenerImpl.getInstance(instance.mContext,
+ callMethodInfo.mComponent);
+ thisApi().addCreditListener(instance.mClient, callMethodInfo.mComponent,
+ listener);
+ callMethodInfo.setCreditListener(listener);
+ }
+
+ /**
+ * Disables credit listener on a Mod.
+ * @param instance us
+ * @param callMethodInfo CallMethod to remove listener from
+ */
+ public static void disableCreditListener(AmbientDataSubscription<CallMethodInfo> instance,
+ CallMethodInfo callMethodInfo) {
+ CallCreditListenerImpl listener = callMethodInfo.getCreditListener();
+ thisApi().removeCreditListener(instance.mClient, callMethodInfo.mComponent,
+ listener);
+ callMethodInfo.setCreditListener(null);
+ }
+
+ /**
+ * Enable Auth Listener on a Mod
+ * @param instance us
+ * @param callMethodInfo CallMethod to add listener to
+ */
+ public static void enableAuthListener(AmbientDataSubscription<CallMethodInfo> instance,
+ CallMethodInfo callMethodInfo) {
+ AuthenticationListenerImpl listener = AuthenticationListenerImpl.getInstance(
+ instance.mContext, callMethodInfo.mComponent);
+ thisApi().addAuthenticationListener(instance.mClient, callMethodInfo.mComponent,
+ listener);
+ callMethodInfo.setAuthListener(listener);
+ }
+
+ /**
+ * Disable Auth Listener on a Mod
+ * @param instance us
+ * @param callMethodInfo CallMethod to remove listener from
+ */
+ public static void disableAuthListener(AmbientDataSubscription<CallMethodInfo> instance,
+ CallMethodInfo callMethodInfo) {
+ AuthenticationListenerImpl listener = callMethodInfo.getAuthListener();
+ thisApi().removeAuthenticationListener(instance.mClient,
+ callMethodInfo.mComponent, listener);
+ callMethodInfo.setAuthListener(null);
+ }
+}
diff --git a/src-ambient/com/android/phone/common/incall/api/InCallQueries.java b/src-ambient/com/android/phone/common/incall/api/InCallQueries.java
new file mode 100644
index 0000000..384cfdb
--- /dev/null
+++ b/src-ambient/com/android/phone/common/incall/api/InCallQueries.java
@@ -0,0 +1,230 @@
+/*
+ * 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.api;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.net.Uri;
+import android.util.Log;
+
+import com.android.phone.common.ambient.AmbientDataSubscription;
+import com.android.phone.common.ambient.TypedPendingResult;
+import com.android.phone.common.incall.CallMethodInfo;
+import com.cyanogen.ambient.analytics.Event;
+import com.cyanogen.ambient.common.api.AmbientApiClient;
+import com.cyanogen.ambient.common.api.Result;
+import com.cyanogen.ambient.common.api.ResultCallback;
+
+/**
+ * Queries for incall plugins
+ */
+public class InCallQueries extends ApiHelper {
+
+ private static final String TAG = InCallQueries.class.getSimpleName();
+ private static final boolean DEBUG = false;
+
+ /**
+ * Prepare to query and fire off ModCore calls in all directions
+ */
+ public static void updateCallPlugins(AmbientDataSubscription<CallMethodInfo> instance) {
+ thisApi().getInstalledPlugins(instance.mClient).setResultCallback(instance.BOOTSTRAP);
+ }
+
+ /**
+ * Get the plugin info
+ * @param componentName of mod
+ *
+ * @return TypedPendingResult to identify which field to modify in our CallMethodInfo object
+ */
+ public static TypedPendingResult getCallMethodInfo(AmbientApiClient client,
+ ComponentName componentName) {
+
+ return new TypedPendingResult(thisApi().getProviderInfo(client, componentName),
+ TypedPendingResult.GENERAL_DATA);
+ }
+
+ /**
+ * Get our mod enabled status
+ * @param componentName of mod
+ *
+ * @return TypedPendingResult to identify which field to modify in our CallMethodInfo object
+ */
+ public static TypedPendingResult getCallMethodStatus(AmbientApiClient client,
+ ComponentName componentName) {
+ return new TypedPendingResult(thisApi().getPluginStatus(client, componentName),
+ TypedPendingResult.STATUS);
+ }
+
+ /**
+ * Get the mod mimetype
+ * @param componentName of mod
+ *
+ * @return TypedPendingResult to identify which field to modify in our CallMethodInfo object
+ */
+ public static TypedPendingResult getCallMethodMimeType(AmbientApiClient client,
+ ComponentName componentName) {
+ return new TypedPendingResult(thisApi().getCallableMimeType(client, componentName),
+ TypedPendingResult.GENERAL_MIME_TYPE);
+ }
+
+ /**
+ * Get the plugin video mimetype
+ * @param componentName of mod
+ *
+ * @return TypedPendingResult to identify which field to modify in our CallMethodInfo object
+ */
+ public static TypedPendingResult getCallMethodVideoCallableMimeType(AmbientApiClient client,
+ ComponentName componentName) {
+ return new TypedPendingResult(thisApi().getVideoCallableMimeType(client, componentName),
+ TypedPendingResult.VIDEO_MIME_TYPE);
+ }
+
+ /**
+ * Get the plugin im mime type
+ * @param componentName of mod
+ *
+ * @return TypedPendingResult to identify which field to modify in our CallMethodInfo object
+ */
+ public static TypedPendingResult getCallMethodImMimeType(AmbientApiClient client,
+ ComponentName componentName) {
+ return new TypedPendingResult(thisApi().getImMimeType(client, componentName),
+ TypedPendingResult.IM_MIME_TYPE);
+ }
+
+ /**
+ * Get the Authentication state of the callmethod
+ * @param componentName of mod
+ *
+ * @return TypedPendingResult to identify which field to modify in our CallMethodInfo object
+ */
+ public static TypedPendingResult getCallMethodAuthenticated(AmbientApiClient client,
+ ComponentName componentName) {
+ return new TypedPendingResult(thisApi().getAuthenticationState(client, componentName),
+ TypedPendingResult.AUTHENTICATION);
+ }
+
+ /**
+ * Get the credits intent of the mod
+ * @param componentName of mod
+ *
+ * @return TypedPendingResult to identify which field to modify in our CallMethodInfo object
+ */
+ public static TypedPendingResult getManageCreditsIntent(AmbientApiClient client,
+ ComponentName componentName) {
+ return new TypedPendingResult(thisApi().getManageCreditsIntent(client, componentName),
+ TypedPendingResult.CREDIT_INTENT);
+ }
+
+ /**
+ * Get the login intent of the mod
+ * @param componentName of mod
+ *
+ * @return TypedPendingResult to identify which field to modify in our CallMethodInfo object
+ */
+ public static TypedPendingResult getLoginIntent(AmbientApiClient client,
+ ComponentName componentName) {
+ return new TypedPendingResult(thisApi().getLoginIntent(client, componentName),
+ TypedPendingResult.LOGIN_INTENT);
+ }
+
+ /**
+ * Get the settings intent for the callmethod
+ * @param componentName of mod
+ *
+ * @return TypedPendingResult to identify which field to modify in our CallMethodInfo object
+ */
+ public static TypedPendingResult getSettingsIntent(AmbientApiClient client,
+ ComponentName componentName) {
+ return new TypedPendingResult(thisApi().getSettingsIntent(client, componentName),
+ TypedPendingResult.SETTINGS_INTENT);
+ }
+
+ /**
+ * Get the credit info of the mod
+ * @param componentName of mod
+ *
+ * @return TypedPendingResult to identify which field to modify in our CallMethodInfo object
+ */
+ public static TypedPendingResult getCreditInfo(AmbientApiClient client,
+ ComponentName componentName) {
+ return new TypedPendingResult(thisApi().getCreditInfo(client, componentName),
+ TypedPendingResult.CREDIT_INFO);
+ }
+
+ /**
+ * Get the account handle of the mod
+ * @param componentName of mod
+ *
+ * @return TypedPendingResult to identify which field to modify in our CallMethodInfo object
+ */
+ public static TypedPendingResult getCallMethodAccountHandle(AmbientApiClient client,
+ ComponentName componentName) {
+ return new TypedPendingResult(thisApi().getAccountHandle(client, componentName),
+ TypedPendingResult.ACCOUNT_HANDLE);
+ }
+
+ /**
+ * Get the hint texts for the callmethod
+ * @param componentName of mod
+ *
+ * @return TypedPendingResult to identify which field to modify in our CallMethodInfo object
+ */
+ public static TypedPendingResult getHintText(AmbientApiClient client,
+ ComponentName componentName) {
+ return new TypedPendingResult(thisApi().getHintText(client, componentName),
+ TypedPendingResult.HINT_TEXT);
+ }
+
+ /**
+ * Get the default search intent for the mod
+ * @param componentName of mod
+ *
+ * @return TypedPendingResult to identify which field to modify in our CallMethodInfo object
+ */
+ public static TypedPendingResult getDefaultDirectorySearchIntent(AmbientApiClient client,
+ ComponentName componentName) {
+ return new TypedPendingResult(thisApi().getDirectorySearchIntent(client, componentName,
+ Uri.parse("")), TypedPendingResult.DEFAULT_DIRECTORY_SEARCH_INTENT);
+ }
+
+ /**
+ * Send analytics to our mod
+ * @param client ambient client
+ * @param componentName Componentname of the mod to send to
+ * @param event the event to send.
+ */
+ public static void shipAnalyticsToPlugin(AmbientApiClient client, ComponentName componentName,
+ Event event) {
+ if (componentName == null) {
+ return;
+ }
+ if (DEBUG) {
+ Log.d(TAG, "componentName: " + componentName.toShortString()
+ + ":Event: " + event.toString());
+ }
+ thisApi().sendAnalyticsEventToPlugin(client, componentName, event)
+ .setResultCallback(new ResultCallback<Result>() {
+ @Override
+ public void onResult(Result result) {
+ if (DEBUG) {
+ Log.v(TAG, "Event sent with result: " + result.getStatus()
+ .getStatusMessage());
+ }
+ }
+ });
+ }
+}
diff --git a/src-ambient/com/android/phone/common/incall/api/InCallResults.java b/src-ambient/com/android/phone/common/incall/api/InCallResults.java
new file mode 100644
index 0000000..b636f56
--- /dev/null
+++ b/src-ambient/com/android/phone/common/incall/api/InCallResults.java
@@ -0,0 +1,283 @@
+/*
+ * 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.api;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.res.Resources;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.phone.common.ambient.AmbientDataSubscription;
+import com.android.phone.common.ambient.TypedPendingResult;
+import com.android.phone.common.incall.CallMethodInfo;
+import com.android.phone.common.incall.utils.CallMethodUtils;
+import com.android.phone.common.ambient.utils.PluginUtils;
+import com.android.phone.common.nudge.api.NudgeTypedResult;
+import com.cyanogen.ambient.discovery.results.BundleResult;
+import com.cyanogen.ambient.discovery.util.NudgeKey;
+import com.cyanogen.ambient.incall.extension.CreditBalance;
+import com.cyanogen.ambient.incall.extension.CreditInfo;
+import com.cyanogen.ambient.incall.extension.GetCreditInfoResult;
+import com.cyanogen.ambient.incall.extension.HintTextResult;
+import com.cyanogen.ambient.incall.extension.StatusCodes;
+import com.cyanogen.ambient.incall.results.AccountHandleResult;
+import com.cyanogen.ambient.incall.results.AuthenticationStateResult;
+import com.cyanogen.ambient.incall.results.HintTextResultResult;
+import com.cyanogen.ambient.incall.results.InCallProviderInfoResult;
+import com.cyanogen.ambient.incall.results.InstalledPluginsResult;
+import com.cyanogen.ambient.incall.results.MimeTypeResult;
+import com.cyanogen.ambient.incall.results.PendingIntentResult;
+import com.cyanogen.ambient.incall.results.PluginStatusResult;
+import com.cyanogen.ambient.incall.util.InCallProviderInfo;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Class that handles writing results to our CallMethodInfo object
+ */
+public class InCallResults extends ApiHelper {
+
+ private static final String TAG = InCallResults.class.getSimpleName();
+
+ public static List<ComponentName> gotInstalledPlugins(InstalledPluginsResult result) {
+ if (result.components == null) {
+ return new ArrayList<ComponentName>();
+ }
+ return result.components;
+ }
+
+ public static void gotStatus(CallMethodInfo callMethodInfo, PluginStatusResult result) {
+ callMethodInfo.mStatus = result.status;
+ }
+
+ public static void gotMimeType(CallMethodInfo callMethodInfo, MimeTypeResult result, int type) {
+ switch(type) {
+ case TypedPendingResult.GENERAL_MIME_TYPE:
+ callMethodInfo.mMimeType = result.mimeType;
+ break;
+ case TypedPendingResult.VIDEO_MIME_TYPE:
+ callMethodInfo.mVideoCallableMimeType = result.mimeType;
+ break;
+ case TypedPendingResult.IM_MIME_TYPE:
+ callMethodInfo.mImMimeType = result.mimeType;
+ break;
+ }
+ }
+
+ public static void gotIntent(CallMethodInfo callMethodInfo, PendingIntentResult result,
+ int type) {
+ switch(type) {
+ case TypedPendingResult.LOGIN_INTENT:
+ callMethodInfo.mLoginIntent = result.intent;
+ break;
+ case TypedPendingResult.CREDIT_INTENT:
+ callMethodInfo.mManageCreditIntent = result.intent;
+ break;
+ case TypedPendingResult.SETTINGS_INTENT:
+ callMethodInfo.mSettingsIntent = result.intent;
+ break;
+ case TypedPendingResult.DEFAULT_DIRECTORY_SEARCH_INTENT:
+ callMethodInfo.mDefaultDirectorySearchIntent = result.intent;
+ break;
+ }
+ }
+
+ public static void gotAuthenticationState(CallMethodInfo callMethodInfo,
+ AuthenticationStateResult result) {
+ callMethodInfo.mIsAuthenticated
+ = result.result == StatusCodes.AuthenticationState.LOGGED_IN;
+ }
+
+ public static void gotAccountHandle(CallMethodInfo callMethodInfo, Context context,
+ AccountHandleResult result) {
+ gotAccountHandle(callMethodInfo, context, result.accountHandle);
+ }
+
+ private static void gotAccountHandle(CallMethodInfo callMethodInfo, Context context,
+ String accountHandle) {
+ callMethodInfo.mAccountHandle = accountHandle;
+ if (TextUtils.isEmpty(callMethodInfo.mAccountHandle)) {
+ callMethodInfo.mAccountHandle
+ = CallMethodUtils.lookupAccountHandle(context, callMethodInfo.mAccountType);
+ }
+ }
+
+ public static void gotGeneralInfo(CallMethodInfo callMethodInfo,
+ AmbientDataSubscription<CallMethodInfo> instance, InCallProviderInfoResult result) {
+
+ ComponentName componentName = callMethodInfo.mComponent;
+ InCallProviderInfo icpi = result.inCallProviderInfo;
+ if (icpi == null) {
+ instance.getPluginInfo().remove(componentName);
+ return;
+ }
+
+ Resources resources = PluginUtils.getPluginResources(instance.mContext, componentName);
+ if (resources == null) {
+ return;
+ }
+
+ callMethodInfo.mBrandIconId = icpi.getBrandIcon();
+ callMethodInfo.mLoginIconId = icpi.getLoginIcon();
+
+ try {
+ callMethodInfo.mSingleColorBrandIcon
+ = resources.getDrawable(icpi.getSingleColorBrandIcon());
+ callMethodInfo.mBrandIcon = resources.getDrawable(callMethodInfo.mBrandIconId);
+ callMethodInfo.mLoginIcon = resources.getDrawable(callMethodInfo.mLoginIconId);
+ callMethodInfo.mVoiceIcon = resources.getDrawable(icpi.getVoiceMimeIcon());
+ callMethodInfo.mImIcon = resources.getDrawable(icpi.getImMimeIcon());
+ callMethodInfo.mBadgeIcon = resources.getDrawable(icpi.getBadgeIcon());
+ callMethodInfo.mVideoIcon = resources.getDrawable(icpi.getVideoMimeIcon());
+ } catch (Resources.NotFoundException e) {
+ Log.e(TAG, "Resource Not found: " + componentName.flattenToShortString());
+ instance.getPluginInfo().remove(componentName);
+ return;
+ }
+
+ callMethodInfo.mSubscriptionButtonText = icpi.getSubscriptionButtonText();
+ callMethodInfo.mCreditButtonText = icpi.getCreditsButtonText();
+ // If present, use the deprecated attribute defined hint text.
+ // These values may be overwritten by getHintText.
+ callMethodInfo.mT9HintDescriptionNoCreditOrSub = icpi.getT9HintDescription();
+ callMethodInfo.mT9HintDescriptionHasCreditOrSub = icpi.getT9HintDescription();
+ callMethodInfo.mDependentPackage = icpi.getDependentPackage();
+ callMethodInfo.mName = icpi.getTitle();
+ callMethodInfo.mSummary = icpi.getSummary();
+ callMethodInfo.mAccountType = icpi.getAccountType();
+ gotAccountHandle(callMethodInfo, instance.mContext, icpi.getAccountHandle());
+ }
+
+ public static void gotCreditData(CallMethodInfo callMethodInfo, GetCreditInfoResult result) {
+ if (result.creditInfo == null) {
+ // Build zero credit dummy if no result found.
+ callMethodInfo.mProviderCreditInfo = new CreditInfo(new CreditBalance(0, null), null);
+ } else {
+ callMethodInfo.mProviderCreditInfo = result.creditInfo;
+ }
+ }
+
+ public static void gotHintText(CallMethodInfo callMethodInfo,
+ HintTextResultResult resultResult) {
+ HintTextResult result = resultResult.result;
+ if (result != null) {
+ String hintText = result.getNoCreditOrSubscriptionHint();
+ if (!TextUtils.isEmpty(hintText)) {
+ callMethodInfo.mT9HintDescriptionNoCreditOrSub = hintText;
+ }
+ hintText = result.getHasCreditOrSubscriptionHint();
+ if (!TextUtils.isEmpty(hintText)) {
+ callMethodInfo.mT9HintDescriptionHasCreditOrSub = hintText;
+ }
+ }
+ }
+
+ public static void updateCreditInfo(AmbientDataSubscription<CallMethodInfo> instance,
+ ComponentName name, GetCreditInfoResult result) {
+ CallMethodInfo callMethodInfo = instance.getPluginIfExists(name);
+ if (callMethodInfo != null) {
+ gotCreditData(callMethodInfo, result);
+ instance.getPluginInfo().put(name, callMethodInfo);
+
+ // Since a CallMethodInfo object was updated here, we should let the subscribers know
+ instance.broadcast();
+ } else {
+ Log.wtf(TAG, "Call method does not exist, this should not happen");
+ }
+ }
+
+ public static void updateAuthenticationState(AmbientDataSubscription<CallMethodInfo> instance,
+ ComponentName name, int state) {
+ CallMethodInfo callMethodInfo = instance.getPluginIfExists(name);
+ if (callMethodInfo != null) {
+ callMethodInfo.mIsAuthenticated = state == StatusCodes.AuthenticationState.LOGGED_IN;
+ instance.getPluginInfo().put(name, callMethodInfo);
+
+ // Since a CallMethodInfo object was updated here, we should let the subscribers know
+ instance.broadcast();
+ } else {
+ Log.wtf(TAG, "Call method does not exist, this should not happen");
+ }
+ }
+
+ public static void gotNudgeData(Context context, CallMethodInfo callMethodInfo,
+ BundleResult result, int type) {
+
+ Bundle bundle = result.bundle;
+ if (bundle == null) {
+ return;
+ }
+ switch (type) {
+ case NudgeTypedResult.INCALL_CREDIT_NUDGE:
+ gotCreditWarn(callMethodInfo, bundle);
+ break;
+ case NudgeTypedResult.INCALL_CONTACT_FRAGMENT_LOGIN:
+ gotLoginSubtitle(callMethodInfo, bundle);
+ break;
+ case NudgeTypedResult.INCALL_CONTACT_CARD_LOGIN:
+ gotContactCardLogin(callMethodInfo, NudgeKey.INCALL_CONTACT_CARD_LOGIN, bundle,
+ context);
+ break;
+ case NudgeTypedResult.INCALL_CONTACT_CARD_DOWNLOAD:
+ gotContactCardDownload(callMethodInfo, NudgeKey.INCALL_CONTACT_CARD_DOWNLOAD,
+ bundle, context);
+ break;
+ }
+ }
+
+ private static void gotLoginSubtitle(CallMethodInfo callMethodInfo, Bundle bundle) {
+ callMethodInfo.mLoginSubtitle = bundle.getString(NudgeKey.NUDGE_PARAM_SUBTITLE);
+ }
+
+ private static void gotContactCardLogin(CallMethodInfo callMethodInfo, String key,
+ Bundle bundle, Context c) {
+ callMethodInfo.mLoginNudgeEnable = bundle.getBoolean(NudgeKey.NUDGE_PARAM_ENABLED, true)
+ && PreferenceManager.getDefaultSharedPreferences(c).getBoolean(
+ getKey(key, callMethodInfo), true);
+ callMethodInfo.mLoginNudgeSubtitle = bundle.getString(NudgeKey.NUDGE_PARAM_SUBTITLE);
+ callMethodInfo.mLoginNudgeActionText = bundle.getString(NudgeKey.NUDGE_PARAM_ACTION_TEXT);
+ }
+
+ private static void gotCreditWarn(CallMethodInfo callMethodInfo, Bundle bundle) {
+ Object creditWarn = bundle.get(NudgeKey.INCALL_PARAM_CREDIT_WARN);
+ if (creditWarn.getClass().equals(Integer.class)) {
+ callMethodInfo.mCreditWarn = (Integer) creditWarn;
+ } else if (creditWarn.getClass().equals(Float.class)) {
+ callMethodInfo.mCreditWarn = (Float) creditWarn;
+ } else {
+ Log.e(TAG, "Invalid value for Credit Warn limit: " + creditWarn);
+ }
+ }
+
+ private static void gotContactCardDownload(CallMethodInfo callMethodInfo, String key,
+ Bundle bundle, Context context) {
+ callMethodInfo.mInstallNudgeEnable = bundle.getBoolean(NudgeKey.NUDGE_PARAM_ENABLED, true)
+ && PreferenceManager.getDefaultSharedPreferences(context).getBoolean(
+ getKey(key, callMethodInfo), true);
+ callMethodInfo.mInstallNudgeSubtitle = bundle.getString(NudgeKey.NUDGE_PARAM_SUBTITLE);
+ callMethodInfo.mInstallNudgeActionText = bundle.getString(NudgeKey.NUDGE_PARAM_ACTION_TEXT);
+ }
+
+
+ private static String getKey(String key, CallMethodInfo cmi) {
+ return cmi.mComponent.getClassName() + "." + key;
+ }
+}
diff --git a/src-ambient/com/android/phone/common/incall/listeners/AuthenticationListenerImpl.java b/src-ambient/com/android/phone/common/incall/listeners/AuthenticationListenerImpl.java
new file mode 100644
index 0000000..8bf3b53
--- /dev/null
+++ b/src-ambient/com/android/phone/common/incall/listeners/AuthenticationListenerImpl.java
@@ -0,0 +1,58 @@
+/*
+ * 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.listeners;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.os.RemoteException;
+import android.util.Log;
+
+import com.android.phone.common.incall.DialerDataSubscription;
+import com.android.phone.common.incall.api.InCallResults;
+import com.cyanogen.ambient.incall.extension.IAuthenticationListener;
+
+public class AuthenticationListenerImpl extends IAuthenticationListener.Stub {
+
+ private static final String TAG = AuthenticationListenerImpl.class.getSimpleName();
+ private static final boolean DEBUG = false;
+
+ private ComponentName mComponentName;
+ private Context mContext;
+
+ public static AuthenticationListenerImpl getInstance(Context context, ComponentName
+ componentName) {
+
+ return new AuthenticationListenerImpl(context, componentName);
+ }
+
+ private AuthenticationListenerImpl(Context context, ComponentName cn) {
+ mContext = context;
+ mComponentName = cn;
+ }
+
+ @Override
+ public void authenticationStateUpdated(int state) throws RemoteException {
+ if (DEBUG) {
+ Log.d(TAG, "Got authenticationStateUpdated for: " + mComponentName + " state: "
+ + state);
+ }
+
+ InCallResults.updateAuthenticationState(DialerDataSubscription.get(mContext),
+ mComponentName, state);
+ }
+
+} \ No newline at end of file
diff --git a/src-ambient/com/android/phone/common/incall/listeners/CallCreditListenerImpl.java b/src-ambient/com/android/phone/common/incall/listeners/CallCreditListenerImpl.java
new file mode 100644
index 0000000..9eef6cc
--- /dev/null
+++ b/src-ambient/com/android/phone/common/incall/listeners/CallCreditListenerImpl.java
@@ -0,0 +1,53 @@
+/*
+ * 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.listeners;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.os.RemoteException;
+import android.util.Log;
+
+import com.android.phone.common.incall.DialerDataSubscription;
+import com.android.phone.common.incall.api.InCallResults;
+import com.cyanogen.ambient.incall.extension.GetCreditInfoResult;
+import com.cyanogen.ambient.incall.extension.ICallCreditListener;
+
+public class CallCreditListenerImpl extends ICallCreditListener.Stub {
+
+ private static final String TAG = CallCreditListenerImpl.class.getSimpleName();
+ private static final boolean DEBUG = false;
+
+ private Context mContext;
+ private ComponentName mComponentName;
+
+ public static CallCreditListenerImpl getInstance(Context context, ComponentName componentName) {
+ return new CallCreditListenerImpl(context, componentName);
+ }
+
+ private CallCreditListenerImpl(Context context, ComponentName cn) {
+ mContext = context;
+ mComponentName = cn;
+ }
+
+ @Override
+ public void creditInfoUpdated(GetCreditInfoResult gcir) throws RemoteException {
+ if (DEBUG) {
+ Log.d(TAG, "got creditInfoUpdated for: " + mComponentName + " gcir: " + gcir);
+ }
+ InCallResults.updateCreditInfo(DialerDataSubscription.get(mContext), mComponentName, gcir);
+ }
+} \ No newline at end of file
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/incall/CallMethodUtils.java b/src-ambient/com/android/phone/common/incall/utils/CallMethodUtils.java
index 87a2348..d29f805 100644
--- a/src-ambient/incall/CallMethodUtils.java
+++ b/src-ambient/com/android/phone/common/incall/utils/CallMethodUtils.java
@@ -1,7 +1,25 @@
-package com.android.phone.common.incall;
+/*
+ * 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.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
import android.telecom.PhoneAccount;
import android.telecom.PhoneAccountHandle;
import android.telecom.TelecomManager;
@@ -12,10 +30,14 @@ 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;
@@ -26,8 +48,10 @@ 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";
@@ -48,7 +72,7 @@ public class CallMethodUtils {
final TelecomManager telecomMgr =
(TelecomManager) context.getSystemService(Context.TELECOM_SERVICE);
final List<PhoneAccountHandle> accountHandles = telecomMgr.getCallCapablePhoneAccounts();
- ArrayList<CallMethodInfo> callMethodInfoList = new ArrayList<CallMethodInfo>();
+ ArrayList<CallMethodInfo> callMethodInfoList = new ArrayList<>();
for (PhoneAccountHandle accountHandle : accountHandles) {
CallMethodInfo info = phoneToCallMethod(context, accountHandle);
if (info != null) {
@@ -122,7 +146,7 @@ public class CallMethodUtils {
// state as authenticated
AccountTypeManager accountTypes = AccountTypeManager.getInstance(context);
List<AccountWithDataSet> accounts = accountTypes.getAccounts(false);
- ArrayMap<String, String> accountMap = new ArrayMap<String, String>();
+ ArrayMap<String, String> accountMap = new ArrayMap<>();
for (AccountWithDataSet account : accounts) {
AccountType accountType =
@@ -148,4 +172,49 @@ public class CallMethodUtils {
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;
+ }
+
+
+}
diff --git a/src-ambient/com/android/phone/common/nudge/api/ApiHelper.java b/src-ambient/com/android/phone/common/nudge/api/ApiHelper.java
new file mode 100644
index 0000000..d2ca30f
--- /dev/null
+++ b/src-ambient/com/android/phone/common/nudge/api/ApiHelper.java
@@ -0,0 +1,31 @@
+/*
+ * 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.nudge.api;
+
+import com.cyanogen.ambient.discovery.NudgeApi;
+import com.cyanogen.ambient.discovery.NudgeServices;
+
+/**
+ * Helper for getting Nudge Api
+ */
+public class ApiHelper {
+
+ static NudgeApi thisApi() {
+ return NudgeServices.NudgeApi;
+ }
+
+}
diff --git a/src-ambient/com/android/phone/common/nudge/api/NudgeQueries.java b/src-ambient/com/android/phone/common/nudge/api/NudgeQueries.java
new file mode 100644
index 0000000..a48e079
--- /dev/null
+++ b/src-ambient/com/android/phone/common/nudge/api/NudgeQueries.java
@@ -0,0 +1,55 @@
+/*
+ * 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.nudge.api;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.util.Log;
+
+import com.android.phone.common.ambient.TypedPendingResult;
+import com.android.phone.common.nudge.utils.NudgeUtils;
+import com.cyanogen.ambient.common.api.AmbientApiClient;
+import com.cyanogen.ambient.discovery.NudgeServices;
+
+/**
+ * Queries for Nudges
+ */
+public class NudgeQueries extends ApiHelper {
+
+ private static TypedPendingResult getNudgeForKey(AmbientApiClient client,
+ ComponentName componentName, String key) {
+ int type = NudgeTypedResult.getNudgeTypeForKey(key);
+ return new TypedPendingResult(thisApi().getConfigurationForKey(
+ client, componentName, key), type);
+ }
+
+ /**
+ * Get a nudge configuration for the mod
+ * @param cn of mod
+ *
+ * @return TypedPendingResult to identify which field to modify in our CallMethodInfo object
+ */
+ public static TypedPendingResult getNudgeConfig(AmbientApiClient client,
+ Context c, ComponentName cn, String key) {
+
+ ComponentName nudgeComponent = NudgeUtils.getNudgeComponent(c, cn);
+ if (nudgeComponent != null) {
+ return NudgeQueries.getNudgeForKey(client, nudgeComponent, key);
+ }
+ return null;
+ }
+}
diff --git a/src-ambient/com/android/phone/common/nudge/api/NudgeTypedResult.java b/src-ambient/com/android/phone/common/nudge/api/NudgeTypedResult.java
new file mode 100644
index 0000000..39a9d19
--- /dev/null
+++ b/src-ambient/com/android/phone/common/nudge/api/NudgeTypedResult.java
@@ -0,0 +1,51 @@
+/*
+ * 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.nudge.api;
+
+import com.android.phone.common.ambient.TypedPendingResult;
+import com.cyanogen.ambient.common.api.PendingResult;
+import com.cyanogen.ambient.discovery.util.NudgeKey;
+
+import android.util.Log;
+
+/**
+ * InCall Pending result types.
+ */
+public class NudgeTypedResult extends TypedPendingResult {
+
+ private static final String TAG = NudgeTypedResult.class.getSimpleName();
+
+ public NudgeTypedResult(PendingResult pendingResult, int type) {
+ super(pendingResult, type);
+ }
+
+ public static int getNudgeTypeForKey(String key) {
+ switch (key) {
+ case NudgeKey.INCALL_CREDIT_NUDGE:
+ return INCALL_CREDIT_NUDGE;
+ case NudgeKey.INCALL_CONTACT_CARD_LOGIN:
+ return INCALL_CONTACT_CARD_LOGIN;
+ case NudgeKey.INCALL_CONTACT_CARD_DOWNLOAD:
+ return INCALL_CONTACT_CARD_DOWNLOAD;
+ case NudgeKey.INCALL_CONTACT_FRAGMENT_LOGIN:
+ return INCALL_CONTACT_FRAGMENT_LOGIN;
+ default:
+ Log.e(TAG, "No nudge type!");
+ return NONE;
+ }
+ }
+}
diff --git a/src-ambient/com/android/phone/common/nudge/utils/NudgeUtils.java b/src-ambient/com/android/phone/common/nudge/utils/NudgeUtils.java
new file mode 100644
index 0000000..921c97f
--- /dev/null
+++ b/src-ambient/com/android/phone/common/nudge/utils/NudgeUtils.java
@@ -0,0 +1,47 @@
+/*
+ * 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.nudge.utils;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ResolveInfo;
+
+import java.util.List;
+
+/**
+ * Utilities class to help with nudge events.
+ */
+public class NudgeUtils {
+
+ public static final String NUDGE_PROVIDER_INTENT = "cyanogen.service.NUDGE_PROVIDER";
+
+ public static ComponentName getNudgeComponent(Context context, final ComponentName cn) {
+ // find a nudge component if it exists for this package
+ Intent nudgeIntent = new Intent(NUDGE_PROVIDER_INTENT);
+ nudgeIntent.setPackage(cn.getPackageName());
+ List<ResolveInfo> resolved = context.getPackageManager()
+ .queryIntentServices(nudgeIntent, 0);
+ if (resolved != null && !resolved.isEmpty()) {
+ ResolveInfo result = resolved.get(0);
+ return new ComponentName(result.serviceInfo.applicationInfo.packageName,
+ result.serviceInfo.name);
+ }
+ // if a nudge component doesn't exist, just finish here
+ return null;
+ }
+}
diff --git a/src-ambient/incall/AuthenticationListenerImpl.java b/src-ambient/incall/AuthenticationListenerImpl.java
deleted file mode 100644
index aec72c8..0000000
--- a/src-ambient/incall/AuthenticationListenerImpl.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package com.android.phone.common.incall;
-
-import android.content.ComponentName;
-import android.os.RemoteException;
-import android.util.Log;
-
-import com.cyanogen.ambient.incall.extension.IAuthenticationListener;
-
-public class AuthenticationListenerImpl extends IAuthenticationListener.Stub {
- private static final String TAG = "AuthenticationListener";
- private ComponentName mComponentName;
-
- public static AuthenticationListenerImpl getInstance(ComponentName componentName) {
- return new AuthenticationListenerImpl(componentName);
- }
-
- private AuthenticationListenerImpl(ComponentName cn) {
- mComponentName = cn;
- }
-
- @Override
- public void authenticationStateUpdated(int state) throws RemoteException {
- Log.d(TAG, "Getting authenticationStateUpdated for: " + mComponentName + " state: " +
- state);
- CallMethodHelper.updateAuthenticationState(mComponentName, state);
- }
-} \ No newline at end of file
diff --git a/src-ambient/incall/CallCreditListenerImpl.java b/src-ambient/incall/CallCreditListenerImpl.java
deleted file mode 100644
index 13fcb30..0000000
--- a/src-ambient/incall/CallCreditListenerImpl.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package com.android.phone.common.incall;
-
-import android.content.ComponentName;
-import android.os.RemoteException;
-import android.util.Log;
-
-import com.cyanogen.ambient.incall.extension.GetCreditInfoResult;
-import com.cyanogen.ambient.incall.extension.ICallCreditListener;
-
-public class CallCreditListenerImpl extends ICallCreditListener.Stub {
- private static final String TAG = "CallCreditListener";
- private ComponentName mComponentName;
-
- public static CallCreditListenerImpl getInstance(ComponentName componentName) {
- return new CallCreditListenerImpl(componentName);
- }
-
- private CallCreditListenerImpl(ComponentName cn) {
- mComponentName = cn;
- }
-
- @Override
- public void creditInfoUpdated(GetCreditInfoResult gcir)
- throws RemoteException {
- Log.d(TAG, "getting creditInfoUpdated for: " + mComponentName + " gcir: " + gcir);
- CallMethodHelper.updateCreditInfo(mComponentName, gcir);
- }
-} \ No newline at end of file
diff --git a/src-ambient/incall/CallMethodHelper.java b/src-ambient/incall/CallMethodHelper.java
deleted file mode 100644
index 5352c28..0000000
--- a/src-ambient/incall/CallMethodHelper.java
+++ /dev/null
@@ -1,1250 +0,0 @@
-/*
- * Copyright (C) 2015 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;
-
-import android.app.PendingIntent;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.content.res.Resources;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.preference.PreferenceManager;
-import android.text.TextUtils;
-import android.util.Log;
-import android.widget.Toast;
-
-import com.android.phone.common.R;
-import com.android.phone.common.ambient.AmbientConnection;
-import com.android.phone.common.util.StartInCallCallReceiver;
-import com.cyanogen.ambient.analytics.Event;
-import com.cyanogen.ambient.common.api.AmbientApiClient;
-import com.cyanogen.ambient.common.api.CommonStatusCodes;
-import com.cyanogen.ambient.common.api.PendingResult;
-import com.cyanogen.ambient.common.api.Result;
-import com.cyanogen.ambient.common.api.ResultCallback;
-import com.cyanogen.ambient.discovery.NudgeServices;
-import com.cyanogen.ambient.discovery.results.BundleResult;
-import com.cyanogen.ambient.discovery.util.NudgeKey;
-import com.cyanogen.ambient.incall.InCallApi;
-import com.cyanogen.ambient.incall.InCallServices;
-import com.cyanogen.ambient.incall.extension.CreditBalance;
-import com.cyanogen.ambient.incall.extension.CreditInfo;
-import com.cyanogen.ambient.incall.extension.GetCreditInfoResult;
-import com.cyanogen.ambient.incall.extension.HintTextResult;
-import com.cyanogen.ambient.incall.extension.IAuthenticationListener;
-import com.cyanogen.ambient.incall.extension.ICallCreditListener;
-import com.cyanogen.ambient.incall.extension.InCallContactInfo;
-import com.cyanogen.ambient.incall.extension.StatusCodes;
-import com.cyanogen.ambient.incall.results.AccountHandleResult;
-import com.cyanogen.ambient.incall.results.AuthenticationStateResult;
-import com.cyanogen.ambient.incall.results.GetCreditInfoResultResult;
-import com.cyanogen.ambient.incall.results.HintTextResultResult;
-import com.cyanogen.ambient.incall.results.InCallProviderInfoResult;
-import com.cyanogen.ambient.incall.results.InstalledPluginsResult;
-import com.cyanogen.ambient.incall.results.MimeTypeResult;
-import com.cyanogen.ambient.incall.results.PendingIntentResult;
-import com.cyanogen.ambient.incall.results.PluginStatusResult;
-import com.cyanogen.ambient.incall.util.InCallProviderInfo;
-import com.cyanogen.ambient.plugin.PluginStatus;
-import com.google.common.base.Joiner;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import static com.cyanogen.ambient.incall.util.InCallHelper.NO_COLOR;
-
-/**
- * Call Method Helper - In charge of keeping a running and updated hashmap of all InCallProviders
- * currently installed.
- *
- * Fragments and Activities can subscribe to changes with subscribe.
- *
- */
-public class CallMethodHelper {
-
- protected static final String TAG = CallMethodHelper.class.getSimpleName();
- protected static final boolean DEBUG = false;
-
- protected static CallMethodHelper sInstance;
- protected AmbientApiClient mClient;
- protected Context mContext;
- protected InCallApi mInCallApi;
- protected Handler mMainHandler;
- protected static List<ComponentName> mInstalledPlugins;
- protected static HashMap<ComponentName, CallMethodInfo> mCallMethodInfos = new HashMap<>();
- protected static HashMap<ComponentName, ICallCreditListener> mCallCreditListeners = new
- HashMap<>();
- protected static HashMap<ComponentName, IAuthenticationListener> mAuthenticationListeners = new
- HashMap<>();
- protected static HashMap<String, CallMethodReceiver> mRegisteredClients = new HashMap<>();
- protected static boolean dataHasBeenBroadcastPreviously = false;
- // determine which info types to load
-
-
- public interface CallMethodReceiver {
- void onChanged(HashMap<ComponentName, CallMethodInfo> callMethodInfos);
- }
-
- /**
- * Broadcasts mCallMethodInfos to all registered clients on the Main thread.
- */
- protected static void broadcast() {
- getInstance().mMainHandler.post(new Runnable() {
- @Override
- public void run() {
- if (DEBUG) Log.d(TAG, "broadcast");
- for (CallMethodReceiver client : mRegisteredClients.values()) {
- client.onChanged(mCallMethodInfos);
- }
- enableListeners();
- if (DEBUG) {
- for (CallMethodInfo cmi : mCallMethodInfos.values()) {
- Log.v(TAG, "Broadcast: " + cmi.mName);
- }
- }
- dataHasBeenBroadcastPreviously = true;
- }
- });
- }
-
- private static void enableListeners() {
- if (DEBUG) Log.d(TAG, "Enabling Listeners");
- for (ComponentName callProviders : mCallMethodInfos.keySet()) {
- if (!mCallCreditListeners.containsKey(callProviders)) {
- CallCreditListenerImpl listener =
- CallCreditListenerImpl.getInstance(callProviders);
- getInstance().mInCallApi.addCreditListener(getInstance().mClient, callProviders,
- listener);
- mCallCreditListeners.put(callProviders, listener);
- }
- if (!mAuthenticationListeners.containsKey(callProviders)) {
- AuthenticationListenerImpl listener =
- AuthenticationListenerImpl.getInstance(callProviders);
- getInstance().mInCallApi.addAuthenticationListener(getInstance().mClient,
- callProviders, listener);
- mAuthenticationListeners.put(callProviders, listener);
- }
- }
- }
-
- private static void disableListeners() {
- if (DEBUG) Log.d(TAG, "Disabling Listeners");
- for(ComponentName callCreditProvider : mCallCreditListeners.keySet()) {
- if (mCallCreditListeners.get(callCreditProvider) != null) {
- getInstance().mInCallApi.removeCreditListener(getInstance().mClient,
- callCreditProvider, mCallCreditListeners.get(callCreditProvider));
- }
- }
- for (ComponentName plugin : mAuthenticationListeners.keySet()) {
- if (mAuthenticationListeners.get(plugin) != null) {
- getInstance().mInCallApi.removeAuthenticationListener(getInstance().mClient,
- plugin, mAuthenticationListeners.get(plugin));
- }
- }
- mCallCreditListeners.clear();
- mAuthenticationListeners.clear();
- }
-
- /**
- * 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() {
- HashMap<ComponentName, CallMethodInfo> cmi = new HashMap<ComponentName, CallMethodInfo>();
- for (Map.Entry<ComponentName, CallMethodInfo> entry : mCallMethodInfos.entrySet()) {
- ComponentName key = entry.getKey();
- CallMethodInfo value = entry.getValue();
-
- if (value.mStatus == PluginStatus.ENABLED) {
- cmi.put(key, value);
- }
- }
- return cmi;
- }
-
- public static HashMap<ComponentName, CallMethodInfo> getAllEnabledAndHiddenCallMethods() {
- HashMap<ComponentName, CallMethodInfo> cmi = new HashMap<ComponentName, CallMethodInfo>();
- synchronized (mCallMethodInfos) {
- for (Map.Entry<ComponentName, CallMethodInfo> entry : mCallMethodInfos.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) {
- CallMethodInfo targetEntry = null;
- synchronized (mCallMethodInfos) {
- for (CallMethodInfo entry : mCallMethodInfos.values()) {
- // TODO: 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;
- }
-
- /***
- * Registers the client, on register returns boolean if
- * callMethodInfo data is already collected and the initial broadcast has been sent.
- * @param id unique string for the client
- * @param cmr client receiver
- * @return boolean isempty
- */
- public static synchronized boolean subscribe(String id, CallMethodReceiver cmr) {
- mRegisteredClients.put(id, cmr);
-
- return dataHasBeenBroadcastPreviously;
- }
-
- /**
- * Unsubscribes the client. All clients should unsubscribe when they are removed.
- * @param id of the client to remove
- */
- public static synchronized void unsubscribe(String id) {
- mRegisteredClients.remove(id);
- disableListeners();
- }
-
- /**
- * Get a single instance of our call method helper. There should only be ever one instance.
- * @return
- */
- protected static synchronized CallMethodHelper getInstance() {
- if (sInstance == null) {
- sInstance = new CallMethodHelper();
- }
- return sInstance;
- }
-
- public interface InCallCallListener {
- void onResult(int resultCode);
- }
-
- /**
- * Generic CallResultReceiver with basic error handling
- * @param cmi
- * @return
- */
- public static StartInCallCallReceiver getVoIPResultReceiver(final CallMethodInfo cmi,
- final String originCode) {
- return getVoIPResultReceiver(cmi, originCode, null);
- }
-
- public static StartInCallCallReceiver getVoIPResultReceiver(final CallMethodInfo cmi,
- final String originCode, final 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 = getInstance().mContext.getResources()
- .getString(R.string.invalid_number_text);
- text = String.format(text, cmi.mName);
- Toast.makeText(getInstance().mContext, 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;
- }
-
- /**
- * Start our Helper and kick off our first ModCore queries.
- * @param context
- */
- public static void init(Context context) {
- CallMethodHelper helper = getInstance();
- helper.mContext = context;
- helper.mClient = AmbientConnection.CLIENT.get(context);
- helper.mInCallApi = InCallServices.getInstance();
- helper.mMainHandler = new Handler(context.getMainLooper());
- refresh();
- }
-
- /**
- * *sip* ahhhh so refreshing
- */
- public static void refresh() {
- updateCallPlugins();
- }
-
- /**
- * This is helpful for items that don't want to subscribe to updates or for things that
- * need a quick CMI and have a component name.
- * @param cn Component name wanted.
- * @return specific call method when given a component name.
- */
- public static CallMethodInfo getCallMethod(ComponentName cn) {
- CallMethodInfo cmi = null;
- synchronized (mCallMethodInfos) {
- if (mCallMethodInfos.containsKey(cn)) {
- cmi = mCallMethodInfos.get(cn);
- }
- }
- return cmi;
- }
-
- /**
- * This is useful for items that subscribe after the initial broadcast has been sent out and
- * need to go get some data right away
- * @return the current HashMap of CMIs.
- */
- public static HashMap<ComponentName, CallMethodInfo> getAllCallMethods() {
- // after the initial broadcast on resume we need to go and get some new data
- // this data will broadcast as soon as it becomes available
- return mCallMethodInfos;
- }
-
- public static void refreshDynamicItems() {
- enableListeners();
- for (ComponentName cn : mCallMethodInfos.keySet()) {
- HashMap<ResultCallback, PendingResult> apiCallbacks = new HashMap<ResultCallback,
- PendingResult>();
- getCallMethodAuthenticated(cn, apiCallbacks);
- getCreditInfo(cn, apiCallbacks);
- executeAll(apiCallbacks);
- }
- }
-
- /**
- * 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() {
- String mimeTypes = "";
-
- List<String> mimeTypesList = new ArrayList<>();
- synchronized (mCallMethodInfos) {
- for (CallMethodInfo cmi : mCallMethodInfos.values()) {
- mimeTypesList.add(cmi.mMimeType);
- }
- }
-
- 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 enabled mime types
- */
- public static String getAllEnabledMimeTypes() {
- String mimeTypes = "";
-
- List<String> enabledMimeTypes = new ArrayList<>();
- synchronized (mCallMethodInfos) {
- for (CallMethodInfo cmi : mCallMethodInfos.values()) {
- if (cmi.mStatus == PluginStatus.ENABLED) {
- enabledMimeTypes.add(cmi.mMimeType);
- }
- }
- }
-
- if (!enabledMimeTypes.isEmpty()) {
- mimeTypes = Joiner.on(",").skipNulls().join(enabledMimeTypes);
- }
- return mimeTypes;
- }
-
- /**
- * 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() {
- String mimeTypes = "";
-
- List<String> enabledMimeTypes = new ArrayList<>();
- synchronized (mCallMethodInfos) {
- for (CallMethodInfo cmi : mCallMethodInfos.values()) {
- if (cmi.mStatus == PluginStatus.ENABLED) {
- enabledMimeTypes.add(cmi.mVideoCallableMimeType);
- }
- }
- }
-
- if (!enabledMimeTypes.isEmpty()) {
- mimeTypes = Joiner.on(",").skipNulls().join(enabledMimeTypes);
- }
- return mimeTypes;
- }
-
- public static String getAllEnabledImMimeTypes() {
- String mimeTypes = "";
-
- List<String> enabledMimeTypes = new ArrayList<>();
- synchronized (mCallMethodInfos) {
- for (CallMethodInfo cmi : mCallMethodInfos.values()) {
- if (cmi.mStatus == PluginStatus.ENABLED) {
- enabledMimeTypes.add(cmi.mImMimeType);
- }
- }
- }
- if (!enabledMimeTypes.isEmpty()) {
- mimeTypes = Joiner.on(",").skipNulls().join(enabledMimeTypes);
- }
- return mimeTypes;
- }
-
- public static void updateCreditInfo(ComponentName name, GetCreditInfoResult gcir) {
- CallMethodInfo cmi = getCallMethodIfExists(name);
- if (cmi != null) {
- if (gcir == null || gcir.creditInfo == null) {
- // Build zero credit dummy if no result found.
- cmi.mProviderCreditInfo =
- new CreditInfo(new CreditBalance(0, null), null);
- } else {
- cmi.mProviderCreditInfo = gcir.creditInfo;
- }
-
- // Since a CallMethodInfo object was updated here, we should let the subscribers know
- broadcast();
- }
- }
-
- public static void updateAuthenticationState(ComponentName name, int state) {
- CallMethodInfo cmi = getCallMethodIfExists(name);
- if (cmi != null) {
- cmi.mIsAuthenticated = state == StatusCodes.AuthenticationState
- .LOGGED_IN;
- mCallMethodInfos.put(name, cmi);
-
- // Since a CallMethodInfo object was updated here, we should let the subscribers know
- broadcast();
- }
- }
-
- /**
- * Broadcast to subscribers once we know we've gathered all our data. Do not do this until we
- * have everything we need for sure.
- *
- * This method is called after every callback from AmbientCore. We will keep track of all of
- * the callbacks, once we have accounted for all callbacks from all plugins, we can go ahead
- * and update subscribers.
- */
- protected static void maybeBroadcastToSubscribers(ResultCallback callback,
- HashMap<ResultCallback, PendingResult> apiCallbacks) {
- if (callback != null) {
- apiCallbacks.remove(callback);
- }
- if (DEBUG) Log.d(TAG, "maybeBroadcastToSubscribers: mInstalledPugins:" + mInstalledPlugins
- .size());
- if (apiCallbacks.isEmpty()) {
- // we are on the last item. broadcast updated hashmap
- broadcast();
- }
- }
-
- /**
- * In order to speed up the process we make calls for providers that may be invalid
- * To prevent this, make sure every resultcallback uses this before filling in the hashmap.
- * @param cn componentname
- * @return callmethodinfo if valid, otherwise null
- */
- public static CallMethodInfo getCallMethodIfExists(ComponentName cn) {
- if (mCallMethodInfos.containsKey(cn)) {
- return mCallMethodInfos.get(cn);
- } else {
- return null;
- }
- }
-
- /**
- * Prepare to query and fire off ModCore calls in all directions
- */
- protected static void updateCallPlugins() {
- getInstance().mInCallApi.getInstalledPlugins(getInstance().mClient)
- .setResultCallback(new ResultCallback<InstalledPluginsResult>() {
- @Override
- public void onResult(InstalledPluginsResult installedPluginsResult) {
- if (DEBUG) Log.d(TAG, "+++updateCallPlugins");
- // got installed components
- mInstalledPlugins = installedPluginsResult.components;
-
- mCallMethodInfos.clear();
-
- if (mInstalledPlugins == null || mInstalledPlugins.size() == 0) {
- broadcast();
- return;
- }
-
- for (ComponentName cn : mInstalledPlugins) {
- HashMap<ResultCallback, PendingResult> apiCallbacks =
- new HashMap<ResultCallback, PendingResult>();
- mCallMethodInfos.put(cn, new CallMethodInfo());
- getCallMethodInfo(cn, apiCallbacks);
- getCallMethodStatus(cn, apiCallbacks);
- getCallMethodMimeType(cn, apiCallbacks);
- getCallMethodVideoCallableMimeType(cn, apiCallbacks);
- getCallMethodAuthenticated(cn, apiCallbacks);
- getLoginIntent(cn, apiCallbacks);
- getSettingsIntent(cn, apiCallbacks);
- getHintText(cn, apiCallbacks);
- getCreditInfo(cn, apiCallbacks);
- getManageCreditsIntent(cn, apiCallbacks);
- checkLowCreditConfig(cn, apiCallbacks);
- executeAll(apiCallbacks);
- }
- }
- });
- }
-
- protected static void executeAll(HashMap<ResultCallback, PendingResult> apiCallbacks) {
- for (ResultCallback resultCallback : apiCallbacks.keySet()) {
- PendingResult pendingResult = apiCallbacks.get(resultCallback);
- pendingResult.setResultCallback(resultCallback);
- }
- }
-
- /**
- * Get the plugin info
- * @param cn
- * @param apiCallbacks keeps track of the target callbacks before broadcast
- */
- protected static void getCallMethodInfo(final ComponentName cn, final
- HashMap<ResultCallback, PendingResult> apiCallbacks) {
- PendingResult result = getInstance().mInCallApi.getProviderInfo(getInstance()
- .mClient, cn);
- ResultCallback callback = new ResultCallback<InCallProviderInfoResult>() {
- @Override
- public void onResult(InCallProviderInfoResult inCallProviderInfoResult) {
- InCallProviderInfo icpi = inCallProviderInfoResult.inCallProviderInfo;
- if (icpi == null) {
- mCallMethodInfos.remove(cn);
- return;
- }
-
- PackageManager packageManager = getInstance().mContext.getPackageManager();
- Resources pluginResources = null;
- try {
- pluginResources = packageManager.getResourcesForApplication(
- cn.getPackageName());
- } catch (PackageManager.NameNotFoundException e) {
- Log.e(TAG, "Plugin isn't installed: " + cn);
- mCallMethodInfos.remove(cn);
- return;
- }
-
- synchronized (mCallMethodInfos) {
- CallMethodInfo cmi = getCallMethodIfExists(cn);
-
- if (cmi == null) {
- return;
- }
-
- try {
- cmi.mSingleColorBrandIcon =
- pluginResources.getDrawable(icpi.getSingleColorBrandIcon(),
- null);
- cmi.mActionOneIcon =
- pluginResources.getDrawable(icpi.getActionOneIcon(), null);
- cmi.mActionTwoIcon =
- pluginResources.getDrawable(icpi.getActionTwoIcon(), null);
- cmi.mBrandIcon =
- pluginResources.getDrawable(icpi.getBrandIcon(), null);
- cmi.mLoginIcon =
- pluginResources.getDrawable(icpi.getLoginIcon(), null);
- cmi.mVoiceIcon = pluginResources.getDrawable(icpi
- .getVoiceMimeIcon(), null);
- cmi.mVideoIcon = pluginResources.getDrawable(icpi
- .getVideoMimeIcon(), null);
- cmi.mImIcon = pluginResources.getDrawable(icpi.getImMimeIcon(),
- null);
- cmi.mBadgeIcon = pluginResources.getDrawable(icpi.getBadgeIcon(),
- null);
-
- } catch (Resources.NotFoundException e) {
- Log.e(TAG, "Resource Not found: " + cn);
- mCallMethodInfos.remove(cn);
- return;
- }
-
- cmi.mSlotId = -1;
- cmi.mSubId = -1;
- cmi.mColor = NO_COLOR;
- cmi.mSubscriptionButtonText = icpi.getSubscriptionButtonText();
- cmi.mCreditButtonText = icpi.getCreditsButtonText();
- // If present, use the deprecated attribute defined hint text.
- // These values may be overwritten by getHintText.
- cmi.mT9HintDescriptionNoCreditOrSub = icpi.getT9HintDescription();
- cmi.mT9HintDescriptionHasCreditOrSub = icpi.getT9HintDescription();
- cmi.mActionOneText = icpi.getActionOneTitle();
- cmi.mActionTwoText = icpi.getActionTwoTitle();
- cmi.mIsInCallProvider = true;
-
- cmi.mComponent = cn;
- cmi.mNudgeComponent = icpi.getNudgeComponent() == null ? null :
- ComponentName.unflattenFromString(icpi.getNudgeComponent());
- cmi.mDependentPackage = icpi.getDependentPackage();
- cmi.mName = icpi.getTitle();
- cmi.mSummary = icpi.getSummary();
- cmi.mAccountType = icpi.getAccountType();
- cmi.mAccountHandle = icpi.getAccountHandle();
- if (TextUtils.isEmpty(cmi.mAccountHandle)) {
- cmi.mAccountHandle = CallMethodUtils.lookupAccountHandle(
- getInstance().mContext, cmi.mAccountType);
- }
- cmi.mBrandIconId = icpi.getBrandIcon();
- cmi.mLoginIconId = icpi.getLoginIcon();
-
- cmi.mAccountType = icpi.getAccountType();
- mCallMethodInfos.put(cn, cmi);
- maybeBroadcastToSubscribers(this, apiCallbacks);
- }
- }
- };
- apiCallbacks.put(callback, result);
- }
-
- /**
- * Get our plugin enabled status
- * @param cn
- * @param apiCallbacks keeps track of the target callbacks before broadcast
- */
- protected static void getCallMethodStatus(final ComponentName cn, final
- HashMap<ResultCallback, PendingResult> apiCallbacks) {
- PendingResult result = getInstance().mInCallApi.getPluginStatus(getInstance().mClient, cn);
- ResultCallback callback = new ResultCallback<PluginStatusResult>() {
- @Override
- public void onResult(PluginStatusResult pluginStatusResult) {
- synchronized (mCallMethodInfos) {
- CallMethodInfo cmi = getCallMethodIfExists(cn);
- if (cmi != null) {
- cmi.mStatus = pluginStatusResult.status;
- mCallMethodInfos.put(cn, cmi);
- maybeBroadcastToSubscribers(this, apiCallbacks);
- }
- }
- }
- };
- apiCallbacks.put(callback, result);
- }
-
- /**
- * Send an event to the component
- * @param cn componentName to send the data to.
- */
- public static void shipAnalyticsToPlugin(final ComponentName cn, Event e) {
- if (cn == null) {
- return;
- }
- if (DEBUG) {
- Log.d(TAG, "componentName: " + cn.toShortString());
- Log.d(TAG, "Event: " + e.toString());
- }
- if (getInstance() == null ||
- getInstance().mInCallApi == null ||
- getInstance().mClient == null) {
- // For testing purposes, this might be null
- return;
- }
- getInstance().mInCallApi.sendAnalyticsEventToPlugin(getInstance().mClient, cn, e)
- .setResultCallback(new ResultCallback<Result>() {
- @Override
- public void onResult(Result result) {
- if (DEBUG) {
- Log.v(TAG, "Event sent with result: " + result.getStatus()
- .getStatusMessage());
- }
- }
- });
- }
-
- /**
- * Get the call method mime type
- * @param cn
- * @param apiCallbacks keeps track of the target callback before broadcast
- */
- protected static void getCallMethodMimeType(final ComponentName cn, final
- HashMap<ResultCallback, PendingResult> apiCallbacks) {
- PendingResult result = getInstance().mInCallApi.getCallableMimeType(getInstance().mClient,
- cn);
- ResultCallback callback = new ResultCallback<MimeTypeResult>() {
- @Override
- public void onResult(MimeTypeResult mimeTypeResult) {
- synchronized (mCallMethodInfos) {
- CallMethodInfo cmi = getCallMethodIfExists(cn);
- if (cmi != null) {
- cmi.mMimeType = mimeTypeResult.mimeType;
- mCallMethodInfos.put(cn, cmi);
- maybeBroadcastToSubscribers(this, apiCallbacks);
- }
- }
- }
- };
- apiCallbacks.put(callback, result);
- }
-
- /**
- * Get the call method mime type
- * @param cn
- * @param apiCallbacks keeps track of the target callback before broadcast
- */
- protected static void getCallMethodVideoCallableMimeType(final ComponentName cn, final
- HashMap<ResultCallback, PendingResult> apiCallbacks) {
- PendingResult result = getInstance().mInCallApi.getVideoCallableMimeType(getInstance()
- .mClient, cn);
- ResultCallback callback = new ResultCallback<MimeTypeResult>() {
- @Override
- public void onResult(MimeTypeResult mimeTypeResult) {
- synchronized (mCallMethodInfos) {
- CallMethodInfo cmi = getCallMethodIfExists(cn);
- if (cmi != null) {
- cmi.mVideoCallableMimeType = mimeTypeResult.mimeType;
- mCallMethodInfos.put(cn, cmi);
- maybeBroadcastToSubscribers(this, apiCallbacks);
- }
- }
- }
- };
- apiCallbacks.put(callback, result);
- }
-
- /**
- * Get the IM mime type
- * @param cn
- * @param apiCallbacks keeps track of the target callbacks before broadcast
- */
- protected static void getCallMethodImMimeType(final ComponentName cn, final
- HashMap<ResultCallback, PendingResult> apiCallbacks) {
- PendingResult result = getInstance().mInCallApi.getImMimeType(getInstance().mClient, cn);
- ResultCallback callback = new ResultCallback<MimeTypeResult>() {
- @Override
- public void onResult(MimeTypeResult mimeTypeResult) {
- synchronized (mCallMethodInfos) {
- CallMethodInfo cmi = getCallMethodIfExists(cn);
- if (cmi != null) {
- cmi.mImMimeType = mimeTypeResult.mimeType;
- mCallMethodInfos.put(cn, cmi);
- maybeBroadcastToSubscribers(this, apiCallbacks);
- }
- }
- }
- };
- apiCallbacks.put(callback, result);
- }
-
- /**
- * Get the Authentication state of the callmethod
- * @param cn
- * @param apiCallbacks keeps track of the target callbacks before broadcast
- */
- protected static void getCallMethodAuthenticated(final ComponentName cn, final
- HashMap<ResultCallback, PendingResult> apiCallbacks) {
- PendingResult result = getInstance().mInCallApi.getAuthenticationState(getInstance()
- .mClient, cn);
- ResultCallback callback = new ResultCallback<AuthenticationStateResult>() {
- @Override
- public void onResult(AuthenticationStateResult result) {
- synchronized (mCallMethodInfos) {
- CallMethodInfo cmi = getCallMethodIfExists(cn);
- if (cmi != null) {
- cmi.mIsAuthenticated = result.result == StatusCodes.AuthenticationState
- .LOGGED_IN;
- mCallMethodInfos.put(cn, cmi);
- maybeBroadcastToSubscribers(this, apiCallbacks);
- }
- }
- }
- };
- apiCallbacks.put(callback, result);
- }
-
- /**
- * Get the logged in account handle of the callmethod
- * @param cn
- * @param apiCallbacks keeps track of the target callbacks before broadcast
- */
- protected static void getCallMethodAccountHandle(final ComponentName cn, final
- HashMap<ResultCallback, PendingResult> apiCallbacks) {
- PendingResult result = getInstance().mInCallApi.getAccountHandle(getInstance().mClient, cn);
- ResultCallback callback = new ResultCallback<AccountHandleResult>() {
- @Override
- public void onResult(AccountHandleResult result) {
- synchronized (mCallMethodInfos) {
- CallMethodInfo cmi = getCallMethodIfExists(cn);
- if (cmi != null) {
- cmi.mAccountHandle = result.accountHandle;
- if (TextUtils.isEmpty(cmi.mAccountHandle)) {
- cmi.mAccountHandle =
- CallMethodUtils.lookupAccountHandle(
- getInstance().mContext, cmi.mAccountType);
- }
- mCallMethodInfos.put(cn, cmi);
- maybeBroadcastToSubscribers(this, apiCallbacks);
- }
- }
- }
- };
- apiCallbacks.put(callback, result);
- }
-
- /**
- * Get the settings intent for the callmethod
- * @param cn
- * @param apiCallbacks keeps track of the target callback counts before broadcast
- */
- private static void getSettingsIntent(final ComponentName cn, final
- HashMap<ResultCallback, PendingResult> apiCallbacks) {
- PendingResult result = getInstance().mInCallApi.getSettingsIntent(getInstance().mClient,
- cn);
- ResultCallback callback = new ResultCallback<PendingIntentResult>() {
- @Override
- public void onResult(PendingIntentResult pendingIntentResult) {
- synchronized (mCallMethodInfos) {
- CallMethodInfo cmi = getCallMethodIfExists(cn);
- if (cmi != null) {
- cmi.mSettingsIntent = pendingIntentResult.intent;
- mCallMethodInfos.put(cn, cmi);
- maybeBroadcastToSubscribers(this, apiCallbacks);
- }
- }
- }
- };
- apiCallbacks.put(callback, result);
- }
-
- /**
- * Get the hint texts for the callmethod
- * @param cn
- * @param apiCallbacks keeps track of the target callback counts before broadcast
- */
- private static void getHintText(final ComponentName cn,
- final HashMap<ResultCallback, PendingResult> apiCallbacks) {
- PendingResult result = getInstance().mInCallApi.getHintText(getInstance().mClient, cn);
- ResultCallback callback = new ResultCallback<HintTextResultResult>() {
- @Override
- public void onResult(HintTextResultResult hintTextResultResult) {
- if (hintTextResultResult != null) {
- HintTextResult result = hintTextResultResult.result;
- if (result != null) {
- synchronized (mCallMethodInfos) {
- CallMethodInfo cmi = getCallMethodIfExists(cn);
- if (cmi != null) {
- String hintText = result.getNoCreditOrSubscriptionHint();
- if (!TextUtils.isEmpty(hintText)) {
- cmi.mT9HintDescriptionNoCreditOrSub = hintText;
- }
-
- hintText = result.getHasCreditOrSubscriptionHint();
- if (!TextUtils.isEmpty(hintText)) {
- cmi.mT9HintDescriptionHasCreditOrSub = hintText;
- }
- mCallMethodInfos.put(cn, cmi);
- maybeBroadcastToSubscribers(this, apiCallbacks);
- }
- }
- }
- }
- }
- };
- apiCallbacks.put(callback, result);
- }
-
- private static void getCreditInfo(final ComponentName cn, final
- HashMap<ResultCallback, PendingResult> apiCallbacks) {
- PendingResult result = getInstance().mInCallApi.getCreditInfo(getInstance().mClient, cn);
- ResultCallback callback = new ResultCallback<GetCreditInfoResultResult>() {
- @Override
- public void onResult(GetCreditInfoResultResult getCreditInfoResultResult) {
- CallMethodInfo cmi = getCallMethodIfExists(cn);
- if (cmi != null) {
- GetCreditInfoResult gcir = getCreditInfoResultResult.result;
- if (gcir == null || gcir.creditInfo == null) {
- // Build zero credit dummy if no result found.
- cmi.mProviderCreditInfo =
- new CreditInfo(new CreditBalance(0, null), null);
- } else {
- cmi.mProviderCreditInfo = gcir.creditInfo;
- }
- mCallMethodInfos.put(cn, cmi);
- maybeBroadcastToSubscribers(this, apiCallbacks);
- }
- }
- };
- apiCallbacks.put(callback, result);
- }
-
- private static void getManageCreditsIntent(final ComponentName cn, final
- HashMap<ResultCallback, PendingResult> apiCallbacks) {
- PendingResult result = getInstance().mInCallApi.getManageCreditsIntent(getInstance()
- .mClient, cn);
- ResultCallback callback = new ResultCallback<PendingIntentResult>() {
- @Override
- public void onResult(PendingIntentResult pendingIntentResult) {
- CallMethodInfo cmi = getCallMethodIfExists(cn);
- if (cmi != null) {
- cmi.mManageCreditIntent = pendingIntentResult.intent;
- mCallMethodInfos.put(cn, cmi);
- maybeBroadcastToSubscribers(this, apiCallbacks);
- }
- }
- };
- apiCallbacks.put(callback, result);
- }
-
- private static void checkLowCreditConfig(final ComponentName cn, final
- HashMap<ResultCallback, PendingResult> apiCallbacks) {
- // find a nudge component if it exists for this package
- Intent nudgeIntent = new Intent("cyanogen.service.NUDGE_PROVIDER");
- nudgeIntent.setPackage(cn.getPackageName());
- List<ResolveInfo> resolved = getInstance().mContext.getPackageManager()
- .queryIntentServices(nudgeIntent, 0);
- if (resolved != null && !resolved.isEmpty()) {
- ResolveInfo result = resolved.get(0);
- ComponentName nudgeComponent = new ComponentName(result.serviceInfo.applicationInfo
- .packageName, result.serviceInfo.name);
- collectLowCreditConfig(cn, nudgeComponent, apiCallbacks);
- return;
- }
-
- // if a nudge component doesn't exist, just finish here
- maybeBroadcastToSubscribers(null, apiCallbacks);
- }
-
- private static void collectLowCreditConfig(final ComponentName pluginComponent, final
- ComponentName nudgeComponent, final HashMap<ResultCallback, PendingResult>
- apiCallbacks) {
- PendingResult result = NudgeServices.NudgeApi.getConfigurationForKey(getInstance().mClient,
- nudgeComponent, NudgeKey.INCALL_CREDIT_NUDGE);
- ResultCallback callback = new ResultCallback<BundleResult>() {
- @Override
- public void onResult(BundleResult bundleResult) {
- CallMethodInfo cmi = getCallMethodIfExists(pluginComponent);
- if (cmi != null) {
- if (bundleResult != null && bundleResult.bundle != null &&
- bundleResult.bundle.containsKey(NudgeKey
- .INCALL_PARAM_CREDIT_WARN)) {
- Object creditWarn = bundleResult.bundle.get(NudgeKey
- .INCALL_PARAM_CREDIT_WARN);
- if (creditWarn.getClass().equals(Integer.class)) {
- cmi.mCreditWarn = (Integer) creditWarn;
- } else if (creditWarn.getClass().equals(Float.class)) {
- cmi.mCreditWarn = (Float) creditWarn;
- } else {
- Log.e(TAG, "Invalid value for Credit Warn limit: " + creditWarn);
- }
- mCallMethodInfos.put(pluginComponent, cmi);
- }
- maybeBroadcastToSubscribers(this, apiCallbacks);
- }
- }
- };
- apiCallbacks.put(callback, result);
- }
-
- protected static void getLoginIntent(final ComponentName cn, final
- HashMap<ResultCallback, PendingResult> apiCallbacks) {
- PendingResult result = getInstance().mInCallApi.getLoginIntent(getInstance().mClient, cn);
- ResultCallback callback = new ResultCallback<PendingIntentResult>() {
- @Override
- public void onResult(PendingIntentResult pendingIntentResult) {
- synchronized (mCallMethodInfos) {
- CallMethodInfo cmi = getCallMethodIfExists(cn);
- if (cmi != null) {
- cmi.mLoginIntent = pendingIntentResult.intent;
- mCallMethodInfos.put(cn, cmi);
- maybeBroadcastToSubscribers(this, apiCallbacks);
- }
- }
- }
- };
- apiCallbacks.put(callback, result);
- }
-
- /**
- * Get the the contact directory search intent with a callback
- * @param cn
- * @param apiCallbacks keeps track of the target callbacks before broadcast
- */
- protected static void getDefaultDirectorySearchIntent(final ComponentName cn, final
- HashMap<ResultCallback, PendingResult> apiCallbacks) {
- PendingResult result = getInstance().mInCallApi.getDirectorySearchIntent(getInstance()
- .mClient, cn, Uri.parse(""));
- ResultCallback callback = new ResultCallback<PendingIntentResult>() {
- @Override
- public void onResult(PendingIntentResult pendingIntentResult) {
- synchronized (mCallMethodInfos) {
- CallMethodInfo cmi = getCallMethodIfExists(cn);
- if (cmi != null) {
- cmi.mDefaultDirectorySearchIntent = pendingIntentResult.intent;
- maybeBroadcastToSubscribers(this, apiCallbacks);
- }
- }
- }
- };
- apiCallbacks.put(callback, result);
- }
-
- /**
- * Get the the invite intent with a callback
- * @param cn
- * @param contactInfo contact info contains display name, phone, and contact Uri for lookup
- */
- protected static void getInviteIntent(final ComponentName cn, InCallContactInfo contactInfo) {
- getInstance().mInCallApi.getInviteIntent(getInstance().mClient, cn,
- contactInfo).setResultCallback(new ResultCallback<PendingIntentResult>() {
- @Override
- public void onResult(PendingIntentResult pendingIntentResult) {
- synchronized (mCallMethodInfos) {
- CallMethodInfo cmi = getCallMethodIfExists(cn);
- if (cmi != null) {
- cmi.mInviteIntent = pendingIntentResult.intent;
- }
- }
- }
- });
- }
-
- /**
- * Get the the contact directory search intent with a blocking call
- * @param cn
- * @param contactInfo contact info contains display name, phone and contact Uri for lookup
- */
-
- public static PendingIntent getInviteIntentSync(final ComponentName cn, InCallContactInfo
- contactInfo) {
- PendingIntentResult pendingIntentResult =
- getInstance().mInCallApi.getInviteIntent(getInstance().mClient, cn, contactInfo)
- .await();
- CallMethodInfo cmi = getCallMethodIfExists(cn);
- if (cmi != null) {
- cmi.mInviteIntent = pendingIntentResult.intent;
- }
- return cmi.mInviteIntent;
- }
-
- /**
- * Get the the contact directory search intent with a callback
- * @param cn
- * @param contactUri contact lookup Uri
- */
- protected static void getDirectorySearchIntent(final ComponentName cn, Uri contactUri) {
- getInstance().mInCallApi.getDirectorySearchIntent(getInstance().mClient, cn, contactUri)
- .setResultCallback(new ResultCallback<PendingIntentResult>() {
- @Override
- public void onResult(PendingIntentResult pendingIntentResult) {
- synchronized (mCallMethodInfos) {
- CallMethodInfo cmi = getCallMethodIfExists(cn);
- if (cmi != null) {
- cmi.mDirectorySearchIntent = pendingIntentResult.intent;
- }
- }
- }
- });
- }
-
- /**
- * Get the the contact directory search intent with a blocking call
- * @param cn
- * @param contactUri contact lookup Uri
- */
-
- public static PendingIntent getDirectorySearchIntentSync(final ComponentName cn, Uri
- contactUri) {
- PendingIntentResult pendingIntentResult =
- getInstance().mInCallApi.getDirectorySearchIntent(getInstance().mClient, cn,
- contactUri).await();
- CallMethodInfo cmi = getCallMethodIfExists(cn);
- if (cmi != null) {
- cmi.mDirectorySearchIntent = pendingIntentResult.intent;
- }
- return cmi.mDirectorySearchIntent;
- }
-
- protected static ComponentName getNudgeComponent(final ComponentName cn) {
- // find a nudge component if it exists for this package
- Intent nudgeIntent = new Intent("cyanogen.service.NUDGE_PROVIDER");
- nudgeIntent.setPackage(cn.getPackageName());
- List<ResolveInfo> resolved = getInstance().mContext.getPackageManager()
- .queryIntentServices(nudgeIntent, 0);
- if (resolved != null && !resolved.isEmpty()) {
- ResolveInfo result = resolved.get(0);
- return new ComponentName(result.serviceInfo.applicationInfo
- .packageName, result.serviceInfo.name);
- }
- // if a nudge component doesn't exist, just finish here
- return null;
- }
-
- protected static void getNudgeConfiguration(final ComponentName cn, final String key, final
- HashMap<ResultCallback, PendingResult> apiCallbacks) {
- final ComponentName nudgeComponent;
-
- CallMethodInfo cm = null;
- synchronized (mCallMethodInfos) {
- cm = getCallMethodIfExists(cn);
- }
- if (cm == null) {
- return;
- }
-
- if (cm.mNudgeComponent == null) {
- nudgeComponent = getNudgeComponent(cn);
- cm.mNudgeComponent = nudgeComponent;
- } else {
- nudgeComponent = cm.mNudgeComponent;
- }
- PendingResult result = NudgeServices.NudgeApi.getConfigurationForKey(getInstance()
- .mClient, nudgeComponent, key);
- ResultCallback callback = new ResultCallback<BundleResult>() {
- @Override
- public void onResult(BundleResult bundleResult) {
- synchronized (mCallMethodInfos) {
- CallMethodInfo cmi = getCallMethodIfExists(cn);
- if (bundleResult != null && bundleResult.bundle != null) {
- Bundle nudgeConfig = bundleResult.bundle;
- switch (key) {
- case NudgeKey.INCALL_CONTACT_FRAGMENT_LOGIN:
- cmi.mLoginSubtitle =
- nudgeConfig.getString(NudgeKey.NUDGE_PARAM_SUBTITLE, "");
- break;
- case NudgeKey.INCALL_CONTACT_CARD_LOGIN:
- cmi.mLoginNudgeEnable =
- nudgeConfig.getBoolean(NudgeKey.NUDGE_PARAM_ENABLED, true)
- &&
- PreferenceManager.getDefaultSharedPreferences
- (getInstance().mContext)
- .getBoolean(cn.getClassName() + "." + key,
- true);
- cmi.mLoginNudgeTitle =
- nudgeConfig.getString(NudgeKey.NUDGE_PARAM_TITLE);
- cmi.mLoginNudgeSubtitle =
- nudgeConfig.getString(NudgeKey.NUDGE_PARAM_SUBTITLE);
- cmi.mLoginNudgeActionText = nudgeConfig.getString(NudgeKey.
- NUDGE_PARAM_ACTION_TEXT);
- break;
- case NudgeKey.INCALL_CONTACT_CARD_DOWNLOAD:
- cmi.mInstallNudgeEnable =
- nudgeConfig.getBoolean(NudgeKey.NUDGE_PARAM_ENABLED, true)
- &&
- PreferenceManager.getDefaultSharedPreferences
- (getInstance().mContext)
- .getBoolean(cn.getClassName() + "." + key,
- true);
- cmi.mInstallNudgeTitle =
- nudgeConfig.getString(NudgeKey.NUDGE_PARAM_TITLE);
- cmi.mInstallNudgeSubtitle =
- nudgeConfig.getString(NudgeKey.NUDGE_PARAM_SUBTITLE);
- cmi.mInstallNudgeActionText = nudgeConfig.getString(NudgeKey.
- NUDGE_PARAM_ACTION_TEXT);
- break;
- default:
- break;
-
- }
- }
-
- maybeBroadcastToSubscribers(this, apiCallbacks);
- }
- }
- };
- apiCallbacks.put(callback, result);
- }
-
- public static Set<String> getAllEnabledVoiceMimeSet() {
- String[] mimes = getAllEnabledMimeTypes().split(",");
- HashSet<String> mimeSet = new HashSet<String>();
- if (mimes != null) {
- mimeSet.addAll(Arrays.asList(mimes));
- }
- return mimeSet;
- }
-
- public static Set<String> getAllEnabledVideoImMimeSet() {
- String[] videoMimes = getAllEnabledVideoCallableMimeTypes().split(",");
- String[] imMimes = getAllEnabledImMimeTypes().split(",");
- HashSet<String> mimeSet = new HashSet<String>();
-
- if (videoMimes != null) {
- mimeSet.addAll(Arrays.asList(videoMimes));
- }
- if (imMimes != null) {
- mimeSet.addAll(Arrays.asList(imMimes));
- }
- return mimeSet;
- }
-
- public static boolean infoReady() {
- return dataHasBeenBroadcastPreviously;
- }
-}