Change SWE app properties back to stock Android

- Changed project package name from com.android.swe.browser
back to com.android.browser along with code references to
old package name.
- Changes to AndroidManifest making it conform closer to stock
browser manifest.
- Changed app and apk name back to Browser.

Change-Id: I778ee1d1197bd50bd4a4850eef6d1d7f4ef0ad0b
diff --git a/src/com/android/browser/DataController.java b/src/com/android/browser/DataController.java
new file mode 100644
index 0000000..eb47080
--- /dev/null
+++ b/src/com/android/browser/DataController.java
@@ -0,0 +1,302 @@
+/*
+ * Copyright (C) 2010 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.android.browser;
+
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteException;
+import android.graphics.Bitmap;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.Message;
+import android.util.Log;
+
+import com.android.browser.platformsupport.BrowserContract;
+import com.android.browser.platformsupport.BrowserContract.History;
+import com.android.browser.provider.BrowserProvider2.Thumbnails;
+
+import java.nio.ByteBuffer;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+
+public class DataController {
+    private static final String LOGTAG = "DataController";
+    // Message IDs
+    private static final int HISTORY_UPDATE_VISITED = 100;
+    private static final int HISTORY_UPDATE_TITLE = 101;
+    private static final int QUERY_URL_IS_BOOKMARK = 200;
+    private static final int TAB_LOAD_THUMBNAIL = 201;
+    private static final int TAB_SAVE_THUMBNAIL = 202;
+    private static final int TAB_DELETE_THUMBNAIL = 203;
+    private static DataController sInstance;
+
+    private Context mContext;
+    private DataControllerHandler mDataHandler;
+    private Handler mCbHandler; // To respond on the UI thread
+    private ByteBuffer mBuffer; // to capture thumbnails
+
+    /* package */ static interface OnQueryUrlIsBookmark {
+        void onQueryUrlIsBookmark(String url, boolean isBookmark);
+    }
+    private static class CallbackContainer {
+        Object replyTo;
+        Object[] args;
+    }
+
+    private static class DCMessage {
+        int what;
+        Object obj;
+        Object replyTo;
+        DCMessage(int w, Object o) {
+            what = w;
+            obj = o;
+        }
+    }
+
+    /* package */ static DataController getInstance(Context c) {
+        if (sInstance == null) {
+            sInstance = new DataController(c);
+        }
+        return sInstance;
+    }
+
+    private DataController(Context c) {
+        mContext = c.getApplicationContext();
+        mDataHandler = new DataControllerHandler();
+        mDataHandler.start();
+        mCbHandler = new Handler() {
+            @Override
+            public void handleMessage(Message msg) {
+                CallbackContainer cc = (CallbackContainer) msg.obj;
+                switch (msg.what) {
+                    case QUERY_URL_IS_BOOKMARK: {
+                        OnQueryUrlIsBookmark cb = (OnQueryUrlIsBookmark) cc.replyTo;
+                        String url = (String) cc.args[0];
+                        boolean isBookmark = (Boolean) cc.args[1];
+                        cb.onQueryUrlIsBookmark(url, isBookmark);
+                        break;
+                    }
+                }
+            }
+        };
+    }
+
+    public void updateVisitedHistory(String url) {
+        mDataHandler.sendMessage(HISTORY_UPDATE_VISITED, url);
+    }
+
+    public void updateHistoryTitle(String url, String title) {
+        mDataHandler.sendMessage(HISTORY_UPDATE_TITLE, new String[] { url, title });
+    }
+
+    public void queryBookmarkStatus(String url, OnQueryUrlIsBookmark replyTo) {
+        if (url == null || url.trim().length() == 0) {
+            // null or empty url is never a bookmark
+            replyTo.onQueryUrlIsBookmark(url, false);
+            return;
+        }
+        mDataHandler.sendMessage(QUERY_URL_IS_BOOKMARK, url.trim(), replyTo);
+    }
+
+    public void loadThumbnail(Tab tab) {
+        mDataHandler.sendMessage(TAB_LOAD_THUMBNAIL, tab);
+    }
+
+    public void deleteThumbnail(Tab tab) {
+        mDataHandler.sendMessage(TAB_DELETE_THUMBNAIL, tab.getId());
+    }
+
+    public void saveThumbnail(Tab tab) {
+        mDataHandler.sendMessage(TAB_SAVE_THUMBNAIL, tab);
+    }
+
+    // The standard Handler and Message classes don't allow the queue manipulation
+    // we want (such as peeking). So we use our own queue.
+    class DataControllerHandler extends Thread {
+        private BlockingQueue<DCMessage> mMessageQueue
+                = new LinkedBlockingQueue<DCMessage>();
+
+        public DataControllerHandler() {
+            super("DataControllerHandler");
+        }
+
+        @Override
+        public void run() {
+            setPriority(Thread.MIN_PRIORITY);
+            while (true) {
+                try {
+                    handleMessage(mMessageQueue.take());
+                } catch (InterruptedException ex) {
+                    break;
+                }
+            }
+        }
+
+        void sendMessage(int what, Object obj) {
+            DCMessage m = new DCMessage(what, obj);
+            mMessageQueue.add(m);
+        }
+
+        void sendMessage(int what, Object obj, Object replyTo) {
+            DCMessage m = new DCMessage(what, obj);
+            m.replyTo = replyTo;
+            mMessageQueue.add(m);
+        }
+
+        private void handleMessage(DCMessage msg) {
+            switch (msg.what) {
+            case HISTORY_UPDATE_VISITED:
+                doUpdateVisitedHistory((String) msg.obj);
+                break;
+            case HISTORY_UPDATE_TITLE:
+                String[] args = (String[]) msg.obj;
+                doUpdateHistoryTitle(args[0], args[1]);
+                break;
+            case QUERY_URL_IS_BOOKMARK:
+                // TODO: Look for identical messages in the queue and remove them
+                // TODO: Also, look for partial matches and merge them (such as
+                //       multiple callbacks querying the same URL)
+                doQueryBookmarkStatus((String) msg.obj, msg.replyTo);
+                break;
+            case TAB_LOAD_THUMBNAIL:
+                doLoadThumbnail((Tab) msg.obj);
+                break;
+            case TAB_DELETE_THUMBNAIL:
+                ContentResolver cr = mContext.getContentResolver();
+                try {
+                    cr.delete(ContentUris.withAppendedId(
+                            Thumbnails.CONTENT_URI, (Long)msg.obj),
+                            null, null);
+                } catch (Throwable t) {}
+                break;
+            case TAB_SAVE_THUMBNAIL:
+                doSaveThumbnail((Tab)msg.obj);
+                break;
+            }
+        }
+
+        private byte[] getCaptureBlob(Tab tab) {
+            synchronized (tab) {
+                Bitmap capture = tab.getScreenshot();
+                if (capture == null) {
+                    return null;
+                }
+                if (mBuffer == null || mBuffer.limit() < capture.getByteCount()) {
+                    mBuffer = ByteBuffer.allocate(capture.getByteCount());
+                }
+                capture.copyPixelsToBuffer(mBuffer);
+                mBuffer.rewind();
+                return mBuffer.array();
+            }
+        }
+
+        private void doSaveThumbnail(Tab tab) {
+            byte[] blob = getCaptureBlob(tab);
+            if (blob == null) {
+                return;
+            }
+            ContentResolver cr = mContext.getContentResolver();
+            ContentValues values = new ContentValues();
+            values.put(Thumbnails._ID, tab.getId());
+            values.put(Thumbnails.THUMBNAIL, blob);
+            cr.insert(Thumbnails.CONTENT_URI, values);
+        }
+
+        private void doLoadThumbnail(Tab tab) {
+            ContentResolver cr = mContext.getContentResolver();
+            Cursor c = null;
+            try {
+                Uri uri = ContentUris.withAppendedId(Thumbnails.CONTENT_URI, tab.getId());
+                c = cr.query(uri, new String[] {Thumbnails._ID,
+                        Thumbnails.THUMBNAIL}, null, null, null);
+                if (c.moveToFirst()) {
+                    byte[] data = c.getBlob(1);
+                    if (data != null && data.length > 0) {
+                        tab.updateCaptureFromBlob(data);
+                    }
+                }
+            } finally {
+                if (c != null) {
+                    c.close();
+                }
+            }
+        }
+
+        private void doUpdateVisitedHistory(String url) {
+            ContentResolver cr = mContext.getContentResolver();
+            Cursor c = null;
+            try {
+                c = cr.query(History.CONTENT_URI, new String[] {History._ID, History.VISITS},
+                        History.URL + "=?", new String[] { url }, null);
+                if (c.moveToFirst()) {
+                    ContentValues values = new ContentValues();
+                    values.put(History.VISITS, c.getInt(1) + 1);
+                    values.put(History.DATE_LAST_VISITED, System.currentTimeMillis());
+                    cr.update(ContentUris.withAppendedId(History.CONTENT_URI, c.getLong(0)),
+                            values, null, null);
+                } else {
+                    android.provider.Browser.truncateHistory(cr);
+                    ContentValues values = new ContentValues();
+                    values.put(History.URL, url);
+                    values.put(History.VISITS, 1);
+                    values.put(History.DATE_LAST_VISITED, System.currentTimeMillis());
+                    values.put(History.TITLE, url);
+                    values.put(History.DATE_CREATED, 0);
+                    values.put(History.USER_ENTERED, 0);
+                    cr.insert(History.CONTENT_URI, values);
+                }
+            } finally {
+                if (c != null) c.close();
+            }
+        }
+
+        private void doQueryBookmarkStatus(String url, Object replyTo) {
+            // Check to see if the site is bookmarked
+            Cursor cursor = null;
+            boolean isBookmark = false;
+            try {
+                cursor = mContext.getContentResolver().query(
+                        BookmarkUtils.getBookmarksUri(mContext),
+                        new String[] { BrowserContract.Bookmarks.URL },
+                        BrowserContract.Bookmarks.URL + " == ?",
+                        new String[] { url },
+                        null);
+                isBookmark = cursor.moveToFirst();
+            } catch (SQLiteException e) {
+                Log.e(LOGTAG, "Error checking for bookmark: " + e);
+            } finally {
+                if (cursor != null) cursor.close();
+            }
+            CallbackContainer cc = new CallbackContainer();
+            cc.replyTo = replyTo;
+            cc.args = new Object[] { url, isBookmark };
+            mCbHandler.obtainMessage(QUERY_URL_IS_BOOKMARK, cc).sendToTarget();
+        }
+
+        private void doUpdateHistoryTitle(String url, String title) {
+            ContentResolver cr = mContext.getContentResolver();
+            ContentValues values = new ContentValues();
+            values.put(History.TITLE, title);
+            cr.update(History.CONTENT_URI, values, History.URL + "=?",
+                    new String[] { url });
+        }
+    }
+}