BrowserService.java revision 8470857ee43444868a38d0e760981386880d6ce2
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    public BrowserRoot onGetRoot(String clientPackageName, int clientUid, Bundle rootHints) {
120        return new BrowserRoot(BROWSE_URI, null);
121    }
122
123    @Override
124    public void onLoadChildren(final Uri parentUri,
125            final Result<List<MediaBrowserItem>> result) {
126        new Handler().postDelayed(new Runnable() {
127                public void run() {
128                    final ArrayList<MediaBrowserItem> list = new ArrayList();
129
130                    for (int i=0; i<10; i++) {
131                        list.add(new MediaBrowserItem.Builder(
132                                    Uri.withAppendedPath(BASE_URI, Integer.toString(i)),
133                                    MediaBrowserItem.FLAG_BROWSABLE, "Title " + i)
134                                .setSummary("Summary " + i)
135                                .build());
136                    }
137
138                    result.sendResult(list);
139                }
140            }, 2000);
141        result.detach();
142    }
143
144    @Override
145    public void onLoadThumbnail(Uri uri, int width, int height, Result<Bitmap> result) {
146        result.sendResult(null);
147    }
148
149    /*
150    @Override
151    public void query(final Query query, final IMetadataResultHandler metadataResultHandler,
152            final IErrorHandler errorHandler)
153            throws RemoteException {
154        Log.d(TAG, "query: " + query);
155        Utils.checkNotNull(query);
156        Utils.checkNotNull(metadataResultHandler);
157        Utils.checkNotNull(errorHandler);
158
159        // Handle async response
160        new Thread(new Runnable() {
161            public void run() {
162                try {
163                    // Pre-load the list of music
164                    List<MusicTrack> musicTracks = getMusicList();
165                    if (musicTracks == null) {
166                        notifyListenersOnPlaybackStateUpdate(getCurrentPlaybackState());
167                        errorHandler.onError(new Error(Error.UNKNOWN,
168                                getString(R.string.music_error)));
169                        return;
170                    }
171
172                    final Uri uri = query.getUri();
173                    int match = sUriMatcher.match(uri);
174                    Log.d(TAG, "Queried: " + uri + "; match: " + match);
175                    switch (match) {
176                        case BROWSE_ROOT:
177                        {
178                            Log.d(TAG, "Browse_root");
179
180                            try {
181                                MatrixCursor matrixCursor = mMusicProvider
182                                        .getRootContainerCurser();
183                                DataHolder holder = new DataHolder(MEDIA_CONTAINER_PROJECTION,
184                                        matrixCursor, null);
185
186                                Log.d(TAG, "on metadata response called " + holder.getCount());
187                                metadataResultHandler.onMetadataResponse(holder);
188                            } catch (RemoteException e) {
189                                Log.w(TAG, "Error delivering metadata in the callback.", e);
190                            }
191                            break;
192                        }
193                        case NOW_PLAYING:
194                        {
195                            try {
196                                Log.d(TAG, "query NOW_PLAYING");
197                                MatrixCursor matrixCursor = mMusicProvider
198                                        .getRootItemCursor(
199                                        PIANO);
200                                DataHolder holder = new DataHolder(MEDIA_CONTAINER_PROJECTION,
201                                        matrixCursor, null);
202                                Log.d(TAG, "on metadata response called " + holder.getCount());
203                                metadataResultHandler.onMetadataResponse(holder);
204                            } catch (RemoteException e) {
205                                Log.w(TAG, "Error querying NOW_PLAYING");
206                            }
207                            break;
208                        }
209                        case PIANO:
210                        {
211                            try {
212                                Log.d(TAG, "query PIANO");
213                                MatrixCursor matrixCursor = mMusicProvider
214                                        .getRootItemCursor(
215                                        PIANO);
216                                DataHolder holder = new DataHolder(MEDIA_CONTAINER_PROJECTION,
217                                        matrixCursor, null);
218                                Log.d(TAG, "on metadata response called " + holder.getCount());
219                                metadataResultHandler.onMetadataResponse(holder);
220                            } catch (RemoteException e) {
221                                Log.w(TAG, "Error querying PIANO");
222                            }
223                            break;
224                        }
225                        case VOICE:
226                        {
227                            try {
228                                Log.d(TAG, "query VOICE");
229                                MatrixCursor matrixCursor = mMusicProvider
230                                        .getRootItemCursor(
231                                        VOICE);
232                                DataHolder holder = new DataHolder(MEDIA_CONTAINER_PROJECTION,
233                                        matrixCursor, null);
234                                Log.d(TAG, "on metadata response called " + holder.getCount());
235                                metadataResultHandler.onMetadataResponse(holder);
236                            } catch (RemoteException e) {
237                                Log.w(TAG, "Error querying VOICE");
238                            }
239                            break;
240                        }
241                        default:
242                        {
243                            Log.w(TAG, "Skipping unmatched URI: " + uri);
244                        }
245                    }
246                } catch (NotFoundException e) {
247                    Log.e(TAG, "::run:", e);
248                } catch (RemoteException e) {
249                    Log.e(TAG, "::run:", e);
250                }
251            } // end run
252        }).start();
253    }
254
255    */
256}
257