Implement proper stream selection in UI and stopStreaming
Modify sample UI to be able to select an active stream
Implement functionality for stopStreaming
Test: testapps
Change-Id: I4b88b36ba4f8313848b1a956aea611ce040574d7
diff --git a/testapps/EmbmsServiceTestApp/src/com/android/phone/testapps/embmsmw/AppActiveStreams.java b/testapps/EmbmsServiceTestApp/src/com/android/phone/testapps/embmsmw/AppActiveStreams.java
index f37a340..35d18e9 100644
--- a/testapps/EmbmsServiceTestApp/src/com/android/phone/testapps/embmsmw/AppActiveStreams.java
+++ b/testapps/EmbmsServiceTestApp/src/com/android/phone/testapps/embmsmw/AppActiveStreams.java
@@ -77,8 +77,10 @@
if (entry != null) {
try {
- entry.setState(StreamingService.STATE_STOPPED);
- entry.getCallback().streamStateChanged(StreamingService.STATE_STOPPED);
+ if (entry.getState() != StreamingService.STATE_STOPPED) {
+ entry.setState(StreamingService.STATE_STOPPED);
+ entry.getCallback().streamStateChanged(StreamingService.STATE_STOPPED);
+ }
} catch (RemoteException e) {
dispose(serviceId);
}
diff --git a/testapps/EmbmsServiceTestApp/src/com/android/phone/testapps/embmsmw/EmbmsTestStreamingService.java b/testapps/EmbmsServiceTestApp/src/com/android/phone/testapps/embmsmw/EmbmsTestStreamingService.java
index 0693292..9758d49 100644
--- a/testapps/EmbmsServiceTestApp/src/com/android/phone/testapps/embmsmw/EmbmsTestStreamingService.java
+++ b/testapps/EmbmsServiceTestApp/src/com/android/phone/testapps/embmsmw/EmbmsTestStreamingService.java
@@ -156,6 +156,16 @@
}
@Override
+ public void stopStreaming(String appName, int subscriptionId, String serviceId) {
+ StreamingAppIdentifier appKey =
+ new StreamingAppIdentifier(Binder.getCallingUid(), appName, subscriptionId);
+ checkInitialized(appKey);
+ checkServiceExists(serviceId);
+
+ mHandler.post(() -> StreamStateTracker.stopStreaming(appKey, serviceId));
+ }
+
+ @Override
public void disposeStream(String appName, int subscriptionId, String serviceId) {
StreamingAppIdentifier appKey =
new StreamingAppIdentifier(Binder.getCallingUid(), appName, subscriptionId);
diff --git a/testapps/EmbmsServiceTestApp/src/com/android/phone/testapps/embmsmw/StreamStateTracker.java b/testapps/EmbmsServiceTestApp/src/com/android/phone/testapps/embmsmw/StreamStateTracker.java
index c5496e8..e340b11 100644
--- a/testapps/EmbmsServiceTestApp/src/com/android/phone/testapps/embmsmw/StreamStateTracker.java
+++ b/testapps/EmbmsServiceTestApp/src/com/android/phone/testapps/embmsmw/StreamStateTracker.java
@@ -18,12 +18,15 @@
import android.telephony.mbms.IStreamingServiceCallback;
import android.telephony.mbms.StreamingService;
+import android.util.Log;
import java.util.HashMap;
import java.util.Map;
// Singleton that keeps track of streaming states for all apps using the middleware.
public class StreamStateTracker {
+ private static final String LOG_TAG = "MbmsStreamStateTracker";
+
private static final Map<StreamingAppIdentifier, AppActiveStreams>
sPerAppStreamStates = new HashMap<>();
@@ -47,6 +50,7 @@
}
public static void stopStreaming(StreamingAppIdentifier appIdentifier, String serviceId) {
+ Log.i(LOG_TAG, "Stopping stream " + serviceId);
AppActiveStreams appStreams = sPerAppStreamStates.get(appIdentifier);
if (appStreams == null) {
// It was never started, so don't bother stopping.
diff --git a/testapps/EmbmsTestStreamingApp/res/layout/activity_main.xml b/testapps/EmbmsTestStreamingApp/res/layout/activity_main.xml
index 47e9807..c1cc539 100644
--- a/testapps/EmbmsTestStreamingApp/res/layout/activity_main.xml
+++ b/testapps/EmbmsTestStreamingApp/res/layout/activity_main.xml
@@ -29,40 +29,81 @@
android:id="@+id/curr_streaming_uri"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
+ <TextView
+ android:id="@+id/tracked_streams_label"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/tracked_streams_label"/>
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+ <Spinner
+ android:id="@+id/curr_streams"
+ android:layout_width="0dp"
+ android:layout_weight="1"
+ android:layout_height="match_parent"/>
+ <TextView
+ android:id="@+id/stream_state"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"/>
+ </LinearLayout>
+ <TextView
+ android:id="@+id/available_services_label"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/available_streaming_services_label"/>
<Spinner
android:id="@+id/available_streaming_services"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:label="@string/available_streaming_services_label"/>
+ android:layout_height="wrap_content"/>
<GridLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:columnCount="2"
android:orientation="vertical" >
<Button
android:id="@+id/bind_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:layout_row="0"
+ android:layout_column="0"
android:text="@string/bind_button" />
<Button
android:id="@+id/get_streaming_services_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:layout_row="0"
+ android:layout_column="1"
android:text="@string/get_streaming_services_button" />
<Button
android:id="@+id/start_streaming_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:layout_row="1"
+ android:layout_column="0"
android:text="@string/start_streaming_button" />
<Button
+ android:id="@+id/stop_streaming_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_row="1"
+ android:layout_column="1"
+ android:text="@string/stop_streaming_button" />
+ <Button
android:id="@+id/dispose_stream_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:layout_row="2"
+ android:layout_column="0"
android:text="@string/dispose_stream_button" />
<Button
android:id="@+id/dispose_manager_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:layout_row="2"
+ android:layout_column="1"
android:text="@string/dispose_manager_button" />
</GridLayout>
</LinearLayout>
diff --git a/testapps/EmbmsTestStreamingApp/res/values/donottranslate_strings.xml b/testapps/EmbmsTestStreamingApp/res/values/donottranslate_strings.xml
index 58518cd..606fa25 100644
--- a/testapps/EmbmsTestStreamingApp/res/values/donottranslate_strings.xml
+++ b/testapps/EmbmsTestStreamingApp/res/values/donottranslate_strings.xml
@@ -17,10 +17,12 @@
<resources>
<string name="bind_button">Bind to service</string>
- <string name="streaming_uri_label">Current Streaming URI</string>
+ <string name="streaming_uri_label">Current Streaming URIs</string>
<string name="get_streaming_services_button">Get streaming services</string>
<string name="start_streaming_button">Start Streaming</string>
+ <string name="stop_streaming_button">Stop Streaming</string>
<string name="available_streaming_services_label">Available Streaming Services</string>
<string name="dispose_stream_button">Dispose latest stream</string>
<string name="dispose_manager_button">Dispose streaming manager</string>
+ <string name="tracked_streams_label">Tracked Streams</string>
</resources>
\ No newline at end of file
diff --git a/testapps/EmbmsTestStreamingApp/src/com/android/phone/testapps/embmsfrontend/EmbmsTestStreamingApp.java b/testapps/EmbmsTestStreamingApp/src/com/android/phone/testapps/embmsfrontend/EmbmsTestStreamingApp.java
index df6396e..c310064 100644
--- a/testapps/EmbmsTestStreamingApp/src/com/android/phone/testapps/embmsfrontend/EmbmsTestStreamingApp.java
+++ b/testapps/EmbmsTestStreamingApp/src/com/android/phone/testapps/embmsfrontend/EmbmsTestStreamingApp.java
@@ -25,6 +25,7 @@
import android.telephony.MbmsStreamingManager;
import android.telephony.mbms.MbmsException;
import android.telephony.mbms.MbmsStreamingManagerCallback;
+import android.telephony.mbms.StreamingService;
import android.telephony.mbms.StreamingServiceInfo;
import android.view.View;
import android.view.ViewGroup;
@@ -39,6 +40,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
public class EmbmsTestStreamingApp extends Activity {
private static final String APP_NAME = "StreamingApp1";
@@ -87,12 +89,38 @@
}
}
+ private final class TrackedStreamAdapter extends ArrayAdapter<String> {
+ public TrackedStreamAdapter(Context context) {
+ super(context, android.R.layout.simple_spinner_item);
+ setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ String serviceId = getItem(position);
+ StreamingServiceTracker tracker = mStreamingServiceTrackerById.get(serviceId);
+ TextView result = new TextView(EmbmsTestStreamingApp.this);
+ result.setText(tracker == null ? "" : tracker.toString());
+ return result;
+ }
+
+ @Override
+ public View getDropDownView(int position, View convertView, ViewGroup parent) {
+ String serviceId = getItem(position);
+ StreamingServiceTracker tracker = mStreamingServiceTrackerById.get(serviceId);
+ TextView result = new TextView(EmbmsTestStreamingApp.this);
+ result.setText(tracker.toString());
+ return result;
+ }
+ }
+
private MbmsStreamingManager mStreamingManager = null;
private Handler mHandler;
private HandlerThread mHandlerThread;
- private StreamingServiceTracker mLatestStream = null;
+ private TrackedStreamAdapter mTrackedStreamingServiceAdapter;
+ private Spinner mStreamSelector;
private StreamingServiceInfoAdapter mStreamingServicesDisplayAdapter;
private final Map<String, StreamingServiceTracker> mStreamingServiceTrackerById =
new HashMap<>();
@@ -107,6 +135,7 @@
mHandler = new Handler(mHandlerThread.getLooper());
mStreamingServicesDisplayAdapter =
new StreamingServiceInfoAdapter(this, android.R.layout.simple_spinner_item);
+ mTrackedStreamingServiceAdapter = new TrackedStreamAdapter(this);
Button bindButton = (Button) findViewById(R.id.bind_button);
bindButton.setOnClickListener((view) ->
@@ -147,17 +176,24 @@
mStreamingServicesDisplayAdapter.setDropDownViewResource(
android.R.layout.simple_spinner_dropdown_item);
serviceSelector.setAdapter(mStreamingServicesDisplayAdapter);
- serviceSelector.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
+
+ mStreamSelector = (Spinner) findViewById(R.id.curr_streams);
+ mTrackedStreamingServiceAdapter.setDropDownViewResource(
+ android.R.layout.simple_spinner_dropdown_item);
+ mStreamSelector.setAdapter(mTrackedStreamingServiceAdapter);
+ mStreamSelector.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
- StreamingServiceInfo info =
- (StreamingServiceInfo) serviceSelector.getItemAtPosition(position);
- String toastText = "Service selected: " + info.getNames().get(info.getLocale());
- Toast.makeText(EmbmsTestStreamingApp.this, toastText, Toast.LENGTH_SHORT).show();
+ String serviceId = (String) mStreamSelector.getItemAtPosition(position);
+ StreamingServiceTracker tracker = mStreamingServiceTrackerById.get(serviceId);
+
+ setStreamStateDisplay(String.valueOf(tracker.getState()));
+ setUriDisplay(tracker.getUri());
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
+ clearStateAndUriDisplay();
}
});
@@ -177,30 +213,43 @@
}
StreamingServiceTracker tracker = new StreamingServiceTracker(this, serviceInfo);
- tracker.startStreaming(mStreamingManager);
- mStreamingServiceTrackerById.put(serviceInfo.getServiceId(), tracker);
- mLatestStream = tracker;
+ if (tracker.startStreaming(mStreamingManager)) {
+ mStreamingServiceTrackerById.put(serviceInfo.getServiceId(), tracker);
+ mTrackedStreamingServiceAdapter.add(serviceInfo.getServiceId());
+ }
+ });
+
+ Button stopStreamingButton = (Button) findViewById(R.id.stop_streaming_button);
+ stopStreamingButton.setOnClickListener((view) -> {
+ if (getSelectedTrackedStream() == null) {
+ Toast.makeText(EmbmsTestStreamingApp.this,
+ "No streams selected", Toast.LENGTH_SHORT).show();
+ return;
+ }
+ StreamingServiceTracker stream = getSelectedTrackedStream();
+ stream.stopStreaming();
});
Button disposeStreamButton = (Button) findViewById(R.id.dispose_stream_button);
disposeStreamButton.setOnClickListener((view) -> {
- if (mLatestStream == null) {
+ if (getSelectedTrackedStream() == null) {
Toast.makeText(EmbmsTestStreamingApp.this,
- "No streams active", Toast.LENGTH_SHORT).show();
+ "No streams selected", Toast.LENGTH_SHORT).show();
return;
}
- mLatestStream.dispose();
- mStreamingServiceTrackerById.remove(mLatestStream.getServiceId());
- TextView uriField = (TextView) findViewById(R.id.curr_streaming_uri);
- uriField.setText("");
- mLatestStream = null;
+ clearStateAndUriDisplay();
+ StreamingServiceTracker stream = getSelectedTrackedStream();
+ mTrackedStreamingServiceAdapter.remove(stream.getServiceId());
+ mStreamingServiceTrackerById.remove(stream.getServiceId());
+ stream.dispose();
});
Button disposeManagerButton = (Button) findViewById(R.id.dispose_manager_button);
disposeManagerButton.setOnClickListener((view) -> {
- TextView uriField = (TextView) findViewById(R.id.curr_streaming_uri);
- uriField.setText("");
+ clearStateAndUriDisplay();
+ mTrackedStreamingServiceAdapter.clear();
mStreamingServicesDisplayAdapter.update(Collections.emptyList());
+ mStreamingServiceTrackerById.clear();
mStreamingManager.dispose();
});
}
@@ -215,10 +264,39 @@
runOnUiThread(() -> mStreamingServicesDisplayAdapter.update(services));
}
- public void updateUriInUi(Uri uri) {
+ private StreamingServiceTracker getSelectedTrackedStream() {
+ String serviceId = (String) mStreamSelector.getSelectedItem();
+ return mStreamingServiceTrackerById.get(serviceId);
+ }
+
+ private void setUriDisplay(Uri uri) {
runOnUiThread(() -> {
TextView uriField = (TextView) findViewById(R.id.curr_streaming_uri);
uriField.setText(uri.toSafeString());
});
}
+
+ private void setStreamStateDisplay(String stateString) {
+ runOnUiThread(() -> {
+ TextView uriField = (TextView) findViewById(R.id.stream_state);
+ uriField.setText(stateString);
+ });
+ }
+
+ private void clearStateAndUriDisplay() {
+ setUriDisplay(Uri.EMPTY);
+ setStreamStateDisplay("");
+ }
+
+ public void updateUri() {
+ Uri uri = getSelectedTrackedStream() == null ?
+ Uri.EMPTY : getSelectedTrackedStream().getUri();
+ setUriDisplay(uri);
+ }
+
+ public void updateStreamingState() {
+ String stateString = getSelectedTrackedStream() == null ?
+ "" : String.valueOf(getSelectedTrackedStream().getState());
+ setStreamStateDisplay(stateString);
+ }
}
diff --git a/testapps/EmbmsTestStreamingApp/src/com/android/phone/testapps/embmsfrontend/StreamingServiceTracker.java b/testapps/EmbmsTestStreamingApp/src/com/android/phone/testapps/embmsfrontend/StreamingServiceTracker.java
index 512c119..c0b12cb 100644
--- a/testapps/EmbmsTestStreamingApp/src/com/android/phone/testapps/embmsfrontend/StreamingServiceTracker.java
+++ b/testapps/EmbmsTestStreamingApp/src/com/android/phone/testapps/embmsfrontend/StreamingServiceTracker.java
@@ -42,20 +42,34 @@
private final EmbmsTestStreamingApp mActivity;
private final StreamingServiceInfo mStreamingServiceInfo;
private StreamingService mStreamingService;
- private int mState;
+
+ private int mState = StreamingService.STATE_STOPPED;
+ private Uri mStreamingUri = Uri.EMPTY;
public StreamingServiceTracker(EmbmsTestStreamingApp appActivity, StreamingServiceInfo info) {
mActivity = appActivity;
mStreamingServiceInfo = info;
}
- public void startStreaming(MbmsStreamingManager streamingManager) {
+ public boolean startStreaming(MbmsStreamingManager streamingManager) {
try {
mStreamingService =
streamingManager.startStreaming(mStreamingServiceInfo, new Callback());
+ return true;
} catch (MbmsException e) {
Toast.makeText(mActivity,
- "Error starting streaming" + e.getErrorCode(),
+ "Error starting streaming: " + e.getErrorCode(),
+ Toast.LENGTH_SHORT).show();
+ }
+ return false;
+ }
+
+ public void stopStreaming() {
+ try {
+ mStreamingService.stopStreaming();
+ } catch (MbmsException e) {
+ Toast.makeText(mActivity,
+ "Error stopping streaming: " + e.getErrorCode(),
Toast.LENGTH_SHORT).show();
}
}
@@ -74,17 +88,19 @@
return mStreamingServiceInfo.getServiceId();
}
+ public int getState() {
+ return mState;
+ }
+
+ public Uri getUri() {
+ return mStreamingUri;
+ }
+
private void onStreamStateChanged(int state) {
- String toastMessage = "Stream "
- + mStreamingServiceInfo.getNames().get(mStreamingServiceInfo.getLocale())
- + " has entered state "
- + state;
- mActivity.runOnUiThread(() ->
- Toast.makeText(mActivity, toastMessage, Toast.LENGTH_SHORT).show());
if (state == StreamingService.STATE_STARTED && mState != StreamingService.STATE_STARTED) {
try {
- Uri streamingUri = mStreamingService.getPlaybackUri();
- mActivity.updateUriInUi(streamingUri);
+ mStreamingUri = mStreamingService.getPlaybackUri();
+ mActivity.updateUri();
} catch (MbmsException e) {
String errorToast = "Got error " + e.getErrorCode() + " while getting uri";
mActivity.runOnUiThread(() ->
@@ -92,5 +108,11 @@
}
}
mState = state;
+ mActivity.updateStreamingState();
+ }
+
+ @Override
+ public String toString() {
+ return "Tracked service with ID " + getServiceId();
}
}