summaryrefslogtreecommitdiff
path: root/InCallUI
diff options
context:
space:
mode:
Diffstat (limited to 'InCallUI')
-rw-r--r--InCallUI/src/com/android/incallui/CallCardFragment.java31
-rw-r--r--InCallUI/src/com/android/incallui/CallCardPresenter.java55
-rw-r--r--InCallUI/src/com/android/incallui/CallHandlerService.java45
-rw-r--r--InCallUI/src/com/android/incallui/CallList.java98
-rw-r--r--InCallUI/src/com/android/incallui/InCallActivity.java20
5 files changed, 230 insertions, 19 deletions
diff --git a/InCallUI/src/com/android/incallui/CallCardFragment.java b/InCallUI/src/com/android/incallui/CallCardFragment.java
index fb60c0b03..2fb317221 100644
--- a/InCallUI/src/com/android/incallui/CallCardFragment.java
+++ b/InCallUI/src/com/android/incallui/CallCardFragment.java
@@ -16,20 +16,47 @@
package com.android.incallui;
-import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.TextView;
/**
* Fragment for call card.
*/
-public class CallCardFragment extends Fragment {
+public class CallCardFragment extends BaseFragment<CallCardPresenter>
+ implements CallCardPresenter.CallCardUi {
+
+ private TextView mPhoneNumber;
+
+ @Override
+ CallCardPresenter createPresenter() {
+ return new CallCardPresenter();
+ }
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.call_card_fragment, container, false);
}
+
+ @Override
+ public void onViewCreated(View view, Bundle savedInstanceState) {
+ mPhoneNumber = (TextView) view.findViewById(R.id.phoneNumber);
+
+ // This method call will begin the callbacks on CallCardUi. We need to ensure
+ // everything needed for the callbacks is set up before this is called.
+ getPresenter().onUiReady(this);
+ }
+
+ @Override
+ public void setNumber(String number) {
+ mPhoneNumber.setText(number);
+ }
+
+ @Override
+ public void setName(String name) {
+ }
+
}
diff --git a/InCallUI/src/com/android/incallui/CallCardPresenter.java b/InCallUI/src/com/android/incallui/CallCardPresenter.java
new file mode 100644
index 000000000..85f05341e
--- /dev/null
+++ b/InCallUI/src/com/android/incallui/CallCardPresenter.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.incallui;
+
+import com.android.services.telephony.common.Call;
+
+/**
+ * Presenter for the Call Card Fragment.
+ * This class listens for changes to CallList and passes it along to the fragment.
+ */
+public class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi>
+ implements CallList.Listener {
+
+ @Override
+ public void onUiReady(CallCardUi ui) {
+ super.onUiReady(ui);
+
+ CallList.getInstance().addListener(this);
+
+ // When UI is ready, manually trigger a change
+ onCallListChange(CallList.getInstance());
+ }
+
+ @Override
+ public void onCallListChange(CallList callList) {
+ Call call = callList.getIncomingOrActive();
+
+ if (call != null) {
+ getUi().setNumber(call.getNumber());
+ } else {
+ // When there is no longer an incoming/active call, we need to reset everything
+ // so that no data survives for the next call.
+ getUi().setNumber("");
+ }
+ }
+
+ public interface CallCardUi extends Ui {
+ public void setNumber(String number);
+ public void setName(String name);
+ }
+}
diff --git a/InCallUI/src/com/android/incallui/CallHandlerService.java b/InCallUI/src/com/android/incallui/CallHandlerService.java
index 127e57513..4a14dab8e 100644
--- a/InCallUI/src/com/android/incallui/CallHandlerService.java
+++ b/InCallUI/src/com/android/incallui/CallHandlerService.java
@@ -18,7 +18,9 @@ package com.android.incallui;
import android.app.Service;
import android.content.Intent;
+import android.os.Handler;
import android.os.IBinder;
+import android.os.Message;
import android.util.Log;
import com.android.services.telephony.common.Call;
@@ -35,13 +37,18 @@ public class CallHandlerService extends Service {
private static final String TAG = CallHandlerService.class.getSimpleName();
private static final boolean DBG = false; // TODO: Have a shared location for this.
+ private static final int ON_UPDATE_CALL = 1;
+ private static final int ON_UPDATE_MULTI_CALL = 2;
+
private CallList mCallList;
+ private Handler mMainHandler;
@Override
public void onCreate() {
super.onCreate();
- mCallList = new CallList();
+ mCallList = CallList.getInstance();
+ mMainHandler = new MainHandler();
}
@Override
@@ -63,21 +70,21 @@ public class CallHandlerService extends Service {
@Override
public void onIncomingCall(Call call) {
- mCallList.onUpdate(call);
-
final Intent intent = new Intent(getApplication(), InCallActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
+
+ mMainHandler.sendMessage(mMainHandler.obtainMessage(ON_UPDATE_CALL, 0, 0, call));
}
@Override
public void onDisconnect(Call call) {
- mCallList.onUpdate(call);
+ mMainHandler.sendMessage(mMainHandler.obtainMessage(ON_UPDATE_CALL, 0, 0, call));
}
@Override
public void onUpdate(List<Call> calls) {
- mCallList.onUpdate(calls);
+ mMainHandler.sendMessage(mMainHandler.obtainMessage(ON_UPDATE_MULTI_CALL, 0, 0, calls));
}
};
@@ -86,4 +93,32 @@ public class CallHandlerService extends Service {
Log.d(TAG, message);
}
}
+
+ /**
+ * Handles messages from the service so that they get executed on the main thread, where they
+ * can interact with UI.
+ */
+ private class MainHandler extends Handler {
+ MainHandler() {
+ super(getApplicationContext().getMainLooper(), null, true);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ executeMessage(msg);
+ }
+ }
+
+ private void executeMessage(Message msg) {
+ switch (msg.what) {
+ case ON_UPDATE_CALL:
+ mCallList.onUpdate((Call) msg.obj);
+ break;
+ case ON_UPDATE_MULTI_CALL:
+ mCallList.onUpdate((List<Call>) msg.obj);
+ break;
+ default:
+ break;
+ }
+ }
}
diff --git a/InCallUI/src/com/android/incallui/CallList.java b/InCallUI/src/com/android/incallui/CallList.java
index 5fe261946..ac3e3bfd5 100644
--- a/InCallUI/src/com/android/incallui/CallList.java
+++ b/InCallUI/src/com/android/incallui/CallList.java
@@ -16,14 +16,19 @@
package com.android.incallui;
+import com.google.android.collect.Lists;
import com.google.android.collect.Maps;
+import com.google.android.collect.Sets;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
+import android.util.Log;
+
import com.android.services.telephony.common.Call;
import java.util.HashMap;
import java.util.List;
+import java.util.Set;
/**
* Maintains the list of active calls received from CallHandlerService.
@@ -31,18 +36,89 @@ import java.util.List;
* changes to calls.
*/
public class CallList {
+ private static String TAG = CallList.class.getSimpleName();
+
+ private static CallList sInstance;
+
+ private final HashMap<Integer, Call> mCallMap = Maps.newHashMap();
+ private final Set<Listener> mListeners = Sets.newArraySet();
+
+ /**
+ * Static singleton accessor method.
+ */
+ public static synchronized CallList getInstance() {
+ if (sInstance == null) {
+ sInstance = new CallList();
+ }
+ return sInstance;
+ }
- final HashMap<Integer, Call> callMap = Maps.newHashMap();
+ /**
+ * Private constructor. Instance should only be acquired through getInstance().
+ */
+ private CallList() {
+ }
+ /**
+ * Called when a single call has changed.
+ */
public void onUpdate(Call call) {
updateCallInMap(call);
+
+ notifyListenersOfChange();
}
+ /**
+ * Called when multiple calls have changed.
+ */
public void onUpdate(List<Call> callsToUpdate) {
Preconditions.checkNotNull(callsToUpdate);
for (Call call : callsToUpdate) {
updateCallInMap(call);
}
+
+ notifyListenersOfChange();
+ }
+
+ public void addListener(Listener listener) {
+ Preconditions.checkNotNull(listener);
+ mListeners.add(listener);
+ }
+
+ public void removeListener(Listener listener) {
+ Preconditions.checkNotNull(listener);
+ mListeners.remove(listener);
+ }
+
+ /**
+ * TODO(klp): Change so that this function is not needed. Instead of assuming there is an active
+ * call, the code should rely on the status of a specific Call and allow the presenters to
+ * update the Call object when the active call changes.
+ */
+ public Call getIncomingOrActive() {
+ Call retval = null;
+
+ for (Call call : mCallMap.values()) {
+ if (call.getState() == Call.State.INCOMING) {
+ retval = call;
+ // incoming call takes precedence, cut out early.
+ break;
+ } else if (retval == null && call.getState() == Call.State.ACTIVE) {
+ retval = call;
+ }
+ }
+
+ return retval;
+ }
+
+ /**
+ * Sends a generic notification to all listeners that something has changed.
+ * It is up to the listeners to call back to determine what changed.
+ */
+ private void notifyListenersOfChange() {
+ for (Listener listener : mListeners) {
+ listener.onCallListChange(this);
+ }
}
private void updateCallInMap(Call call) {
@@ -50,15 +126,23 @@ public class CallList {
final Integer id = new Integer(call.getCallId());
- if (isCallActive(call)) {
- callMap.put(id, call);
- } else if (callMap.containsKey(id)) {
- callMap.remove(id);
+ if (!isCallDead(call)) {
+ mCallMap.put(id, call);
+ } else if (mCallMap.containsKey(id)) {
+ mCallMap.remove(id);
}
}
- private boolean isCallActive(Call call) {
+ private boolean isCallDead(Call call) {
final int state = call.getState();
- return Call.State.IDLE != state && Call.State.INVALID != state;
+ return Call.State.IDLE == state || Call.State.INVALID == state;
+ }
+
+ /**
+ * Listener interface for any class that wants to be notified of changes
+ * to the call list.
+ */
+ public interface Listener {
+ public void onCallListChange(CallList callList);
}
}
diff --git a/InCallUI/src/com/android/incallui/InCallActivity.java b/InCallUI/src/com/android/incallui/InCallActivity.java
index 71e981b94..04f1f09b1 100644
--- a/InCallUI/src/com/android/incallui/InCallActivity.java
+++ b/InCallUI/src/com/android/incallui/InCallActivity.java
@@ -38,6 +38,7 @@ public class InCallActivity extends Activity implements CallButtonPresenter.EndC
private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
private CallButtonPresenter mCallButtonPresenter;
+ private CallCardPresenter mCallCardPresenter;
@Override
protected void onCreate(Bundle icicle) {
@@ -57,6 +58,8 @@ public class InCallActivity extends Activity implements CallButtonPresenter.EndC
// Inflate everything in incall_screen.xml and add it to the screen.
setContentView(R.layout.incall_screen);
+ initializeInCall();
+
logD("onCreate(): exit");
}
@@ -65,11 +68,6 @@ public class InCallActivity extends Activity implements CallButtonPresenter.EndC
protected void onResume() {
logD("onResume()...");
- final CallButtonFragment callButtonFragment = (CallButtonFragment) getFragmentManager()
- .findFragmentById(R.id.callButtonFragment);
- mCallButtonPresenter = callButtonFragment.getPresenter();
- mCallButtonPresenter.setEndCallListener(this);
-
// TODO(klp): create once and reset when needed.
final AnswerFragment answerFragment = new AnswerFragment();
final AnswerPresenter presenter = answerFragment.getPresenter();
@@ -207,8 +205,20 @@ public class InCallActivity extends Activity implements CallButtonPresenter.EndC
return super.onKeyDown(keyCode, event);
}
+ private void initializeInCall() {
+
+ final CallButtonFragment callButtonFragment = (CallButtonFragment) getFragmentManager()
+ .findFragmentById(R.id.callButtonFragment);
+ mCallButtonPresenter = callButtonFragment.getPresenter();
+ mCallButtonPresenter.setEndCallListener(this);
+
+ final CallCardFragment callCardFragment = (CallCardFragment) getFragmentManager()
+ .findFragmentById(R.id.callCardFragment);
+ }
+
private void toast(String text) {
final Toast toast = Toast.makeText(this, text, Toast.LENGTH_SHORT);
+
toast.show();
}