summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build/sdk.atree1
-rw-r--r--samples/Support7Demos/src/com/example/android/supportv7/widget/AnimatedRecyclerView.java10
-rw-r--r--samples/Support7Demos/src/com/example/android/supportv7/widget/BaseLayoutManagerActivity.java5
-rw-r--r--samples/Support7Demos/src/com/example/android/supportv7/widget/GridLayoutManagerActivity.java6
-rw-r--r--samples/Support7Demos/src/com/example/android/supportv7/widget/RecyclerViewActivity.java5
-rw-r--r--samples/SupportLeanbackDemos/AndroidManifest.xml1
-rw-r--r--samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlayFragment.java504
-rw-r--r--samples/browseable/MediaBrowserService/res/drawable-night-xxhdpi/ic_star_off.pngbin3201 -> 0 bytes
-rw-r--r--samples/browseable/MediaBrowserService/res/drawable-night-xxhdpi/ic_star_on.pngbin4058 -> 0 bytes
-rw-r--r--samples/browseable/MediaBrowserService/res/drawable-xxhdpi/ic_star_off.pngbin3305 -> 4835 bytes
-rw-r--r--samples/browseable/MediaBrowserService/res/drawable-xxhdpi/ic_star_on.pngbin4131 -> 3309 bytes
-rw-r--r--samples/browseable/MediaBrowserService/src/com.example.android.mediabrowserservice/MusicPlayerActivity.java4
-rw-r--r--samples/browseable/MediaBrowserService/src/com.example.android.mediabrowserservice/MusicService.java21
-rw-r--r--samples/browseable/MessagingService/res/layout-land/fragment_message_me.xml1
-rw-r--r--samples/browseable/MessagingService/res/layout/fragment_message_me.xml1
-rw-r--r--samples/browseable/MessagingService/src/com.example.android.messagingservice/Conversations.java8
-rw-r--r--samples/browseable/SpeedTracker/Application/AndroidManifest.xml2
-rw-r--r--samples/browseable/SpeedTracker/Application/res/values-v21/template-styles.xml22
-rw-r--r--sdk/platform_source.prop_template2
19 files changed, 341 insertions, 252 deletions
diff --git a/build/sdk.atree b/build/sdk.atree
index 8c678a895..124fc8855 100644
--- a/build/sdk.atree
+++ b/build/sdk.atree
@@ -328,6 +328,7 @@ developers/build/prebuilts/gradle/SkeletonWearableApp samples/${PLATFO
developers/build/prebuilts/gradle/SpeedTracker samples/${PLATFORM_NAME}/wearable/SpeedTracker
developers/build/prebuilts/gradle/SynchronizedNotifications samples/${PLATFORM_NAME}/wearable/SynchronizedNotifications
developers/build/prebuilts/gradle/Timer samples/${PLATFORM_NAME}/wearable/Timer
+developers/build/prebuilts/gradle/WatchFace samples/${PLATFORM_NAME}/wearable/WatchFace
developers/build/prebuilts/gradle/WatchViewStub samples/${PLATFORM_NAME}/wearable/WatchViewStub
# Old sample tree
diff --git a/samples/Support7Demos/src/com/example/android/supportv7/widget/AnimatedRecyclerView.java b/samples/Support7Demos/src/com/example/android/supportv7/widget/AnimatedRecyclerView.java
index b503bcf0e..4c56933e7 100644
--- a/samples/Support7Demos/src/com/example/android/supportv7/widget/AnimatedRecyclerView.java
+++ b/samples/Support7Demos/src/com/example/android/supportv7/widget/AnimatedRecyclerView.java
@@ -124,8 +124,12 @@ public class AnimatedRecyclerView extends Activity {
public void itemClicked(View view) {
ViewGroup parent = (ViewGroup) view;
MyViewHolder holder = (MyViewHolder) mRecyclerView.getChildViewHolder(parent);
+ final int position = holder.getAdapterPosition();
+ if (position == RecyclerView.NO_POSITION) {
+ return;
+ }
mAdapter.toggleExpanded(holder);
- mAdapter.notifyItemChanged(holder.getPosition());
+ mAdapter.notifyItemChanged(position);
}
public void deleteItem(View view) {
@@ -240,7 +244,7 @@ public class AnimatedRecyclerView extends Activity {
if (lastVisibleView != null) {
RecyclerView.LayoutParams lastParams =
(RecyclerView.LayoutParams) lastVisibleView.getLayoutParams();
- int lastPosition = lastParams.getViewPosition();
+ int lastPosition = lastParams.getViewLayoutPosition();
final List<RecyclerView.ViewHolder> previousViews = recycler.getScrapList();
count = previousViews.size();
for (int i = 0; i < count; ++i) {
@@ -250,7 +254,7 @@ public class AnimatedRecyclerView extends Activity {
if (params.isItemRemoved()) {
continue;
}
- int position = params.getViewPosition();
+ int position = params.getViewLayoutPosition();
int newTop;
if (position < mFirstPosition) {
newTop = view.getHeight() * (position - mFirstPosition);
diff --git a/samples/Support7Demos/src/com/example/android/supportv7/widget/BaseLayoutManagerActivity.java b/samples/Support7Demos/src/com/example/android/supportv7/widget/BaseLayoutManagerActivity.java
index 0a6ac6d36..4bb64f4b1 100644
--- a/samples/Support7Demos/src/com/example/android/supportv7/widget/BaseLayoutManagerActivity.java
+++ b/samples/Support7Demos/src/com/example/android/supportv7/widget/BaseLayoutManagerActivity.java
@@ -84,11 +84,10 @@ abstract public class BaseLayoutManagerActivity<T extends RecyclerView.LayoutMan
vh.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
- final int pos = vh.getPosition();
- if (pos + 1 < getItemCount()) {
+ final int pos = vh.getAdapterPosition();
+ if (pos != RecyclerView.NO_POSITION && pos + 1 < getItemCount()) {
swap(pos, pos + 1);
}
- notifyItemChanged(pos);
}
});
return vh;
diff --git a/samples/Support7Demos/src/com/example/android/supportv7/widget/GridLayoutManagerActivity.java b/samples/Support7Demos/src/com/example/android/supportv7/widget/GridLayoutManagerActivity.java
index 00cfbf86a..ef25c0b0e 100644
--- a/samples/Support7Demos/src/com/example/android/supportv7/widget/GridLayoutManagerActivity.java
+++ b/samples/Support7Demos/src/com/example/android/supportv7/widget/GridLayoutManagerActivity.java
@@ -119,11 +119,13 @@ public class GridLayoutManagerActivity extends BaseLayoutManagerActivity<GridLay
vh.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
- final int pos = vh.getPosition();
+ final int pos = vh.getAdapterPosition();
+ if (pos == RecyclerView.NO_POSITION) {
+ return;
+ }
if (pos + 1 < getItemCount()) {
swap(pos, pos + 1);
}
- notifyItemChanged(pos);
}
});
return vh;
diff --git a/samples/Support7Demos/src/com/example/android/supportv7/widget/RecyclerViewActivity.java b/samples/Support7Demos/src/com/example/android/supportv7/widget/RecyclerViewActivity.java
index 747992b19..38b50bd3a 100644
--- a/samples/Support7Demos/src/com/example/android/supportv7/widget/RecyclerViewActivity.java
+++ b/samples/Support7Demos/src/com/example/android/supportv7/widget/RecyclerViewActivity.java
@@ -56,7 +56,10 @@ public class RecyclerViewActivity extends Activity {
vh.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
- final int pos = vh.getPosition();
+ final int pos = vh.getAdapterPosition();
+ if (pos == RecyclerView.NO_POSITION) {
+ return;
+ }
if (pos + 1 < getItemCount()) {
swap(pos, pos + 1);
}
diff --git a/samples/SupportLeanbackDemos/AndroidManifest.xml b/samples/SupportLeanbackDemos/AndroidManifest.xml
index 68016c52a..e9fc37c63 100644
--- a/samples/SupportLeanbackDemos/AndroidManifest.xml
+++ b/samples/SupportLeanbackDemos/AndroidManifest.xml
@@ -10,6 +10,7 @@
android:label="@string/app_name"
android:icon="@drawable/ic_launcher"
android:banner="@drawable/ic_launcher"
+ android:supportsRtl="true"
android:theme="@style/Theme.Example.Leanback">
<activity android:name="MainActivity"
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlayFragment.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlayFragment.java
index f11c84389..c37ca204e 100644
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlayFragment.java
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlayFragment.java
@@ -13,299 +13,395 @@
*/
package com.example.android.leanback;
-import java.util.ArrayList;
-
import android.content.Context;
-import android.content.res.Resources;
import android.graphics.drawable.Drawable;
+import android.media.session.MediaController;
+import android.media.session.MediaSessionManager;
+import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
+import android.os.RemoteException;
+import android.support.v17.leanback.app.MediaControllerGlue;
+import android.support.v17.leanback.app.PlaybackControlGlue;
import android.support.v17.leanback.widget.Action;
import android.support.v17.leanback.widget.ArrayObjectAdapter;
-import android.support.v17.leanback.widget.ClassPresenterSelector;
-import android.support.v17.leanback.widget.AbstractDetailsDescriptionPresenter;
import android.support.v17.leanback.widget.PlaybackControlsRow;
-import android.support.v17.leanback.widget.PlaybackControlsRow.PlayPauseAction;
import android.support.v17.leanback.widget.PlaybackControlsRow.RepeatAction;
import android.support.v17.leanback.widget.PlaybackControlsRow.ThumbsUpAction;
import android.support.v17.leanback.widget.PlaybackControlsRow.ThumbsDownAction;
-import android.support.v17.leanback.widget.PlaybackControlsRow.ShuffleAction;
-import android.support.v17.leanback.widget.PlaybackControlsRow.SkipNextAction;
-import android.support.v17.leanback.widget.PlaybackControlsRow.SkipPreviousAction;
import android.support.v17.leanback.widget.PlaybackControlsRowPresenter;
import android.support.v17.leanback.widget.HeaderItem;
-import android.support.v17.leanback.widget.VerticalGridView;
+import android.support.v17.leanback.widget.PresenterSelector;
import android.support.v17.leanback.widget.Row;
import android.support.v17.leanback.widget.ListRow;
import android.support.v17.leanback.widget.Presenter;
import android.support.v17.leanback.widget.RowPresenter;
import android.support.v17.leanback.widget.ListRowPresenter;
-import android.support.v17.leanback.widget.OnActionClickedListener;
import android.support.v17.leanback.widget.OnItemViewSelectedListener;
import android.support.v17.leanback.widget.OnItemViewClickedListener;
import android.support.v17.leanback.widget.ControlButtonPresenterSelector;
+import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
+import android.support.v4.media.session.MediaControllerCompat;
+import android.support.v4.media.session.MediaSessionCompat;
import android.util.Log;
import android.widget.Toast;
+import java.util.List;
+
public class PlaybackOverlayFragment extends android.support.v17.leanback.app.PlaybackOverlayFragment {
private static final String TAG = "leanback.PlaybackControlsFragment";
- private static final boolean SHOW_DETAIL = true;
- private static final boolean HIDE_MORE_ACTIONS = false;
- private static final int PRIMARY_CONTROLS = 5;
- private static final boolean SHOW_IMAGE = PRIMARY_CONTROLS <= 5;
+ /**
+ * Change this to choose a different overlay background.
+ */
private static final int BACKGROUND_TYPE = PlaybackOverlayFragment.BG_LIGHT;
- private static final int MORE_ROWS = 3;
- private ArrayObjectAdapter mRowsAdapter;
- private ArrayObjectAdapter mPrimaryActionsAdapter;
- private ArrayObjectAdapter mSecondaryActionsAdapter;
- private PlayPauseAction mPlayPauseAction;
+ /**
+ * Change the number of related content rows.
+ */
+ private static final int RELATED_CONTENT_ROWS = 3;
+
+ /**
+ * Change the location of the thumbs up/down controls
+ */
+ private static final boolean THUMBS_PRIMARY = true;
+
+ /**
+ * Change this to select hidden
+ */
+ private static final boolean SECONDARY_HIDDEN = false;
+
+ private static final String FAUX_TITLE = "A short song of silence";
+ private static final String FAUX_SUBTITLE = "2014";
+ private static final int FAUX_DURATION = 33 * 1000;
+
+ private static final int ROW_CONTROLS = 0;
+
+ private PlaybackControlGlue mGlue;
+ private PlaybackControlsRowPresenter mPlaybackControlsRowPresenter;
+ private ListRowPresenter mListRowPresenter;
+
private RepeatAction mRepeatAction;
private ThumbsUpAction mThumbsUpAction;
private ThumbsDownAction mThumbsDownAction;
- private ShuffleAction mShuffleAction;
- private SkipNextAction mSkipNextAction;
- private SkipPreviousAction mSkipPreviousAction;
- private PlaybackControlsRow mPlaybackControlsRow;
- private ArrayList<MediaItem> mItems = new ArrayList<MediaItem>();
- private int mCurrentItem;
private Handler mHandler;
- private Runnable mRunnable;
+
+ // These should match the playback service FF behavior
+ private int[] mFastForwardSpeeds = { 2, 3, 4, 5 };
+
+ private OnItemViewClickedListener mOnItemViewClickedListener = new OnItemViewClickedListener() {
+ @Override
+ public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item,
+ RowPresenter.ViewHolder rowViewHolder, Row row) {
+ if (item instanceof Action) {
+ onActionClicked((Action) item);
+ }
+ }
+ };
+
+ private OnItemViewSelectedListener mOnItemViewSelectedListener = new OnItemViewSelectedListener() {
+ @Override
+ public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item,
+ RowPresenter.ViewHolder rowViewHolder, Row row) {
+ Log.i(TAG, "onItemSelected: " + item + " row " + row);
+ }
+ };
+
+ final Runnable mUpdateProgressRunnable = new Runnable() {
+ @Override
+ public void run() {
+ mGlue.updateProgress();
+ mHandler.postDelayed(this, mGlue.getUpdatePeriod());
+ }
+ };
+
+ public SparseArrayObjectAdapter getAdapter() {
+ return (SparseArrayObjectAdapter) super.getAdapter();
+ }
@Override
public void onCreate(Bundle savedInstanceState) {
Log.i(TAG, "onCreate");
super.onCreate(savedInstanceState);
+ setBackgroundType(BACKGROUND_TYPE);
+ setOnItemViewSelectedListener(mOnItemViewSelectedListener);
+
+ createComponents(getActivity());
+ }
+
+ private void createComponents(Context context) {
mHandler = new Handler();
+ mThumbsUpAction = new PlaybackControlsRow.ThumbsUpAction(context);
+ mThumbsUpAction.setIndex(ThumbsUpAction.OUTLINE);
+ mThumbsDownAction = new PlaybackControlsRow.ThumbsDownAction(context);
+ mThumbsDownAction.setIndex(ThumbsDownAction.OUTLINE);
+ mRepeatAction = new PlaybackControlsRow.RepeatAction(context);
+
+ mGlue = new PlaybackControlGlue(context, this, mFastForwardSpeeds) {
+ private boolean mIsPlaying;
+ private int mSpeed = PlaybackControlGlue.PLAYBACK_SPEED_PAUSED;
+ private long mStartTime;
+ private long mStartPosition = 0;
- setBackgroundType(BACKGROUND_TYPE);
- setFadingEnabled(false);
+ @Override
+ protected SparseArrayObjectAdapter createPrimaryActionsAdapter(
+ PresenterSelector presenterSelector) {
+ return PlaybackOverlayFragment.this.createPrimaryActionsAdapter(
+ presenterSelector);
+ }
+
+ @Override
+ public boolean hasValidMedia() {
+ return true;
+ }
- setupRows();
+ @Override
+ public boolean isMediaPlaying() {
+ return mIsPlaying;
+ }
- setOnItemViewSelectedListener(new OnItemViewSelectedListener() {
@Override
- public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item,
- RowPresenter.ViewHolder rowViewHolder, Row row) {
- Log.i(TAG, "onItemSelected: " + item + " row " + row);
+ public CharSequence getMediaTitle() {
+ return FAUX_TITLE;
}
- });
- setOnItemViewClickedListener(new OnItemViewClickedListener() {
+
@Override
- public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item,
- RowPresenter.ViewHolder rowViewHolder, Row row) {
- Log.i(TAG, "onItemClicked: " + item + " row " + row);
+ public CharSequence getMediaSubtitle() {
+ return FAUX_SUBTITLE;
}
- });
- }
+ @Override
+ public int getMediaDuration() {
+ return FAUX_DURATION;
+ }
- private void setupRows() {
- ClassPresenterSelector ps = new ClassPresenterSelector();
+ @Override
+ public Drawable getMediaArt() {
+ return null;
+ }
- PlaybackControlsRowPresenter playbackControlsRowPresenter;
- if (SHOW_DETAIL) {
- playbackControlsRowPresenter = new PlaybackControlsRowPresenter(
- new DescriptionPresenter());
- } else {
- playbackControlsRowPresenter = new PlaybackControlsRowPresenter();
- }
- playbackControlsRowPresenter.setOnActionClickedListener(new OnActionClickedListener() {
- public void onActionClicked(Action action) {
- if (action.getId() == mPlayPauseAction.getId()) {
- if (mPlayPauseAction.getIndex() == PlayPauseAction.PLAY) {
- startProgressAutomation();
- setFadingEnabled(true);
- } else {
- stopProgressAutomation();
- setFadingEnabled(false);
+ @Override
+ public long getSupportedActions() {
+ return PlaybackControlGlue.ACTION_PLAY_PAUSE |
+ PlaybackControlGlue.ACTION_FAST_FORWARD |
+ PlaybackControlGlue.ACTION_REWIND;
+ }
+
+ @Override
+ public int getCurrentSpeedId() {
+ return mSpeed;
+ }
+
+ @Override
+ public int getCurrentPosition() {
+ int speed;
+ if (mSpeed == PlaybackControlGlue.PLAYBACK_SPEED_PAUSED) {
+ speed = 0;
+ } else if (mSpeed == PlaybackControlGlue.PLAYBACK_SPEED_NORMAL) {
+ speed = 1;
+ } else if (mSpeed >= PlaybackControlGlue.PLAYBACK_SPEED_FAST_L0) {
+ int index = mSpeed - PlaybackControlGlue.PLAYBACK_SPEED_FAST_L0;
+ speed = getFastForwardSpeeds()[index];
+ } else if (mSpeed <= -PlaybackControlGlue.PLAYBACK_SPEED_FAST_L0) {
+ int index = -mSpeed - PlaybackControlGlue.PLAYBACK_SPEED_FAST_L0;
+ speed = -getRewindSpeeds()[index];
+ } else {
+ return -1;
+ }
+ long position = mStartPosition +
+ (System.currentTimeMillis() - mStartTime) * speed;
+ if (position > getMediaDuration()) {
+ position = getMediaDuration();
+ onPlaybackComplete(true);
+ } else if (position < 0) {
+ position = 0;
+ onPlaybackComplete(false);
+ }
+ return (int) position;
+ }
+
+ void onPlaybackComplete(final boolean ended) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ if (mRepeatAction.getIndex() == RepeatAction.NONE) {
+ pausePlayback();
+ } else {
+ startPlayback(PlaybackControlGlue.PLAYBACK_SPEED_NORMAL);
+ }
+ mStartPosition = 0;
+ onStateChanged();
}
- } else if (action.getId() == mSkipNextAction.getId()) {
- next();
- } else if (action.getId() == mSkipPreviousAction.getId()) {
- Toast.makeText(getActivity(), "TODO", Toast.LENGTH_SHORT).show();
+ });
+ }
+
+ @Override
+ protected void startPlayback(int speed) {
+ if (speed == mSpeed) {
+ return;
}
- if (action instanceof PlaybackControlsRow.MultiAction) {
- ((PlaybackControlsRow.MultiAction) action).nextIndex();
- notifyChanged(action);
+ mStartPosition = getCurrentPosition();
+ mSpeed = speed;
+ mIsPlaying = true;
+ mStartTime = System.currentTimeMillis();
+ }
+
+ @Override
+ protected void pausePlayback() {
+ if (mSpeed == PlaybackControlGlue.PLAYBACK_SPEED_PAUSED) {
+ return;
}
+ mStartPosition = getCurrentPosition();
+ mSpeed = PlaybackControlGlue.PLAYBACK_SPEED_PAUSED;
+ mIsPlaying = false;
}
- });
- playbackControlsRowPresenter.setSecondaryActionsHidden(HIDE_MORE_ACTIONS);
- ps.addClassPresenter(PlaybackControlsRow.class, playbackControlsRowPresenter);
- ps.addClassPresenter(ListRow.class, new ListRowPresenter());
- mRowsAdapter = new ArrayObjectAdapter(ps);
+ @Override
+ protected void skipToNext() {
+ // Not supported
+ }
- addPlaybackControlsRow();
- addOtherRows();
+ @Override
+ protected void skipToPrevious() {
+ // Not supported
+ }
- setAdapter(mRowsAdapter);
- }
+ @Override
+ protected void onRowChanged(PlaybackControlsRow row) {
+ PlaybackOverlayFragment.this.onRowChanged(row);
+ }
- private void addPlaybackControlsRow() {
- Context context = getActivity();
+ @Override
+ public void enableProgressUpdating(boolean enable) {
+ PlaybackOverlayFragment.this.enableProgressUpdating(enable);
+ }
- if (SHOW_DETAIL) {
- mPlaybackControlsRow = new PlaybackControlsRow(new MediaItem());
- } else {
- mPlaybackControlsRow = new PlaybackControlsRow();
- }
- mRowsAdapter.add(mPlaybackControlsRow);
-
- mItems = new ArrayList<MediaItem>();
- mItems.add(new MediaItem("Awesome Tune", "The More Awesome Band", R.drawable.details_img, 15*1000));
- mItems.add(new MediaItem("Pretty nice Tune", "The Nice Guys", R.drawable.details_img, 10*1000));
- mCurrentItem = 1;
- updatePlaybackRow(mCurrentItem);
-
- ControlButtonPresenterSelector presenterSelector = new ControlButtonPresenterSelector();
- mPrimaryActionsAdapter = new ArrayObjectAdapter(presenterSelector);
- mSecondaryActionsAdapter = new ArrayObjectAdapter(presenterSelector);
- mPlaybackControlsRow.setPrimaryActionsAdapter(mPrimaryActionsAdapter);
- mPlaybackControlsRow.setSecondaryActionsAdapter(mSecondaryActionsAdapter);
-
- mPlayPauseAction = new PlayPauseAction(context);
- mRepeatAction = new RepeatAction(context);
- mThumbsUpAction = new ThumbsUpAction(context);
- mThumbsDownAction = new ThumbsDownAction(context);
- mShuffleAction = new ShuffleAction(context);
- mSkipNextAction = new PlaybackControlsRow.SkipNextAction(context);
- mSkipPreviousAction = new PlaybackControlsRow.SkipPreviousAction(context);
-
- if (PRIMARY_CONTROLS > 5) {
- mPrimaryActionsAdapter.add(mThumbsUpAction);
- } else {
- mSecondaryActionsAdapter.add(mThumbsUpAction);
- }
- mPrimaryActionsAdapter.add(mSkipPreviousAction);
- if (PRIMARY_CONTROLS > 3) {
- mPrimaryActionsAdapter.add(new PlaybackControlsRow.RewindAction(context));
- }
- mPrimaryActionsAdapter.add(mPlayPauseAction);
- if (PRIMARY_CONTROLS > 3) {
- mPrimaryActionsAdapter.add(new PlaybackControlsRow.FastForwardAction(context));
- }
- mPrimaryActionsAdapter.add(mSkipNextAction);
+ @Override
+ public int getUpdatePeriod() {
+ return PlaybackOverlayFragment.this.getUpdatePeriod();
+ }
+ };
- mSecondaryActionsAdapter.add(mRepeatAction);
- mSecondaryActionsAdapter.add(mShuffleAction);
- if (PRIMARY_CONTROLS > 5) {
- mPrimaryActionsAdapter.add(mThumbsDownAction);
- } else {
- mSecondaryActionsAdapter.add(mThumbsDownAction);
- }
- mSecondaryActionsAdapter.add(new PlaybackControlsRow.HighQualityAction(context));
- mSecondaryActionsAdapter.add(new PlaybackControlsRow.ClosedCaptioningAction(context));
- }
+ mGlue.setOnItemViewClickedListener(mOnItemViewClickedListener);
- private void notifyChanged(Action action) {
- ArrayObjectAdapter adapter = mPrimaryActionsAdapter;
- if (adapter.indexOf(action) >= 0) {
- adapter.notifyArrayItemRangeChanged(adapter.indexOf(action), 1);
- return;
- }
- adapter = mSecondaryActionsAdapter;
- if (adapter.indexOf(action) >= 0) {
- adapter.notifyArrayItemRangeChanged(adapter.indexOf(action), 1);
- return;
- }
- }
+ mPlaybackControlsRowPresenter = mGlue.createControlsRowAndPresenter();
+ mPlaybackControlsRowPresenter.setSecondaryActionsHidden(SECONDARY_HIDDEN);
+ mListRowPresenter = new ListRowPresenter();
- private void updatePlaybackRow(int index) {
- if (mPlaybackControlsRow.getItem() != null) {
- MediaItem item = (MediaItem) mPlaybackControlsRow.getItem();
- item.title = mItems.get(index).title;
- item.subtitle = mItems.get(index).subtitle;
+ setAdapter(new SparseArrayObjectAdapter(new PresenterSelector() {
+ @Override
+ public Presenter getPresenter(Object object) {
+ if (object instanceof PlaybackControlsRow) {
+ return mPlaybackControlsRowPresenter;
+ } else if (object instanceof ListRow) {
+ return mListRowPresenter;
+ }
+ throw new IllegalArgumentException("Unhandled object: " + object);
+ }
+ }));
+
+ // Set secondary control actions
+ PlaybackControlsRow controlsRow = mGlue.getControlsRow();
+ ArrayObjectAdapter adapter = new ArrayObjectAdapter(new ControlButtonPresenterSelector());
+ controlsRow.setSecondaryActionsAdapter(adapter);
+ if (!THUMBS_PRIMARY) {
+ adapter.add(mThumbsDownAction);
}
- if (SHOW_IMAGE) {
- mPlaybackControlsRow.setImageDrawable(getResources().getDrawable(
- mItems.get(mCurrentItem).imageResId));
+ adapter.add(mRepeatAction);
+ if (!THUMBS_PRIMARY) {
+ adapter.add(mThumbsUpAction);
}
- mRowsAdapter.notifyArrayItemRangeChanged(0, 1);
- mPlaybackControlsRow.setTotalTime(mItems.get(mCurrentItem).durationMs);
- mPlaybackControlsRow.setCurrentTime(0);
- mPlaybackControlsRow.setBufferedProgress(75 * 1000);
- }
+ // Add the controls row
+ getAdapter().set(ROW_CONTROLS, controlsRow);
- private void addOtherRows() {
- for (int i = 0; i < MORE_ROWS; ++i) {
+ // Add related content rows
+ for (int i = 0; i < RELATED_CONTENT_ROWS; ++i) {
ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(new StringPresenter());
listRowAdapter.add("Some related content");
listRowAdapter.add("Other related content");
HeaderItem header = new HeaderItem(i, "Row " + i);
- mRowsAdapter.add(new ListRow(header, listRowAdapter));
+ getAdapter().set(ROW_CONTROLS + 1 + i, new ListRow(header, listRowAdapter));
}
}
- private int getUpdatePeriod() {
- if (getView() == null || mPlaybackControlsRow.getTotalTime() <= 0) {
- return 1000;
+ private SparseArrayObjectAdapter createPrimaryActionsAdapter(
+ PresenterSelector presenterSelector) {
+ SparseArrayObjectAdapter adapter = new SparseArrayObjectAdapter(presenterSelector);
+ if (THUMBS_PRIMARY) {
+ adapter.set(PlaybackControlGlue.ACTION_CUSTOM_LEFT_FIRST, mThumbsUpAction);
+ adapter.set(PlaybackControlGlue.ACTION_CUSTOM_RIGHT_FIRST, mThumbsDownAction);
}
- return Math.max(16, mPlaybackControlsRow.getTotalTime() / getView().getWidth());
+ return adapter;
}
- private void startProgressAutomation() {
- mRunnable = new Runnable() {
- @Override
- public void run() {
- int updatePeriod = getUpdatePeriod();
- int currentTime = mPlaybackControlsRow.getCurrentTime() + updatePeriod;
- int totalTime = mPlaybackControlsRow.getTotalTime();
- mPlaybackControlsRow.setCurrentTime(currentTime);
- if (totalTime > 0 && totalTime <= currentTime) {
- next();
- }
- mHandler.postDelayed(this, updatePeriod);
- }
- };
- mHandler.postDelayed(mRunnable, getUpdatePeriod());
+ private void onRowChanged(PlaybackControlsRow row) {
+ if (getAdapter() == null) {
+ return;
+ }
+ int index = getAdapter().indexOf(row);
+ if (index >= 0) {
+ getAdapter().notifyArrayItemRangeChanged(index, 1);
+ }
}
- private void next() {
- if (++mCurrentItem >= mItems.size()) {
- mCurrentItem = 0;
+ private void enableProgressUpdating(boolean enable) {
+ Log.v(TAG, "enableProgressUpdating " + enable + " this " + this);
+ mHandler.removeCallbacks(mUpdateProgressRunnable);
+ if (enable) {
+ mUpdateProgressRunnable.run();
}
- updatePlaybackRow(mCurrentItem);
}
- private void stopProgressAutomation() {
- if (mHandler != null && mRunnable != null) {
- mHandler.removeCallbacks(mRunnable);
+ private int getUpdatePeriod() {
+ int totalTime = mGlue.getControlsRow().getTotalTime();
+ if (getView() == null || totalTime <= 0) {
+ return 1000;
}
+ return Math.max(16, totalTime / getView().getWidth());
}
- @Override
- public void onStop() {
- stopProgressAutomation();
- super.onStop();
+ private void onActionClicked(Action action) {
+ Log.v(TAG, "onActionClicked " + action);
+ Toast.makeText(getActivity(), action.toString(), Toast.LENGTH_SHORT).show();
+ if (action instanceof PlaybackControlsRow.MultiAction) {
+ PlaybackControlsRow.MultiAction multiAction = (PlaybackControlsRow.MultiAction) action;
+ multiAction.nextIndex();
+ notifyActionChanged(multiAction);
+ }
}
- static class MediaItem {
- String title;
- String subtitle;
- int imageResId;
- int durationMs;
+ private SparseArrayObjectAdapter getPrimaryActionsAdapter() {
+ return (SparseArrayObjectAdapter) mGlue.getControlsRow().getPrimaryActionsAdapter();
+ }
- MediaItem() {
- }
+ private ArrayObjectAdapter getSecondaryActionsAdapter() {
+ return (ArrayObjectAdapter) mGlue.getControlsRow().getSecondaryActionsAdapter();
+ }
- MediaItem(String title, String subtitle, int imageResId, int durationMs) {
- this.title = title;
- this.subtitle = subtitle;
- this.imageResId = imageResId;
- this.durationMs = durationMs;
+ private void notifyActionChanged(PlaybackControlsRow.MultiAction action) {
+ int index;
+ index = getPrimaryActionsAdapter().indexOf(action);
+ if (index >= 0) {
+ getPrimaryActionsAdapter().notifyArrayItemRangeChanged(index, 1);
+ } else {
+ index = getSecondaryActionsAdapter().indexOf(action);
+ if (index >= 0) {
+ getSecondaryActionsAdapter().notifyArrayItemRangeChanged(index, 1);
+ }
}
}
- static class DescriptionPresenter extends AbstractDetailsDescriptionPresenter {
- @Override
- protected void onBindDescription(ViewHolder vh, Object item) {
- vh.getTitle().setText(((MediaItem) item).title);
- vh.getSubtitle().setText(((MediaItem) item).subtitle);
- }
+ @Override
+ public void onStart() {
+ super.onStart();
+ mGlue.enableProgressUpdating(mGlue.hasValidMedia() && mGlue.isMediaPlaying());
+ }
+
+ @Override
+ public void onStop() {
+ mGlue.enableProgressUpdating(false);
+ super.onStop();
}
}
diff --git a/samples/browseable/MediaBrowserService/res/drawable-night-xxhdpi/ic_star_off.png b/samples/browseable/MediaBrowserService/res/drawable-night-xxhdpi/ic_star_off.png
deleted file mode 100644
index e435d2a9f..000000000
--- a/samples/browseable/MediaBrowserService/res/drawable-night-xxhdpi/ic_star_off.png
+++ /dev/null
Binary files differ
diff --git a/samples/browseable/MediaBrowserService/res/drawable-night-xxhdpi/ic_star_on.png b/samples/browseable/MediaBrowserService/res/drawable-night-xxhdpi/ic_star_on.png
deleted file mode 100644
index 0c75bb6da..000000000
--- a/samples/browseable/MediaBrowserService/res/drawable-night-xxhdpi/ic_star_on.png
+++ /dev/null
Binary files differ
diff --git a/samples/browseable/MediaBrowserService/res/drawable-xxhdpi/ic_star_off.png b/samples/browseable/MediaBrowserService/res/drawable-xxhdpi/ic_star_off.png
index 836085b68..fb7afb0c9 100644
--- a/samples/browseable/MediaBrowserService/res/drawable-xxhdpi/ic_star_off.png
+++ b/samples/browseable/MediaBrowserService/res/drawable-xxhdpi/ic_star_off.png
Binary files differ
diff --git a/samples/browseable/MediaBrowserService/res/drawable-xxhdpi/ic_star_on.png b/samples/browseable/MediaBrowserService/res/drawable-xxhdpi/ic_star_on.png
index 7cd6cfc52..6f7fc75e1 100644
--- a/samples/browseable/MediaBrowserService/res/drawable-xxhdpi/ic_star_on.png
+++ b/samples/browseable/MediaBrowserService/res/drawable-xxhdpi/ic_star_on.png
Binary files differ
diff --git a/samples/browseable/MediaBrowserService/src/com.example.android.mediabrowserservice/MusicPlayerActivity.java b/samples/browseable/MediaBrowserService/src/com.example.android.mediabrowserservice/MusicPlayerActivity.java
index 648d26896..394b01ad2 100644
--- a/samples/browseable/MediaBrowserService/src/com.example.android.mediabrowserservice/MusicPlayerActivity.java
+++ b/samples/browseable/MediaBrowserService/src/com.example.android.mediabrowserservice/MusicPlayerActivity.java
@@ -17,7 +17,6 @@ package com.example.android.mediabrowserservice;
import android.app.Activity;
import android.media.browse.MediaBrowser;
-import android.media.session.MediaController;
import android.os.Bundle;
/**
@@ -28,9 +27,6 @@ public class MusicPlayerActivity extends Activity
private static final String TAG = MusicPlayerActivity.class.getSimpleName();
- private MediaBrowser mMediaBrowser;
- private MediaController mMediaController;
-
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
diff --git a/samples/browseable/MediaBrowserService/src/com.example.android.mediabrowserservice/MusicService.java b/samples/browseable/MediaBrowserService/src/com.example.android.mediabrowserservice/MusicService.java
index 1c8744f00..b48242664 100644
--- a/samples/browseable/MediaBrowserService/src/com.example.android.mediabrowserservice/MusicService.java
+++ b/samples/browseable/MediaBrowserService/src/com.example.android.mediabrowserservice/MusicService.java
@@ -39,7 +39,6 @@ import android.os.PowerManager;
import android.os.SystemClock;
import android.service.media.MediaBrowserService;
-import com.example.android.mediabrowserservice.PackageValidator;
import com.example.android.mediabrowserservice.model.MusicProvider;
import com.example.android.mediabrowserservice.utils.LogHelper;
import com.example.android.mediabrowserservice.utils.MediaIDHelper;
@@ -379,6 +378,11 @@ public class MusicService extends MediaBrowserService implements OnPreparedListe
@Override
public void onSkipToQueueItem(long queueId) {
LogHelper.d(TAG, "OnSkipToQueueItem:" + queueId);
+
+ if (mState == PlaybackState.STATE_PAUSED) {
+ mState = PlaybackState.STATE_STOPPED;
+ }
+
if (mPlayingQueue != null && !mPlayingQueue.isEmpty()) {
// set the current index on queue from the music Id:
@@ -393,6 +397,10 @@ public class MusicService extends MediaBrowserService implements OnPreparedListe
public void onPlayFromMediaId(String mediaId, Bundle extras) {
LogHelper.d(TAG, "playFromMediaId mediaId:", mediaId, " extras=", extras);
+ if (mState == PlaybackState.STATE_PAUSED) {
+ mState = PlaybackState.STATE_STOPPED;
+ }
+
// The mediaId used here is not the unique musicId. This one comes from the
// MediaBrowser, and is actually a "hierarchy-aware mediaID": a concatenation of
// the hierarchy in MediaBrowser and the actual unique musicID. This is necessary
@@ -406,6 +414,7 @@ public class MusicService extends MediaBrowserService implements OnPreparedListe
if (mPlayingQueue != null && !mPlayingQueue.isEmpty()) {
String uniqueMusicID = MediaIDHelper.extractMusicIDFromMediaID(mediaId);
+
// set the current index on queue from the music Id:
mCurrentIndexOnQueue = QueueHelper.getMusicIndexOnQueue(
mPlayingQueue, uniqueMusicID);
@@ -435,7 +444,7 @@ public class MusicService extends MediaBrowserService implements OnPreparedListe
mCurrentIndexOnQueue = 0;
}
if (QueueHelper.isIndexPlayable(mCurrentIndexOnQueue, mPlayingQueue)) {
- mState = PlaybackState.STATE_PLAYING;
+ mState = PlaybackState.STATE_STOPPED;
handlePlayRequest();
} else {
LogHelper.e(TAG, "skipToNext: cannot skip to next. next Index=" +
@@ -448,7 +457,6 @@ public class MusicService extends MediaBrowserService implements OnPreparedListe
@Override
public void onSkipToPrevious() {
LogHelper.d(TAG, "skipToPrevious");
-
mCurrentIndexOnQueue--;
if (mPlayingQueue != null && mCurrentIndexOnQueue < 0) {
// This sample's behavior: skipping to previous when in first song restarts the
@@ -456,7 +464,7 @@ public class MusicService extends MediaBrowserService implements OnPreparedListe
mCurrentIndexOnQueue = 0;
}
if (QueueHelper.isIndexPlayable(mCurrentIndexOnQueue, mPlayingQueue)) {
- mState = PlaybackState.STATE_PLAYING;
+ mState = PlaybackState.STATE_STOPPED;
handlePlayRequest();
} else {
LogHelper.e(TAG, "skipToPrevious: cannot skip to previous. previous Index=" +
@@ -486,12 +494,15 @@ public class MusicService extends MediaBrowserService implements OnPreparedListe
public void onPlayFromSearch(String query, Bundle extras) {
LogHelper.d(TAG, "playFromSearch query=", query);
+ if (mState == PlaybackState.STATE_PAUSED) {
+ mState = PlaybackState.STATE_STOPPED;
+ }
+
mPlayingQueue = QueueHelper.getPlayingQueueFromSearch(query, mMusicProvider);
LogHelper.d(TAG, "playFromSearch playqueue.length=" + mPlayingQueue.size());
mSession.setQueue(mPlayingQueue);
if (mPlayingQueue != null && !mPlayingQueue.isEmpty()) {
-
// start playing from the beginning of the queue
mCurrentIndexOnQueue = 0;
diff --git a/samples/browseable/MessagingService/res/layout-land/fragment_message_me.xml b/samples/browseable/MessagingService/res/layout-land/fragment_message_me.xml
index 8f7b60a23..6f4f88bac 100644
--- a/samples/browseable/MessagingService/res/layout-land/fragment_message_me.xml
+++ b/samples/browseable/MessagingService/res/layout-land/fragment_message_me.xml
@@ -61,7 +61,6 @@
android:layout_above="@id/clear"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:maxLines="20"
android:scrollbars="vertical"/>
</RelativeLayout>
</LinearLayout>
diff --git a/samples/browseable/MessagingService/res/layout/fragment_message_me.xml b/samples/browseable/MessagingService/res/layout/fragment_message_me.xml
index d01c5137a..29a8c441a 100644
--- a/samples/browseable/MessagingService/res/layout/fragment_message_me.xml
+++ b/samples/browseable/MessagingService/res/layout/fragment_message_me.xml
@@ -47,7 +47,6 @@
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
- android:maxLines="20"
android:scrollbars="vertical"/>
<Button
android:layout_width="match_parent"
diff --git a/samples/browseable/MessagingService/src/com.example.android.messagingservice/Conversations.java b/samples/browseable/MessagingService/src/com.example.android.messagingservice/Conversations.java
index 210e061f0..7425df499 100644
--- a/samples/browseable/MessagingService/src/com.example.android.messagingservice/Conversations.java
+++ b/samples/browseable/MessagingService/src/com.example.android.messagingservice/Conversations.java
@@ -45,10 +45,10 @@ public class Conversations {
* Senders of the said messages.
*/
private static final String[] PARTICIPANTS = new String[]{
- "John Rambo",
- "Han Solo",
- "Rocky Balboa",
- "Lara Croft"
+ "John Smith",
+ "Robert Lawrence",
+ "James Smith",
+ "Jane Doe"
};
static class Conversation {
diff --git a/samples/browseable/SpeedTracker/Application/AndroidManifest.xml b/samples/browseable/SpeedTracker/Application/AndroidManifest.xml
index 3361a44df..97db73217 100644
--- a/samples/browseable/SpeedTracker/Application/AndroidManifest.xml
+++ b/samples/browseable/SpeedTracker/Application/AndroidManifest.xml
@@ -12,7 +12,7 @@
android:glEsVersion="0x00020000" android:required="true"/>
<uses-sdk
android:minSdkVersion="18"
- android:targetSdkVersion="19" />
+ android:targetSdkVersion="20" />
<application
android:name=".PhoneApplication"
diff --git a/samples/browseable/SpeedTracker/Application/res/values-v21/template-styles.xml b/samples/browseable/SpeedTracker/Application/res/values-v21/template-styles.xml
deleted file mode 100644
index 134fcd9d3..000000000
--- a/samples/browseable/SpeedTracker/Application/res/values-v21/template-styles.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<!--
- Copyright 2014 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.
- -->
-
-<resources>
-
- <!-- Activity themes -->
- <style name="Theme.Base" parent="android:Theme.Material.Light" />
-
-</resources>
diff --git a/sdk/platform_source.prop_template b/sdk/platform_source.prop_template
index da04c30dd..101ca237c 100644
--- a/sdk/platform_source.prop_template
+++ b/sdk/platform_source.prop_template
@@ -2,7 +2,7 @@ Pkg.Desc=Android SDK Platform ${PLATFORM_VERSION}
Pkg.UserSrc=false
Platform.Version=${PLATFORM_VERSION}
Platform.CodeName=LOLLIPOP
-Pkg.Revision=1
+Pkg.Revision=2
AndroidVersion.ApiLevel=${PLATFORM_SDK_VERSION}
AndroidVersion.CodeName=${PLATFORM_VERSION_CODENAME}
Layoutlib.Api=12