BrowserService.java revision 319f9a979c1c10c0c15ca50ee20e0a05e932cbb7
1/*
2 * Copyright (C) 2014 Google Inc. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.example.android.musicservicedemo;
18
19import android.app.SearchManager;
20import android.app.Service;
21import android.content.Context;
22import android.content.Intent;
23import android.content.UriMatcher;
24import android.content.res.Resources.NotFoundException;
25import android.database.MatrixCursor;
26import android.graphics.Bitmap;
27import android.media.AudioManager;
28import android.media.MediaPlayer;
29import android.media.MediaPlayer.OnCompletionListener;
30import android.media.MediaPlayer.OnErrorListener;
31import android.media.MediaPlayer.OnPreparedListener;
32import android.media.browse.MediaBrowserItem;
33import android.media.browse.MediaBrowserService;
34import android.media.browse.MediaBrowserService.BrowserRoot;
35import android.media.session.MediaSession;
36import android.net.Uri;
37import android.net.wifi.WifiManager;
38import android.net.wifi.WifiManager.WifiLock;
39import android.os.Bundle;
40import android.os.Handler;
41import android.os.IBinder;
42import android.os.Message;
43import android.os.PowerManager;
44import android.os.RemoteException;
45import android.os.SystemClock;
46import android.util.Log;
47
48import com.example.android.musicservicedemo.browser.MusicProvider;
49import com.example.android.musicservicedemo.browser.MusicProviderTask;
50import com.example.android.musicservicedemo.browser.MusicProviderTaskListener;
51import com.example.android.musicservicedemo.browser.MusicTrack;
52
53import org.json.JSONException;
54
55import java.io.IOException;
56import java.util.ArrayList;
57import java.util.List;
58
59/**
60 * Service that implements MediaBrowserService and returns our menu hierarchy.
61 */
62public class BrowserService extends MediaBrowserService {
63    private static final String TAG = "BrowserService";
64
65    // URI paths for browsing music
66    public static final String BROWSE_ROOT_BASE_PATH = "browse";
67    public static final String NOW_PLAYING_PATH = "now_playing";
68    public static final String PIANO_BASE_PATH = "piano";
69    public static final String VOICE_BASE_PATH = "voice";
70
71    // Content URIs
72    public static final String AUTHORITY = "com.example.android.automotive.musicplayer";
73    public static final Uri BASE_URI = Uri.parse("content://" + AUTHORITY);
74    public static final Uri BROWSE_URI = Uri.withAppendedPath(BASE_URI, BROWSE_ROOT_BASE_PATH);
75
76    // URI matcher constants for browsing paths
77    public static final int BROWSE_ROOT = 1;
78    public static final int NOW_PLAYING = 2;
79    public static final int PIANO = 3;
80    public static final int VOICE = 4;
81
82    // Map the the URI paths with the URI matcher constants
83    private static final UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
84    static {
85        sUriMatcher.addURI(AUTHORITY, BROWSE_ROOT_BASE_PATH, BROWSE_ROOT);
86        sUriMatcher.addURI(AUTHORITY, NOW_PLAYING_PATH, NOW_PLAYING);
87        sUriMatcher.addURI(AUTHORITY, PIANO_BASE_PATH, PIANO);
88        sUriMatcher.addURI(AUTHORITY, VOICE_BASE_PATH, VOICE);
89    }
90
91    // Media metadata that will be provided for a media container
92    public static final String[] MEDIA_CONTAINER_PROJECTION = {
93            "uri",
94            "title",
95            "subtitle",
96            "image_uri",
97            "supported_actions"
98    };
99
100    // MusicProvider will download the music catalog
101    private MusicProvider mMusicProvider;
102
103    private MediaSession mSession;
104
105    @Override
106    public void onCreate() {
107        super.onCreate();
108
109        mSession = new MediaSession(this, "com.example.android.musicservicedemo.BrowserService");
110        setSessionToken(mSession.getSessionToken());
111    }
112
113    @Override
114    public void onDestroy() {
115        super.onDestroy();
116    }
117
118    @Override
119    protected BrowserRoot onGetRoot(String clientPackageName, int clientUid, Bundle rootHints) {
120        return new BrowserRoot(BROWSE_URI, null);
121    }
122
123    @Override
124    protected List<MediaBrowserItem> onLoadChildren(Uri parentUri) {
125        final ArrayList<MediaBrowserItem> results = new ArrayList();
126
127        for (int i=0; i<10; i++) {
128            results.add(new MediaBrowserItem.Builder(
129                    Uri.withAppendedPath(BASE_URI, Integer.toString(i)),
130                    MediaBrowserItem.FLAG_BROWSABLE, "Title " + i)
131                    .setSummary("Summary " + i)
132                    .build());
133        }
134
135        return results;
136    }
137
138    @Override
139    protected Bitmap onGetThumbnail(Uri uri, int width, int height) {
140        return null;
141    }
142
143    /*
144    @Override
145    public void query(final Query query, final IMetadataResultHandler metadataResultHandler,
146            final IErrorHandler errorHandler)
147            throws RemoteException {
148        Log.d(TAG, "query: " + query);
149        Utils.checkNotNull(query);
150        Utils.checkNotNull(metadataResultHandler);
151        Utils.checkNotNull(errorHandler);
152
153        // Handle async response
154        new Thread(new Runnable() {
155            public void run() {
156                try {
157                    // Pre-load the list of music
158                    List<MusicTrack> musicTracks = getMusicList();
159                    if (musicTracks == null) {
160                        notifyListenersOnPlaybackStateUpdate(getCurrentPlaybackState());
161                        errorHandler.onError(new Error(Error.UNKNOWN,
162                                getString(R.string.music_error)));
163                        return;
164                    }
165
166                    final Uri uri = query.getUri();
167                    int match = sUriMatcher.match(uri);
168                    Log.d(TAG, "Queried: " + uri + "; match: " + match);
169                    switch (match) {
170                        case BROWSE_ROOT:
171                        {
172                            Log.d(TAG, "Browse_root");
173
174                            try {
175                                MatrixCursor matrixCursor = mMusicProvider
176                                        .getRootContainerCurser();
177                                DataHolder holder = new DataHolder(MEDIA_CONTAINER_PROJECTION,
178                                        matrixCursor, null);
179
180                                Log.d(TAG, "on metadata response called " + holder.getCount());
181                                metadataResultHandler.onMetadataResponse(holder);
182                            } catch (RemoteException e) {
183                                Log.w(TAG, "Error delivering metadata in the callback.", e);
184                            }
185                            break;
186                        }
187                        case NOW_PLAYING:
188                        {
189                            try {
190                                Log.d(TAG, "query NOW_PLAYING");
191                                MatrixCursor matrixCursor = mMusicProvider
192                                        .getRootItemCursor(
193                                        PIANO);
194                                DataHolder holder = new DataHolder(MEDIA_CONTAINER_PROJECTION,
195                                        matrixCursor, null);
196                                Log.d(TAG, "on metadata response called " + holder.getCount());
197                                metadataResultHandler.onMetadataResponse(holder);
198                            } catch (RemoteException e) {
199                                Log.w(TAG, "Error querying NOW_PLAYING");
200                            }
201                            break;
202                        }
203                        case PIANO:
204                        {
205                            try {
206                                Log.d(TAG, "query PIANO");
207                                MatrixCursor matrixCursor = mMusicProvider
208                                        .getRootItemCursor(
209                                        PIANO);
210                                DataHolder holder = new DataHolder(MEDIA_CONTAINER_PROJECTION,
211                                        matrixCursor, null);
212                                Log.d(TAG, "on metadata response called " + holder.getCount());
213                                metadataResultHandler.onMetadataResponse(holder);
214                            } catch (RemoteException e) {
215                                Log.w(TAG, "Error querying PIANO");
216                            }
217                            break;
218                        }
219                        case VOICE:
220                        {
221                            try {
222                                Log.d(TAG, "query VOICE");
223                                MatrixCursor matrixCursor = mMusicProvider
224                                        .getRootItemCursor(
225                                        VOICE);
226                                DataHolder holder = new DataHolder(MEDIA_CONTAINER_PROJECTION,
227                                        matrixCursor, null);
228                                Log.d(TAG, "on metadata response called " + holder.getCount());
229                                metadataResultHandler.onMetadataResponse(holder);
230                            } catch (RemoteException e) {
231                                Log.w(TAG, "Error querying VOICE");
232                            }
233                            break;
234                        }
235                        default:
236                        {
237                            Log.w(TAG, "Skipping unmatched URI: " + uri);
238                        }
239                    }
240                } catch (NotFoundException e) {
241                    Log.e(TAG, "::run:", e);
242                } catch (RemoteException e) {
243                    Log.e(TAG, "::run:", e);
244                }
245            } // end run
246        }).start();
247    }
248
249    */
250}
251