/*
* Copyright (C) 2011 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.borqs.browser.homepages;
import android.content.Context;
import android.content.UriMatcher;
import android.content.res.Resources;
import android.database.Cursor;
import android.net.Uri;
import android.provider.Browser;
import android.text.TextUtils;
import android.util.Base64;
import android.util.Log;
import com.borqs.browser.R;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RequestHandler extends Thread {
private static final String TAG = "RequestHandler";
private static final int INDEX = 1;
private static final int RESOURCE = 2;
private static final UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
Uri mUri;
Context mContext;
OutputStream mOutput;
static {
sUriMatcher.addURI(HomeProvider.AUTHORITY, "/", INDEX);
sUriMatcher.addURI(HomeProvider.AUTHORITY, "res/*/*", RESOURCE);
}
public RequestHandler(Context context, Uri uri, OutputStream out) {
mUri = uri;
mContext = context.getApplicationContext();
mOutput = out;
}
@Override
public void run() {
super.run();
try {
doHandleRequest();
} catch (Exception e) {
Log.e(TAG, "Failed to handle request: " + mUri, e);
} finally {
cleanup();
}
}
void doHandleRequest() throws IOException {
int match = sUriMatcher.match(mUri);
switch (match) {
case INDEX:
writeTemplatedIndex();
break;
case RESOURCE:
writeResource(getUriResourcePath());
break;
}
}
byte[] htmlEncode(String s) {
return TextUtils.htmlEncode(s).getBytes();
}
void writeTemplatedIndex() throws IOException {
Template t = Template.getCachedTemplate(mContext, R.raw.most_visited);
Cursor cursor = mContext.getContentResolver().query(Browser.BOOKMARKS_URI,
new String[] { "DISTINCT url", "title", "thumbnail" },
"(visits > 0 OR bookmark = 1) AND url NOT LIKE 'content:%' AND thumbnail IS NOT NULL", null, "visits DESC LIMIT 12");
t.assignLoop("most_visited", new Template.CursorListEntityWrapper(cursor) {
@Override
public void writeValue(OutputStream stream, String key) throws IOException {
Cursor cursor = getCursor();
if (key.equals("url")) {
stream.write(htmlEncode(cursor.getString(0)));
} else if (key.equals("title")) {
stream.write(htmlEncode(cursor.getString(1)));
} else if (key.equals("thumbnail")) {
stream.write("data:image/png;base64,".getBytes());
byte[] thumb = cursor.getBlob(2);
stream.write(Base64.encode(thumb, Base64.DEFAULT));
}
}
});
t.write(mOutput);
}
String getUriResourcePath() {
final Pattern pattern = Pattern.compile("/?res/([\\w/]+)");
Matcher m = pattern.matcher(mUri.getPath());
if (m.matches()) {
return m.group(1);
} else {
return mUri.getPath();
}
}
void writeResource(String fileName) throws IOException {
Resources res = mContext.getResources();
String packageName = R.class.getPackage().getName();
int id = res.getIdentifier(fileName, null, packageName);
if (id != 0) {
InputStream in = res.openRawResource(id);
byte[] buf = new byte[4096];
int read;
while ((read = in.read(buf)) > 0) {
mOutput.write(buf, 0, read);
}
}
}
void writeString(String str) throws IOException {
mOutput.write(str.getBytes());
}
void writeString(String str, int offset, int count) throws IOException {
mOutput.write(str.getBytes(), offset, count);
}
void cleanup() {
try {
mOutput.close();
} catch (Exception e) {
Log.e(TAG, "Failed to close pipe!", e);
}
}
}