summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Tharp <dtharp@codeaurora.org>2015-06-16 11:17:34 -0700
committerjrizzoli <joey@cyanogenmoditalia.it>2015-08-28 13:15:45 +0200
commit490ca7fb96367bd8444698b59a5d0fe17f1a90d1 (patch)
tree7fe4f6576f4b4bc3e572bf8868712de11494ecd5
parent62bc791f1bcbfb7daeb76142239a70ab3dc1f6ec (diff)
downloadandroid_packages_apps_Gello-490ca7fb96367bd8444698b59a5d0fe17f1a90d1.tar.gz
android_packages_apps_Gello-490ca7fb96367bd8444698b59a5d0fe17f1a90d1.tar.bz2
android_packages_apps_Gello-490ca7fb96367bd8444698b59a5d0fe17f1a90d1.zip
MDM Managed Bookmarks
When passed a JSON description of a managed bookmarks tree through the MDM mechanism, SWE populates a special 'Managed' bookmark folder which builds the specified tree beneath it. If the JSON managed bookmarks descriptor is the same as the currently enforced descriptor, the current managed tree is left alone, otherwise the current managed bookmarks tree is removed and the new descriptor is used to populate a new Managed tree. If an MDM bundle is received without a JSON managed bookmarks descriptior, any existing 'Managed' bookmark tree is removed. The bookmark elements in the 'Managed' tree are not editable by the user (the edit and delete pop-up menu items are greyed-out), and are rendered with a briefcase icon overlaid. This commit adds the following new icons (new art created in-house): res/drawable-xxhdpi/img_deco_mdm_badge_bright.png res/drawable-xxhdpi/img_deco_mdm_badge_dark.png Other new files are the core implementation of the ManagedBookmarkRestriction and the tests for it: ManagedBookmarksRestriction.java ManagedBookmarksRestrictionsTest.java Also included in this commit are some debugging refinements which required minor edits of unrelated MDM restrictions. Change-Id: Iac7ae6bee788418d3d444577951a8d29af2a67f2
-rw-r--r--res/drawable-xxhdpi/img_deco_mdm_badge_bright.pngbin0 -> 3663 bytes
-rw-r--r--res/drawable-xxhdpi/img_deco_mdm_badge_dark.pngbin0 -> 3897 bytes
-rw-r--r--res/menu/bookmarkscontext.xml4
-rw-r--r--src/com/android/browser/BrowserActivity.java2
-rw-r--r--src/com/android/browser/BrowserBookmarksAdapter.java46
-rw-r--r--src/com/android/browser/BrowserBookmarksAdapterItem.java1
-rw-r--r--src/com/android/browser/BrowserBookmarksPage.java118
-rw-r--r--src/com/android/browser/mdm/DoNotTrackRestriction.java2
-rw-r--r--src/com/android/browser/mdm/IncognitoRestriction.java2
-rw-r--r--src/com/android/browser/mdm/ManagedBookmarksRestriction.java441
-rw-r--r--src/com/android/browser/mdm/ProxyRestriction.java2
-rw-r--r--src/com/android/browser/mdm/Restriction.java7
-rw-r--r--src/com/android/browser/mdm/SearchEngineRestriction.java2
-rw-r--r--src/com/android/browser/mdm/ThirdPartyCookiesRestriction.java2
-rw-r--r--src/com/android/browser/mdm/URLFilterRestriction.java2
-rw-r--r--src/com/android/browser/mdm/tests/ManagedBookmarksRestrictionsTest.java278
-rw-r--r--src/com/android/browser/view/BookmarkThumbImageView.java48
17 files changed, 912 insertions, 45 deletions
diff --git a/res/drawable-xxhdpi/img_deco_mdm_badge_bright.png b/res/drawable-xxhdpi/img_deco_mdm_badge_bright.png
new file mode 100644
index 00000000..060f1839
--- /dev/null
+++ b/res/drawable-xxhdpi/img_deco_mdm_badge_bright.png
Binary files differ
diff --git a/res/drawable-xxhdpi/img_deco_mdm_badge_dark.png b/res/drawable-xxhdpi/img_deco_mdm_badge_dark.png
new file mode 100644
index 00000000..0afa667a
--- /dev/null
+++ b/res/drawable-xxhdpi/img_deco_mdm_badge_dark.png
Binary files differ
diff --git a/res/menu/bookmarkscontext.xml b/res/menu/bookmarkscontext.xml
index df6f9afe..ac19e0ba 100644
--- a/res/menu/bookmarkscontext.xml
+++ b/res/menu/bookmarkscontext.xml
@@ -38,9 +38,9 @@
android:visible="false">
<item android:id="@+id/new_window_context_menu_id"
android:title="@string/open_all_in_new_window"/>
- <item android:id="@+id/edit_context_menu_id"
+ <item android:id="@+id/folder_edit_context_menu_id"
android:title="@string/edit_folder"/>
- <item android:id="@+id/delete_context_menu_id"
+ <item android:id="@+id/folder_delete_context_menu_id"
android:title="@string/delete_folder"/>
</group>
</menu>
diff --git a/src/com/android/browser/BrowserActivity.java b/src/com/android/browser/BrowserActivity.java
index 0f100724..8bade816 100644
--- a/src/com/android/browser/BrowserActivity.java
+++ b/src/com/android/browser/BrowserActivity.java
@@ -41,6 +41,7 @@ import android.view.Window;
import org.chromium.base.VisibleForTesting;
import com.android.browser.R;
+import com.android.browser.mdm.ManagedBookmarksRestriction;
import com.android.browser.mdm.ThirdPartyCookiesRestriction;
import com.android.browser.search.DefaultSearchEngine;
import com.android.browser.search.SearchEngine;
@@ -161,6 +162,7 @@ public class BrowserActivity extends Activity {
// MDM Restrictions not tied to a UI element initialized here.
ThirdPartyCookiesRestriction.getInstance();
+ ManagedBookmarksRestriction.getInstance();
}
@VisibleForTesting
diff --git a/src/com/android/browser/BrowserBookmarksAdapter.java b/src/com/android/browser/BrowserBookmarksAdapter.java
index 2acc9c99..ae9c4915 100644
--- a/src/com/android/browser/BrowserBookmarksAdapter.java
+++ b/src/com/android/browser/BrowserBookmarksAdapter.java
@@ -19,6 +19,7 @@ package com.android.browser;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.view.LayoutInflater;
import android.view.View;
@@ -26,7 +27,7 @@ import android.view.ViewGroup;
import android.widget.ImageView.ScaleType;
import android.widget.TextView;
-import com.android.browser.R;
+import com.android.browser.mdm.ManagedBookmarksRestriction;
import com.android.browser.platformsupport.BrowserContract.Bookmarks;
import com.android.browser.util.ThreadedCursorAdapter;
import com.android.browser.view.BookmarkContainer;
@@ -35,6 +36,7 @@ import com.android.browser.view.BookmarkThumbImageView;
public class BrowserBookmarksAdapter extends
ThreadedCursorAdapter<BrowserBookmarksAdapterItem> {
+ private static final String TAG = "BrowserBookmarksAdapter";
LayoutInflater mInflater;
Context mContext;
@@ -85,19 +87,50 @@ public class BrowserBookmarksAdapter extends
padding, view.getPaddingBottom());
BookmarkThumbImageView thumb = (BookmarkThumbImageView) view.findViewById(R.id.thumb_image);
TextView tv = (TextView) view.findViewById(R.id.label);
+ float badgeScale = 0.8f;
tv.setText(item.title);
if (item.is_folder) {
// folder
- thumb.setImageResource(R.drawable.thumb_bookmark_widget_folder_holo);
- thumb.setScaleType(ScaleType.FIT_END);
+ if(item.is_mdm_managed) {
+ // build a bitmap that has the mdm badge overlaid
+ Bitmap b = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.thumb_bookmark_widget_folder_holo);
+ Bitmap bm = BrowserBookmarksPage.overlayBookmarkBitmap(b, R.drawable.img_deco_mdm_badge_bright, mContext, badgeScale);
+ thumb.setmAdjustDown(false);
+ thumb.setScaleType(ScaleType.CENTER_INSIDE);
+ thumb.setImageBitmap(bm);
+ }
+ else {
+ thumb.setmAdjustDown(true);
+ thumb.setImageResource(R.drawable.thumb_bookmark_widget_folder_holo);
+ thumb.setScaleType(ScaleType.FIT_END);
+ }
thumb.setBackground(null);
} else {
if (item.thumbnail == null || !item.has_thumbnail) {
- thumb.setScaleType(ScaleType.CENTER_CROP);
- thumb.setImageResource(R.drawable.browser_thumbnail);
+ if(item.is_mdm_managed) {
+ Bitmap b = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.browser_thumbnail);
+ Bitmap bm = BrowserBookmarksPage.overlayBookmarkBitmap(b, R.drawable.img_deco_mdm_badge_bright, mContext, badgeScale);
+ thumb.setmAdjustDown(false);
+ thumb.setScaleType(ScaleType.CENTER_INSIDE);
+ thumb.setImageBitmap(bm);
+ }
+ else {
+ thumb.setmAdjustDown(true);
+ thumb.setScaleType(ScaleType.CENTER_CROP);
+ thumb.setImageResource(R.drawable.browser_thumbnail);
+ }
} else {
- thumb.setImageDrawable(item.thumbnail);
+ if (item.is_mdm_managed) {
+ Bitmap b = item.thumbnail.getBitmap();
+ Bitmap bm = BrowserBookmarksPage.overlayBookmarkBitmap(b, R.drawable.img_deco_mdm_badge_bright, mContext, badgeScale);
+ thumb.setmAdjustDown(false);
+ thumb.setScaleType(ScaleType.CENTER_INSIDE);
+ thumb.setImageBitmap(bm);
+ } else {
+ thumb.setmAdjustDown(true);
+ thumb.setImageDrawable(item.thumbnail);
+ }
}
}
}
@@ -119,6 +152,7 @@ public class BrowserBookmarksAdapter extends
item.is_folder = c.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) != 0;
item.title = getTitle(c);
item.url = c.getString(BookmarksLoader.COLUMN_INDEX_URL);
+ item.is_mdm_managed = ManagedBookmarksRestriction.getInstance().mDb.isMdmElement(getItemId(c));
return item;
}
diff --git a/src/com/android/browser/BrowserBookmarksAdapterItem.java b/src/com/android/browser/BrowserBookmarksAdapterItem.java
index 6b995787..5fb648e1 100644
--- a/src/com/android/browser/BrowserBookmarksAdapterItem.java
+++ b/src/com/android/browser/BrowserBookmarksAdapterItem.java
@@ -23,4 +23,5 @@ public class BrowserBookmarksAdapterItem {
public BitmapDrawable thumbnail;
public boolean has_thumbnail;
public boolean is_folder;
+ public boolean is_mdm_managed;
}
diff --git a/src/com/android/browser/BrowserBookmarksPage.java b/src/com/android/browser/BrowserBookmarksPage.java
index d026b09d..e0042255 100644
--- a/src/com/android/browser/BrowserBookmarksPage.java
+++ b/src/com/android/browser/BrowserBookmarksPage.java
@@ -34,13 +34,14 @@ import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
+import android.graphics.Canvas;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
+import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
-import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
@@ -50,7 +51,7 @@ import android.widget.ExpandableListView;
import android.widget.ExpandableListView.OnChildClickListener;
import android.widget.Toast;
-import com.android.browser.R;
+import com.android.browser.mdm.ManagedBookmarksRestriction;
import com.android.browser.platformsupport.BrowserContract;
import com.android.browser.platformsupport.BrowserContract.Accounts;
import com.android.browser.provider.BrowserProvider2;
@@ -78,6 +79,8 @@ public class BrowserBookmarksPage extends Fragment implements View.OnCreateConte
LoaderManager.LoaderCallbacks<Cursor>, BreadCrumbView.Controller,
OnChildClickListener {
+ private static final String TAG = "BrowserBookmarksPage";
+
public static class ExtraDragState {
public int childPosition;
public int groupPosition;
@@ -196,6 +199,7 @@ public class BrowserBookmarksPage extends Fragment implements View.OnCreateConte
case R.id.open_context_menu_id:
loadUrl(adapter, childPosition);
break;
+ case R.id.folder_edit_context_menu_id:
case R.id.edit_context_menu_id:
editBookmark(adapter, childPosition);
break;
@@ -203,6 +207,7 @@ public class BrowserBookmarksPage extends Fragment implements View.OnCreateConte
Cursor c = adapter.getItem(childPosition);
activity.sendBroadcast(createShortcutIntent(getActivity(), c));
break;
+ case R.id.folder_delete_context_menu_id:
case R.id.delete_context_menu_id:
displayRemoveBookmarkDialog(adapter, childPosition);
break;
@@ -287,21 +292,31 @@ public class BrowserBookmarksPage extends Fragment implements View.OnCreateConte
}
boolean isFolder
= cursor.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) != 0;
+ boolean isMdmElem = ManagedBookmarksRestriction.getInstance().mDb.
+ isMdmElement(cursor.getLong(BookmarksLoader.COLUMN_INDEX_ID));
final Activity activity = getActivity();
MenuInflater inflater = activity.getMenuInflater();
inflater.inflate(R.menu.bookmarkscontext, menu);
if (isFolder) {
menu.setGroupVisible(R.id.FOLDER_CONTEXT_MENU, true);
+ if(isMdmElem) {
+ menu.findItem(R.id.folder_edit_context_menu_id).setEnabled(false);
+ menu.findItem(R.id.folder_delete_context_menu_id).setEnabled(false);
+ }
} else {
menu.setGroupVisible(R.id.BOOKMARK_CONTEXT_MENU, true);
if (mDisableNewWindow) {
menu.findItem(R.id.new_window_context_menu_id).setVisible(false);
}
+ if(isMdmElem) {
+ menu.findItem(R.id.edit_context_menu_id).setEnabled(false);
+ menu.findItem(R.id.delete_context_menu_id).setEnabled(false);
+ }
}
BookmarkItem header = new BookmarkItem(activity);
header.setEnableScrolling(true);
- populateBookmarkItem(cursor, header, isFolder);
+ populateBookmarkItem(cursor, header, isFolder, isMdmElem);
menu.setHeaderView(header);
int count = menu.size();
@@ -316,12 +331,71 @@ public class BrowserBookmarksPage extends Fragment implements View.OnCreateConte
|| type == BrowserContract.Bookmarks.BOOKMARK_TYPE_FOLDER;
}
- private void populateBookmarkItem(Cursor cursor, BookmarkItem item, boolean isFolder) {
+ public static Bitmap overlayBookmarkBitmap(Bitmap origImage, int overlayResId, Context context,
+ float overlayScaleFactor) {
+ if (origImage == null) {
+ Log.e(TAG, "Orig Image is null!");
+ return origImage;
+ }
+ // Get metrics for incoming bitmap
+ int origWidth = origImage.getWidth();
+ int origHeight = origImage.getHeight();
+
+ // Load the bitmap for the badge
+ Bitmap srcOverlay = BitmapFactory.decodeResource(context.getResources(), overlayResId);
+
+ if (srcOverlay == null) {
+ Log.e(TAG, "Overlay bitmap creation failed");
+ return origImage;
+ }
+
+ // Scale the badge
+ float fx = (float) srcOverlay.getWidth() * overlayScaleFactor;
+ float fy = (float) srcOverlay.getHeight() * overlayScaleFactor;
+ Bitmap scaledOverlay = Bitmap.createScaledBitmap(srcOverlay, (int) fx, (int) fy, true);
+ if (scaledOverlay == null) {
+ srcOverlay.recycle();
+ Runtime.getRuntime().gc();
+ Log.e(TAG, "Scaled bitmap creation failed");
+ return origImage;
+ }
+
+ // Create the bitmap we are compositing into
+ Bitmap overlaid = Bitmap.createBitmap(origWidth, origHeight, Bitmap.Config.ARGB_8888);
+ if (overlaid == null) {
+ srcOverlay.recycle();
+ scaledOverlay.recycle();
+ Runtime.getRuntime().gc();
+ Log.e(TAG, "Composite bitmap creation failed");
+ return origImage;
+ }
+
+ // Do the overlay
+ Canvas comboImage = new Canvas(overlaid);
+ comboImage.drawBitmap(origImage, 0, 0, null);
+
+ comboImage.drawBitmap(scaledOverlay,
+ origWidth - scaledOverlay.getWidth(),
+ origHeight - scaledOverlay.getHeight(),
+ null);
+
+ // Clean up our bitmaps
+ srcOverlay.recycle();
+ scaledOverlay.recycle();
+ Runtime.getRuntime().gc();
+
+ return overlaid;
+ }
+
+ private void populateBookmarkItem(Cursor cursor, BookmarkItem item, boolean isFolder, boolean isMdmElem) {
item.setName(cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE));
if (isFolder) {
item.setUrl(null);
Bitmap bitmap =
BitmapFactory.decodeResource(getResources(), R.drawable.ic_deco_folder_normal);
+ if (isMdmElem) {
+ bitmap = overlayBookmarkBitmap(bitmap, R.drawable.img_deco_mdm_badge_bright, getActivity(), 0.25f);
+ }
item.setFavicon(bitmap);
new LookupBookmarkCount(getActivity(), item)
.execute(cursor.getLong(BookmarksLoader.COLUMN_INDEX_ID));
@@ -329,6 +403,12 @@ public class BrowserBookmarksPage extends Fragment implements View.OnCreateConte
String url = cursor.getString(BookmarksLoader.COLUMN_INDEX_URL);
item.setUrl(url);
Bitmap bitmap = getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_FAVICON);
+ if (isMdmElem) {
+ if (null == bitmap) {
+ bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_deco_favicon_normal);
+ }
+ bitmap = overlayBookmarkBitmap(bitmap, R.drawable.img_deco_mdm_badge_bright, getActivity(), 0.25f);
+ }
item.setFavicon(bitmap);
}
}
@@ -419,11 +499,18 @@ public class BrowserBookmarksPage extends Fragment implements View.OnCreateConte
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
- Intent intent = new Intent(activity, AddBookmarkPage.class);
- intent.putExtra(BrowserContract.Bookmarks.URL, "http://");
- intent.putExtra(BrowserContract.Bookmarks.TITLE, "");
- intent.putExtra(BrowserContract.Bookmarks.PARENT, mCurrentFolderId);
- activity.startActivity(intent);
+ ManagedBookmarksRestriction mbr = ManagedBookmarksRestriction.getInstance();
+ if (mbr.isEnabled() &&
+ mbr.mDb.isMdmElement(mCurrentFolderId)) {
+ Toast.makeText(getActivity(), R.string.mdm_managed_alert, Toast.LENGTH_SHORT).show();
+ }
+ else {
+ Intent intent = new Intent(activity, AddBookmarkPage.class);
+ intent.putExtra(BrowserContract.Bookmarks.URL, "http://");
+ intent.putExtra(BrowserContract.Bookmarks.TITLE, "");
+ intent.putExtra(BrowserContract.Bookmarks.PARENT, mCurrentFolderId);
+ activity.startActivity(intent);
+ }
}
});
@@ -431,9 +518,16 @@ public class BrowserBookmarksPage extends Fragment implements View.OnCreateConte
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
- Intent intent = new Intent(activity, AddBookmarkFolder.class);
- intent.putExtra(BrowserContract.Bookmarks.PARENT, mCurrentFolderId);
- activity.startActivity(intent);
+ ManagedBookmarksRestriction mbr = ManagedBookmarksRestriction.getInstance();
+ if (mbr.isEnabled() &&
+ mbr.mDb.isMdmElement(mCurrentFolderId)) {
+ Toast.makeText(getActivity(), R.string.mdm_managed_alert, Toast.LENGTH_SHORT).show();
+ }
+ else {
+ Intent intent = new Intent(activity, AddBookmarkFolder.class);
+ intent.putExtra(BrowserContract.Bookmarks.PARENT, mCurrentFolderId);
+ activity.startActivity(intent);
+ }
}
});
diff --git a/src/com/android/browser/mdm/DoNotTrackRestriction.java b/src/com/android/browser/mdm/DoNotTrackRestriction.java
index e69fe16a..94db45f8 100644
--- a/src/com/android/browser/mdm/DoNotTrackRestriction.java
+++ b/src/com/android/browser/mdm/DoNotTrackRestriction.java
@@ -48,7 +48,7 @@ public class DoNotTrackRestriction extends Restriction implements PreferenceKeys
private MdmCheckBoxPreference mPref = null;
private DoNotTrackRestriction() {
- super();
+ super(TAG);
}
public static DoNotTrackRestriction getInstance() {
diff --git a/src/com/android/browser/mdm/IncognitoRestriction.java b/src/com/android/browser/mdm/IncognitoRestriction.java
index 3ea1fe4e..ee2f2e63 100644
--- a/src/com/android/browser/mdm/IncognitoRestriction.java
+++ b/src/com/android/browser/mdm/IncognitoRestriction.java
@@ -48,7 +48,7 @@ public class IncognitoRestriction extends Restriction {
private ArrayList<Drawable> registeredDrawables;
private IncognitoRestriction() {
- super();
+ super(TAG);
registeredViews = new ArrayList<>();
registeredDrawables = new ArrayList<>();
}
diff --git a/src/com/android/browser/mdm/ManagedBookmarksRestriction.java b/src/com/android/browser/mdm/ManagedBookmarksRestriction.java
new file mode 100644
index 00000000..84c21a72
--- /dev/null
+++ b/src/com/android/browser/mdm/ManagedBookmarksRestriction.java
@@ -0,0 +1,441 @@
+/*
+ * Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+package com.android.browser.mdm;
+
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.util.Log;
+
+import com.android.browser.platformsupport.BrowserContract;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import static org.chromium.base.ApplicationStatus.getApplicationContext;
+
+public class ManagedBookmarksRestriction extends Restriction {
+
+ private final static String TAG = "+++MngdBookmarks_Rest";
+
+ public static final String MANAGED_BOOKMARKS = "ManagedBookmarks";
+ private static final String FOLDER_URL_KEY = "MDM";
+ private static ManagedBookmarksRestriction sInstance;
+ private String mJsonBookmarks;
+ public BookmarksDb mDb;
+ private boolean mCreatedMdmBookmarks;
+
+ private ManagedBookmarksRestriction() {
+ super(TAG);
+ }
+
+ public static ManagedBookmarksRestriction getInstance() {
+ synchronized (ManagedBookmarksRestriction.class) {
+ if (sInstance == null) {
+ sInstance = new ManagedBookmarksRestriction();
+ }
+ }
+ return sInstance;
+ }
+
+ @Override
+ protected void doCustomInit() {
+ mDb = new BookmarksDb();
+ mCreatedMdmBookmarks = false;
+ }
+
+ public class BookmarksDb {
+ private ContentResolver mCr = null;
+
+ public class CRException extends Exception {
+ public CRException(String s) {
+ super(s);
+ }
+ }
+ private ContentResolver cr() throws CRException {
+ if (mCr == null) {
+ mCr = getApplicationContext().getContentResolver();
+ }
+ if (mCr == null) {
+ throw new CRException("Null ContentResolver");
+ }
+ return mCr;
+ }
+
+ public Cursor queryById(long id, String[] projections) {
+ String where = BrowserContract.Bookmarks._ID + " = " + id;
+ Cursor c = null;
+ try {
+ c = cr().query(BrowserContract.Bookmarks.CONTENT_URI,
+ projections, // projections... the columns we want. null means all
+ where, // where clause (without the WHERE keyword)
+ null, // selectionArgs
+ null); // sortOrder
+ } catch (android.database.sqlite.SQLiteException e) {
+ Log.e(TAG, "queryById SQL Exception: [" + e.toString() + "]");
+ } catch (CRException e) {
+ Log.e(TAG, "queryById CR Exception: [" + e.toString() + "]");
+ }
+ return c;
+ }
+
+ public void deleteItemById(long id) {
+ String where = BrowserContract.Bookmarks._ID + " = " + id;
+ try {
+ cr().delete(BrowserContract.Bookmarks.CONTENT_URI, where, null);
+ }
+ catch (android.database.sqlite.SQLiteException e) {
+ Log.e(TAG, "deleteItemById Exception: [" + e.toString() + "]");
+ } catch (CRException e) {
+ Log.e(TAG, "deleteItemById CR Exception: [" + e.toString() + "]");
+ }
+ }
+
+ public long getMdmRootFolderId() {
+ long result = -1;
+ String projections[] = new String[] {BrowserContract.Bookmarks._ID};
+ String where = BrowserContract.Bookmarks.TITLE + " = 'Managed' AND " +
+ BrowserContract.Bookmarks.IS_FOLDER + " = 1 AND " +
+ BrowserContract.Bookmarks.URL + " like '" + FOLDER_URL_KEY + "%' AND " +
+ BrowserContract.Bookmarks.PARENT + " = 1";
+ try {
+ Cursor c = cr().query(BrowserContract.Bookmarks.CONTENT_URI,
+ projections, // projections... the columns we want. null means all
+ where, // where clause (without the WHERE keyword)
+ null, // selectionArgs
+ null); // sortOrder
+ if (c.getCount() != 0) {
+ c.moveToFirst();
+ result = c.getLong(0);
+ }
+ c.close();
+ } catch (android.database.sqlite.SQLiteException e) {
+ Log.e(TAG, "getMdmRootFolderId SQL Exception: [" + e.toString() + "]");
+ } catch (CRException e) {
+ Log.e(TAG, "getMdmRootFolderId CR Exception: [" + e.toString() + "]");
+ }
+ return result;
+ }
+
+ public Cursor getChildrenForMdmFolder(long id, String [] projections) {
+ String where = BrowserContract.Bookmarks.PARENT + " = " + id;
+ Cursor c = null;
+ try {
+ c = cr().query(BrowserContract.Bookmarks.CONTENT_URI,
+ projections, // projections... the columns we want. null means all
+ where, // where clause (without the WHERE keyword)
+ null, // selectionArgs
+ null); // sortOrder
+ } catch (android.database.sqlite.SQLiteException e) {
+ Log.e(TAG, "getChildrenForMdmFolder SQL Exception: [" + e.toString() + "]");
+ } catch (CRException e) {
+ Log.e(TAG, "getChildrenForMdmFolder CR Exception: [" + e.toString() + "]");
+ }
+ return c;
+ }
+
+ private void addBookmark(String title, long parent, String url) {
+ ContentValues values = new ContentValues();
+ values.put(BrowserContract.Bookmarks.PARENT, parent);
+ values.put(BrowserContract.Bookmarks.TITLE, title);
+ values.put(BrowserContract.Bookmarks.URL, url);
+
+ try {
+ Uri uri = cr().insert(BrowserContract.Bookmarks.CONTENT_URI, values);
+ if (uri == null) {
+ Log.e(TAG, "Bookmark '" + title + "' creation failed.");
+ }
+ } catch (android.database.sqlite.SQLiteException e) {
+ Log.e(TAG, "addBookmark-SQL Exception during creation: [" + e.toString() + "]");
+ } catch (CRException e) {
+ Log.e(TAG, "addBookmark CR Exception: [" + e.toString() + "]");
+ }
+ }
+
+ private boolean bookmarksAlreadyEnabled(int hash) {
+ boolean ret = false;
+ String incomingHash = String.valueOf(hash);
+ long rootId = getMdmRootFolderId();
+ if (rootId != -1) {
+ Cursor c = queryById(rootId, new String[] {BrowserContract.Bookmarks.URL});
+ if (c.getCount() == 1) {
+ c.moveToFirst();
+ String url = c.getString(0);
+ if (url.contains(incomingHash)) {
+ ret = true;
+ }
+ }
+ c.close();
+ }
+ return ret;
+ }
+
+ private void addFolder(String title, long parent, JSONArray children, int hash) {
+ ContentValues values = new ContentValues();
+ values.put(BrowserContract.Bookmarks.PARENT, parent);
+ values.put(BrowserContract.Bookmarks.TITLE, title);
+ values.put(BrowserContract.Bookmarks.IS_FOLDER, 1);
+
+ // We are using the URL field (normally not used for folders) to
+ // lock down that this folder is managed by Mdm. This is certainly
+ // non-standard, but the alternative would be to modify the database schema,
+ // which would become a maintenance headache later when google updates the schema.
+ if (hash != 0) {
+ // We add the hash of the json string to the root folder. We use this
+ // to check if we already have this bookmark set enabled.
+ values.put(BrowserContract.Bookmarks.URL, FOLDER_URL_KEY + ":" + hash);
+ }
+ else {
+ values.put(BrowserContract.Bookmarks.URL, FOLDER_URL_KEY);
+ }
+
+ try {
+ Uri uri = cr().insert(BrowserContract.Bookmarks.CONTENT_URI, values);
+ if (uri != null) {
+ long nodeId = ContentUris.parseId(uri);
+
+ if (children != null) {
+ for (int i = 0; i < children.length(); i++) {
+ JSONObject j = children.getJSONObject(i);
+
+ // if it has a URL, then it's a bookmark
+ if (j.has("url")) {
+ String t = j.getString("name");
+ String u = j.getString("url");
+ mDb.addBookmark(t, nodeId, u);
+ }
+ // if it has children, then it's a subfolder
+ else if (j.has("children")) {
+ String t = j.getString("name");
+ JSONArray ja = new JSONArray(j.getString("children"));
+ addFolder(t, nodeId, ja, 0);
+ } else {
+ Log.e(TAG, "Parse error processing children for [" + title + "]");
+ }
+ }
+ }
+ } else {
+ Log.e(TAG, "Folder creation failed.");
+ }
+ } catch (android.database.sqlite.SQLiteException e) {
+ Log.e(TAG, "addFolder-SQL Exception during creation: [" + e.toString() + "]");
+ } catch (JSONException e) {
+ Log.e(TAG, "addFolder-JSON exception during creation: [" + e.toString() + "]");
+ } catch (CRException e) {
+ Log.e(TAG, "addFolder CR Exception: [" + e.toString() + "]");
+ }
+ }
+
+ public boolean isMdmElement(long id) {
+ boolean ret = false;
+
+ String[] projections =
+ new String[]{
+ BrowserContract.Bookmarks.IS_FOLDER,
+ BrowserContract.Bookmarks.URL,
+ BrowserContract.Bookmarks.PARENT};
+
+ Cursor c = mDb.queryById(id, projections);
+ if(1 == c.getCount()) {
+ c.moveToFirst();
+ int isFolder = c.getInt(0);
+ String url = c.getString(1);
+ long parent = c.getLong(2);
+
+ if (isFolder != 0) {
+ if (url != null && url.startsWith(FOLDER_URL_KEY)) {
+ ret = true;
+ }
+ }
+ else {
+ Cursor cp = mDb.queryById(parent, projections);
+ if(1 == cp.getCount()) {
+ cp.moveToFirst();
+ String u2 = cp.getString(1);
+ if (u2 != null && u2.startsWith(FOLDER_URL_KEY)) {
+ ret = true;
+ }
+ }
+ else {
+ Log.e(TAG,"isMdmElement: Invalid parent id ["+id+"]");
+ }
+ }
+ }
+ else {
+ Log.e(TAG,"isMdmElement: Invalid id ["+id+"]");
+ }
+ c.close();
+ return ret;
+ }
+
+ private void deleteTree(long folderId) {
+ if (folderId == -1) {
+ Log.i(TAG, " deleteTree: no tree to delete.");
+ return;
+ }
+
+ String[] projections =
+ new String[]{
+ BrowserContract.Bookmarks.IS_FOLDER,
+ BrowserContract.Bookmarks._ID};
+
+ try {
+ Cursor c = getChildrenForMdmFolder(folderId, projections);
+
+ int n = c.getCount();
+ if (n != 0) {
+ c.moveToFirst();
+ for (int i = 0; i < n; i++) {
+ int isFolder = c.getInt(0);
+ int itemId = c.getInt(1);
+
+ if (isFolder == 1) {
+ deleteTree(itemId);
+ }
+ else {
+ mDb.deleteItemById(itemId);
+ }
+ c.moveToNext();
+ }
+ }
+ else {
+ Log.i(TAG,"DeleteTree: no children for id["+folderId+"]");
+ }
+ c.close();
+
+ // now that the contents have been deleted, delete this folder
+ mDb.deleteItemById(folderId);
+ } catch (android.database.sqlite.SQLiteException e) {
+ Log.e(TAG, "deleteTree SQL Exception: [" + e.toString() + "]");
+ }
+ }
+ }
+
+ /* For Debugging
+ public void dumpCursor(Cursor c) {
+ int n = c.getCount();
+ int pos = c.getPosition();
+
+ if (n != 0) {
+ String cols[] = c.getColumnNames();
+ Log.i(TAG, " ********* Dumping " + n + " records *************");
+ c.moveToFirst();
+ for (int i = 0; i < n; i++) {
+ Log.i(TAG," == Record ["+i+"]");
+ for (String col : cols) {
+ int ndx = c.getColumnIndex(col);
+ switch (c.getType(ndx)) {
+ case Cursor.FIELD_TYPE_NULL:
+ Log.i(TAG, " " + col + " = <null>");
+ break;
+ case Cursor.FIELD_TYPE_BLOB:
+ Log.i(TAG, " " + col + " = <blob>");
+ break;
+ case Cursor.FIELD_TYPE_FLOAT:
+ Log.i(TAG, " " + col + " = " +
+ c.getFloat(ndx));
+ break;
+ case Cursor.FIELD_TYPE_INTEGER:
+ Log.i(TAG, " " + col + " = " +
+ c.getInt(ndx));
+ break;
+ case Cursor.FIELD_TYPE_STRING:
+ Log.i(TAG, " " + col + " = " +
+ c.getString(ndx));
+ break;
+ }
+ }
+ c.moveToNext();
+ }
+ Log.i(TAG, " ********* END Dump *************");
+ }
+ c.moveToPosition(pos); // restore incoming position
+ } */
+
+ private void removeManagedBookmarks() {
+ mDb.deleteTree(mDb.getMdmRootFolderId());
+ }
+
+ public boolean bookmarksWereCreated() {
+ return mCreatedMdmBookmarks;
+ }
+
+ private void addManagedBookmarks() {
+ String name = "Managed";
+ int rootFolder = 1;
+ mCreatedMdmBookmarks = false;
+
+ int hash = mJsonBookmarks.hashCode();
+ if (! mDb.bookmarksAlreadyEnabled(hash)) {
+ Log.i(TAG, ">>>>>>> BOOKMARKS NOT ALREADY ENABLED <<<<<<<<<<<<");
+ removeManagedBookmarks();
+ JSONArray dict = null;
+ try {
+ dict = new JSONArray(mJsonBookmarks);
+ } catch (JSONException e) {
+ Log.w(TAG, "addManagedBookmarks: Incoming JSON didn't parse. Creating empty folder." + e.toString());
+ }
+
+ mDb.addFolder(name, rootFolder, dict, hash);
+
+ mCreatedMdmBookmarks = true;
+ }
+ else {
+ Log.w(TAG, ">>>>>>> BOOKMARKS ALREADY ENABLED <<<<<<<<<<<<");
+ mCreatedMdmBookmarks = false;
+ }
+ }
+
+ @Override
+ public void enforce(Bundle restrictions) {
+ mJsonBookmarks = restrictions.getString(MANAGED_BOOKMARKS);
+
+ // Enable if we got something in the json bookmarks string
+ enable(!(mJsonBookmarks == null || mJsonBookmarks.isEmpty()));
+
+ Log.i(TAG, "Enforcing. enabled[" + isEnabled() + "]. val[" + mJsonBookmarks + "]");
+
+ if(isEnabled()){
+ addManagedBookmarks();
+ }
+ else {
+ removeManagedBookmarks();
+ }
+ }
+
+ public String getValue() {
+ return mJsonBookmarks;
+ }
+}
diff --git a/src/com/android/browser/mdm/ProxyRestriction.java b/src/com/android/browser/mdm/ProxyRestriction.java
index ddcf0a2f..1a4b5915 100644
--- a/src/com/android/browser/mdm/ProxyRestriction.java
+++ b/src/com/android/browser/mdm/ProxyRestriction.java
@@ -62,7 +62,7 @@ public class ProxyRestriction extends Restriction implements PreferenceKeys {
private static ProxyRestriction sInstance;
private ProxyRestriction() {
- super();
+ super(TAG);
}
public static ProxyRestriction getInstance() {
diff --git a/src/com/android/browser/mdm/Restriction.java b/src/com/android/browser/mdm/Restriction.java
index ab21c039..a9e4285f 100644
--- a/src/com/android/browser/mdm/Restriction.java
+++ b/src/com/android/browser/mdm/Restriction.java
@@ -31,6 +31,7 @@
package com.android.browser.mdm;
import android.os.Bundle;
+import android.util.Log;
import org.codeaurora.swe.util.Activator;
import org.codeaurora.swe.util.Observable;
@@ -44,8 +45,10 @@ public abstract class Restriction {
private boolean mEnabled = false;
- public Restriction() {
+ public Restriction(String s) {
// Register observer for restrictions
+ Log.i("+++", "["+ s + "] is registering it's observer");
+ doCustomInit();
Activator.activate(new Observable.Observer() {
@Override
public void onChange(Object... params) {
@@ -65,5 +68,7 @@ public abstract class Restriction {
}
abstract public void enforce(Bundle restrictions);
+
+ protected void doCustomInit() {}
}
diff --git a/src/com/android/browser/mdm/SearchEngineRestriction.java b/src/com/android/browser/mdm/SearchEngineRestriction.java
index 23a75a08..3f0eef87 100644
--- a/src/com/android/browser/mdm/SearchEngineRestriction.java
+++ b/src/com/android/browser/mdm/SearchEngineRestriction.java
@@ -53,7 +53,7 @@ public class SearchEngineRestriction extends Restriction implements PreferenceKe
private SearchEngineInfo mSearchEngineInfo;
private SearchEngineRestriction() {
- super();
+ super(TAG);
}
public static SearchEngineRestriction getInstance() {
diff --git a/src/com/android/browser/mdm/ThirdPartyCookiesRestriction.java b/src/com/android/browser/mdm/ThirdPartyCookiesRestriction.java
index 7f55c22f..86e31034 100644
--- a/src/com/android/browser/mdm/ThirdPartyCookiesRestriction.java
+++ b/src/com/android/browser/mdm/ThirdPartyCookiesRestriction.java
@@ -46,7 +46,7 @@ public class ThirdPartyCookiesRestriction extends Restriction {
private boolean mTpcValue;
private ThirdPartyCookiesRestriction() {
- super();
+ super(TAG);
}
public static ThirdPartyCookiesRestriction getInstance() {
diff --git a/src/com/android/browser/mdm/URLFilterRestriction.java b/src/com/android/browser/mdm/URLFilterRestriction.java
index 551f5ea4..3141247a 100644
--- a/src/com/android/browser/mdm/URLFilterRestriction.java
+++ b/src/com/android/browser/mdm/URLFilterRestriction.java
@@ -41,7 +41,7 @@ public class URLFilterRestriction extends Restriction {
private static URLFilterRestriction sInstance;
private URLFilterRestriction() {
- super();
+ super(TAG);
}
public static URLFilterRestriction getInstance() {
diff --git a/src/com/android/browser/mdm/tests/ManagedBookmarksRestrictionsTest.java b/src/com/android/browser/mdm/tests/ManagedBookmarksRestrictionsTest.java
new file mode 100644
index 00000000..37676633
--- /dev/null
+++ b/src/com/android/browser/mdm/tests/ManagedBookmarksRestrictionsTest.java
@@ -0,0 +1,278 @@
+/*
+ * Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+package com.android.browser.mdm.tests;
+
+import android.app.Instrumentation;
+import android.database.Cursor;
+import android.os.Bundle;
+import android.test.ActivityInstrumentationTestCase2;
+import android.util.Log;
+
+import com.android.browser.BrowserActivity;
+import com.android.browser.PreferenceKeys;
+import com.android.browser.mdm.ManagedBookmarksRestriction;
+import com.android.browser.mdm.ManagedProfileManager;
+import com.android.browser.platformsupport.BrowserContract;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.util.ArrayList;
+
+public class ManagedBookmarksRestrictionsTest extends ActivityInstrumentationTestCase2<BrowserActivity>
+ implements PreferenceKeys {
+
+ private final static String TAG = "BkmrksRestTest";
+
+ private Instrumentation mInstrumentation;
+ private BrowserActivity mActivity;
+ private ManagedBookmarksRestriction managedBookmarksRestriction;
+ private ManagedBookmarksRestriction.BookmarksDb mDb;
+
+ private ArrayList<bmTuple> mBookmarks;
+ private String mSubDirName;
+
+ public ManagedBookmarksRestrictionsTest() {
+ super(BrowserActivity.class);
+ }
+
+ private class bmTuple {
+ String name;
+ String url;
+ public bmTuple(String n, String u) {
+ name = n;
+ url = u;
+ }
+ public String getName(){ return name;}
+ public String getUrl() { return url;}
+ }
+
+ void initializeTestData() {
+ mBookmarks = new ArrayList<>();
+ // Level 0
+ mBookmarks.add(new bmTuple("Chromium for Snapdragon", "www.codeaurora.org/forums/chromium-snapdragon"));
+ mBookmarks.add(new bmTuple("Chromium Browser for Snapdragon", "www.codeaurora.org/xwiki/bin/Chromium+for+Snapdragon"));
+ mSubDirName = "Repos And Patches";
+
+ // Level 1
+ mBookmarks.add(new bmTuple("Code Aurora git repositories", "www.codeaurora.org/cgit/quic/chrome4sdp"));
+ mBookmarks.add(new bmTuple("Patches", "www.codeaurora.org/patches/quic/chrome4snapdragon"));
+ }
+
+ private String getBookmarksDict(int indent) {
+ JSONArray dict = new JSONArray();
+
+ JSONObject bm_0_0 = new JSONObject();
+ JSONObject bm_0_1 = new JSONObject();
+
+ JSONObject level_1_Folder = new JSONObject();
+ JSONArray level_1_Children = new JSONArray();
+ JSONObject bm_1_0 = new JSONObject();
+ JSONObject bm_1_1 = new JSONObject();
+ try {
+ bm_0_0.put("name", mBookmarks.get(0).getName());
+ bm_0_0.put("url", mBookmarks.get(0).getUrl());
+
+ bm_0_1.put("name", mBookmarks.get(1).getName());
+ bm_0_1.put("url", mBookmarks.get(1).getUrl());
+
+ bm_1_0.put("name", mBookmarks.get(2).getName());
+ bm_1_0.put("url", mBookmarks.get(2).getUrl());
+
+ bm_1_1.put("name", mBookmarks.get(3).getName());
+ bm_1_1.put("url", mBookmarks.get(3).getUrl());
+
+ level_1_Children.put(bm_1_0);
+ level_1_Children.put(bm_1_1);
+
+ level_1_Folder.put("name", mSubDirName);
+ level_1_Folder.put("children", level_1_Children);
+
+ dict.put(bm_0_0);
+ dict.put(bm_0_1);
+ dict.put(level_1_Folder);
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+
+ String ret = null;
+ try {
+ ret = (indent != 0 ? dict.toString(indent): dict.toString());
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+
+ return ret;
+ }
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mInstrumentation = getInstrumentation();
+ mActivity = getActivity();
+ managedBookmarksRestriction = ManagedBookmarksRestriction.getInstance();
+ mDb = managedBookmarksRestriction.mDb;
+ initializeTestData();
+ }
+
+ public void test_MB() throws Throwable {
+ Log.i(TAG,"!!! ******** Starting Managed Bookmark Tests *************");
+
+ clearMBRestrictions();
+ assertFalse(managedBookmarksRestriction.isEnabled());
+ assertNull(managedBookmarksRestriction.getValue());
+
+ setMBRestrictions(true);
+ assertTrue(managedBookmarksRestriction.isEnabled());
+ assertEquals(getBookmarksDict(0), managedBookmarksRestriction.getValue());
+
+ // Now check the DB for our bookmark records
+ assertTrue(managedBookmarksRestriction.bookmarksWereCreated());
+ long rootId = mDb.getMdmRootFolderId();
+ assertFalse(rootId == -1);
+ assertTrue(mDb.isMdmElement(rootId));
+
+ String[] projections = new String[] {
+ BrowserContract.Bookmarks.URL,
+ BrowserContract.Bookmarks.IS_FOLDER,
+ BrowserContract.Bookmarks.TITLE,
+ BrowserContract.Bookmarks._ID,
+ };
+
+ long chromeLinksId = -1; // we need the folder id for the 2nd level checks
+
+ //
+ // Check Level 0
+ //
+ Cursor c = mDb.getChildrenForMdmFolder(rootId, projections);
+ int n = c.getCount();
+ assertTrue(n == 3);
+
+ for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
+ String url = c.getString(0);
+ int isFolder = c.getInt(1);
+ String title = c.getString(2);
+ long id = c.getLong(3);
+
+ assertTrue(mDb.isMdmElement(id));
+
+ boolean found = false;
+ for (bmTuple t : mBookmarks){
+ if (t.getName().equals(title)) {
+ found = true;
+ assertEquals(t.getUrl(), url);
+ assertEquals(0, isFolder);
+ }
+ }
+
+ if (title.equals(mSubDirName)) {
+ assertEquals("MDM", url);
+ assertEquals(1, isFolder);
+ chromeLinksId = id;
+ found = true;
+ }
+ if (!found) {
+ assertFalse("Unexpected entry ["+title+"] found", true);
+ }
+ }
+ //
+ // Check Level 1
+ //
+ c = mDb.getChildrenForMdmFolder(chromeLinksId, projections);
+ n = c.getCount();
+ assertTrue(n == 2);
+
+ for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
+ String url = c.getString(0);
+ int isFolder = c.getInt(1);
+ String title = c.getString(2);
+ long id = c.getLong(3);
+
+ assertTrue(mDb.isMdmElement(id));
+
+ boolean found = false;
+ for (bmTuple t : mBookmarks){
+ if (t.getName().equals(title)) {
+ found = true;
+ assertEquals(t.getUrl(), url);
+ assertEquals(0, isFolder);
+ }
+ }
+ if (!found) {
+ assertFalse("Unexpected entry ["+title+"] found", true);
+ }
+ }
+
+ //
+ // attempt to add bookmarks again. Should fail silently.
+ // catt bookmarksWereCreated() to see if they were actually created or not
+ //
+ setMBRestrictions(true);
+ assertFalse(managedBookmarksRestriction.bookmarksWereCreated());
+
+ //
+ // Now, clear the restriction and check that there is no root mdm folder in the DB
+ //
+ clearMBRestrictions();
+ assertFalse(managedBookmarksRestriction.isEnabled());
+ assertNull(managedBookmarksRestriction.getValue());
+ rootId = mDb.getMdmRootFolderId();
+ assertTrue(rootId == -1);
+ }
+
+ /**
+ * Activate ManagedBookmarks restriction
+ * @param enable boolean. Set the state of the restriction.
+ */
+ private void setMBRestrictions(boolean enable) {
+ // Construct restriction bundle
+ final Bundle restrictions = new Bundle();
+
+ if(enable) {
+ restrictions.putString(ManagedBookmarksRestriction.MANAGED_BOOKMARKS, getBookmarksDict(0));
+ }
+
+ // Deliver restriction on UI thread
+ mActivity.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ ManagedProfileManager.getInstance().setMdmRestrictions(restrictions);
+ }
+ });
+
+ // Wait to ensure restriction is set
+ mInstrumentation.waitForIdleSync();
+ }
+
+ private void clearMBRestrictions() {
+ setMBRestrictions(false);
+ }
+}
diff --git a/src/com/android/browser/view/BookmarkThumbImageView.java b/src/com/android/browser/view/BookmarkThumbImageView.java
index 50b35447..21c1f4fb 100644
--- a/src/com/android/browser/view/BookmarkThumbImageView.java
+++ b/src/com/android/browser/view/BookmarkThumbImageView.java
@@ -38,6 +38,8 @@ import android.widget.ImageView;
public class BookmarkThumbImageView extends ImageView {
+ private boolean mAdjustDown = true;
+
public BookmarkThumbImageView(Context context) {
this(context, null);
}
@@ -50,29 +52,39 @@ public class BookmarkThumbImageView extends ImageView {
super(context, attrs, defStyleAttr);
}
+ public boolean getAdjustDown() {
+ return mAdjustDown;
+ }
+
+ public void setmAdjustDown(boolean mAdjustDown) {
+ this.mAdjustDown = mAdjustDown;
+ }
+
@Override
public void setImageDrawable(Drawable drawable) {
- int drawableWidth = drawable.getIntrinsicWidth();
- int drawableHeight = drawable.getIntrinsicHeight();
- int containerWidth = getWidth() - getPaddingLeft() - getPaddingRight();
- int containerHeight = getHeight() - getPaddingTop() - getPaddingBottom();
+ if (mAdjustDown) {
+ int drawableWidth = drawable.getIntrinsicWidth();
+ int drawableHeight = drawable.getIntrinsicHeight();
+ int containerWidth = getWidth() - getPaddingLeft() - getPaddingRight();
+ int containerHeight = getHeight() - getPaddingTop() - getPaddingBottom();
- float scale;
- Matrix m = new Matrix();
- if ( (drawableWidth * containerHeight) > (containerWidth * drawableHeight)) {
- scale = (float) containerHeight / (float) drawableHeight;
- } else {
- scale = (float) containerWidth / (float) drawableWidth;
- float translateY = (containerHeight - drawableHeight * scale) / 2;
- if (translateY < 0) {
- translateY = 0;
+ float scale;
+ Matrix m = new Matrix();
+ if ( (drawableWidth * containerHeight) > (containerWidth * drawableHeight)) {
+ scale = (float) containerHeight / (float) drawableHeight;
+ } else {
+ scale = (float) containerWidth / (float) drawableWidth;
+ float translateY = (containerHeight - drawableHeight * scale) / 2;
+ if (translateY < 0) {
+ translateY = 0;
+ }
+ m.postTranslate(0, translateY + 0.5f);
}
- m.postTranslate(0, translateY + 0.5f);
- }
- m.setScale(scale, scale);
+ m.setScale(scale, scale);
- this.setScaleType(ScaleType.MATRIX);
- this.setImageMatrix(m);
+ this.setScaleType(ScaleType.MATRIX);
+ this.setImageMatrix(m);
+ }
super.setImageDrawable(drawable);
}
}