Home | History | Annotate | Download | only in browser
      1 /*
      2  * Copyright (C) 2006 The Android Open Source Project
      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 
     17 package com.android.browser;
     18 
     19 import android.app.Activity;
     20 import android.content.ContentResolver;
     21 import android.content.Intent;
     22 import android.content.res.Resources;
     23 import android.database.Cursor;
     24 import android.graphics.Bitmap;
     25 import android.net.ParseException;
     26 import android.net.WebAddress;
     27 import android.os.Bundle;
     28 import android.os.Handler;
     29 import android.os.Message;
     30 import android.provider.Browser;
     31 import android.view.View;
     32 import android.view.Window;
     33 import android.widget.EditText;
     34 import android.widget.TextView;
     35 import android.widget.Toast;
     36 
     37 import java.net.URI;
     38 import java.net.URISyntaxException;
     39 import java.util.Date;
     40 
     41 public class AddBookmarkPage extends Activity {
     42 
     43     private final String LOGTAG = "Bookmarks";
     44 
     45     private EditText    mTitle;
     46     private EditText    mAddress;
     47     private TextView    mButton;
     48     private View        mCancelButton;
     49     private boolean     mEditingExisting;
     50     private Bundle      mMap;
     51     private String      mTouchIconUrl;
     52     private Bitmap      mThumbnail;
     53     private String      mOriginalUrl;
     54 
     55     // Message IDs
     56     private static final int SAVE_BOOKMARK = 100;
     57 
     58     private Handler mHandler;
     59 
     60     private View.OnClickListener mSaveBookmark = new View.OnClickListener() {
     61         public void onClick(View v) {
     62             if (save()) {
     63                 finish();
     64             }
     65         }
     66     };
     67 
     68     private View.OnClickListener mCancel = new View.OnClickListener() {
     69         public void onClick(View v) {
     70             finish();
     71         }
     72     };
     73 
     74     protected void onCreate(Bundle icicle) {
     75         super.onCreate(icicle);
     76         requestWindowFeature(Window.FEATURE_LEFT_ICON);
     77         setContentView(R.layout.browser_add_bookmark);
     78         setTitle(R.string.save_to_bookmarks);
     79         getWindow().setFeatureDrawableResource(Window.FEATURE_LEFT_ICON, R.drawable.ic_list_bookmark);
     80 
     81         String title = null;
     82         String url = null;
     83         mMap = getIntent().getExtras();
     84         if (mMap != null) {
     85             Bundle b = mMap.getBundle("bookmark");
     86             if (b != null) {
     87                 mMap = b;
     88                 mEditingExisting = true;
     89                 setTitle(R.string.edit_bookmark);
     90             }
     91             title = mMap.getString("title");
     92             url = mOriginalUrl = mMap.getString("url");
     93             mTouchIconUrl = mMap.getString("touch_icon_url");
     94             mThumbnail = (Bitmap) mMap.getParcelable("thumbnail");
     95         }
     96 
     97         mTitle = (EditText) findViewById(R.id.title);
     98         mTitle.setText(title);
     99         mAddress = (EditText) findViewById(R.id.address);
    100         mAddress.setText(url);
    101 
    102         View.OnClickListener accept = mSaveBookmark;
    103         mButton = (TextView) findViewById(R.id.OK);
    104         mButton.setOnClickListener(accept);
    105 
    106         mCancelButton = findViewById(R.id.cancel);
    107         mCancelButton.setOnClickListener(mCancel);
    108 
    109         if (!getWindow().getDecorView().isInTouchMode()) {
    110             mButton.requestFocus();
    111         }
    112     }
    113 
    114     /**
    115      * Runnable to save a bookmark, so it can be performed in its own thread.
    116      */
    117     private class SaveBookmarkRunnable implements Runnable {
    118         private Message mMessage;
    119         public SaveBookmarkRunnable(Message msg) {
    120             mMessage = msg;
    121         }
    122         public void run() {
    123             // Unbundle bookmark data.
    124             Bundle bundle = mMessage.getData();
    125             String title = bundle.getString("title");
    126             String url = bundle.getString("url");
    127             boolean invalidateThumbnail = bundle.getBoolean(
    128                     "invalidateThumbnail");
    129             Bitmap thumbnail = invalidateThumbnail ? null
    130                     : (Bitmap) bundle.getParcelable("thumbnail");
    131             String touchIconUrl = bundle.getString("touchIconUrl");
    132 
    133             // Save to the bookmarks DB.
    134             try {
    135                 final ContentResolver cr = getContentResolver();
    136                 Bookmarks.addBookmark(null, cr, url, title, thumbnail, true);
    137                 if (touchIconUrl != null) {
    138                     new DownloadTouchIcon(cr, url).execute(mTouchIconUrl);
    139                 }
    140                 mMessage.arg1 = 1;
    141             } catch (IllegalStateException e) {
    142                 mMessage.arg1 = 0;
    143             }
    144             mMessage.sendToTarget();
    145         }
    146     }
    147 
    148     private void createHandler() {
    149         if (mHandler == null) {
    150             mHandler = new Handler() {
    151                 @Override
    152                 public void handleMessage(Message msg) {
    153                     switch (msg.what) {
    154                         case SAVE_BOOKMARK:
    155                             if (1 == msg.arg1) {
    156                                 Toast.makeText(AddBookmarkPage.this, R.string.bookmark_saved,
    157                                         Toast.LENGTH_LONG).show();
    158                             } else {
    159                                 Toast.makeText(AddBookmarkPage.this, R.string.bookmark_not_saved,
    160                                         Toast.LENGTH_LONG).show();
    161                             }
    162                             break;
    163                     }
    164                 }
    165             };
    166         }
    167     }
    168 
    169     /**
    170      * Parse the data entered in the dialog and post a message to update the bookmarks database.
    171      */
    172     boolean save() {
    173         createHandler();
    174 
    175         String title = mTitle.getText().toString().trim();
    176         String unfilteredUrl =
    177                 BrowserActivity.fixUrl(mAddress.getText().toString());
    178         boolean emptyTitle = title.length() == 0;
    179         boolean emptyUrl = unfilteredUrl.trim().length() == 0;
    180         Resources r = getResources();
    181         if (emptyTitle || emptyUrl) {
    182             if (emptyTitle) {
    183                 mTitle.setError(r.getText(R.string.bookmark_needs_title));
    184             }
    185             if (emptyUrl) {
    186                 mAddress.setError(r.getText(R.string.bookmark_needs_url));
    187             }
    188             return false;
    189         }
    190         String url = unfilteredUrl.trim();
    191         try {
    192             // We allow bookmarks with a javascript: scheme, but these will in most cases
    193             // fail URI parsing, so don't try it if that's the kind of bookmark we have.
    194 
    195             if (!url.toLowerCase().startsWith("javascript:")) {
    196                 URI uriObj = new URI(url);
    197                 String scheme = uriObj.getScheme();
    198                 if (!Bookmarks.urlHasAcceptableScheme(url)) {
    199                     // If the scheme was non-null, let the user know that we
    200                     // can't save their bookmark. If it was null, we'll assume
    201                     // they meant http when we parse it in the WebAddress class.
    202                     if (scheme != null) {
    203                         mAddress.setError(r.getText(R.string.bookmark_cannot_save_url));
    204                         return false;
    205                     }
    206                     WebAddress address;
    207                     try {
    208                         address = new WebAddress(unfilteredUrl);
    209                     } catch (ParseException e) {
    210                         throw new URISyntaxException("", "");
    211                     }
    212                     if (address.mHost.length() == 0) {
    213                         throw new URISyntaxException("", "");
    214                     }
    215                     url = address.toString();
    216                 }
    217             }
    218         } catch (URISyntaxException e) {
    219             mAddress.setError(r.getText(R.string.bookmark_url_not_valid));
    220             return false;
    221         }
    222 
    223         if (mEditingExisting) {
    224             mMap.putString("title", title);
    225             mMap.putString("url", url);
    226             mMap.putBoolean("invalidateThumbnail", !url.equals(mOriginalUrl));
    227             setResult(RESULT_OK, (new Intent()).setAction(
    228                     getIntent().toString()).putExtras(mMap));
    229         } else {
    230             // Post a message to write to the DB.
    231             Bundle bundle = new Bundle();
    232             bundle.putString("title", title);
    233             bundle.putString("url", url);
    234             bundle.putParcelable("thumbnail", mThumbnail);
    235             bundle.putBoolean("invalidateThumbnail", !url.equals(mOriginalUrl));
    236             bundle.putString("touchIconUrl", mTouchIconUrl);
    237             Message msg = Message.obtain(mHandler, SAVE_BOOKMARK);
    238             msg.setData(bundle);
    239             // Start a new thread so as to not slow down the UI
    240             Thread t = new Thread(new SaveBookmarkRunnable(msg));
    241             t.start();
    242             setResult(RESULT_OK);
    243             LogTag.logBookmarkAdded(url, "bookmarkview");
    244         }
    245         return true;
    246     }
    247 }
    248