BP2TestCaseHelper.java revision 57e39f9e46091750c8a07895531446a7f0efdb21
1/* 2 * Copyright (C) 2011 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 17package com.android.browser.tests.utils; 18 19import com.android.browser.provider.BrowserProvider2; 20 21import android.content.ContentValues; 22import android.database.ContentObserver; 23import android.net.Uri; 24import android.provider.Browser; 25import android.provider.BrowserContract; 26import android.provider.BrowserContract.Bookmarks; 27import android.provider.BrowserContract.History; 28import android.util.Log; 29 30/** 31 * This is a replacement for ProviderTestCase2 that can handle notifyChange testing. 32 * It also has helper methods specifically for testing BrowserProvider2 33 */ 34public abstract class BP2TestCaseHelper extends ProviderTestCase3<BrowserProvider2> { 35 36 // Tag for potential performance impacts 37 private static final String PERFTAG = "BP2-PerfCheck"; 38 39 private TriggeredObserver mLegacyObserver; 40 private TriggeredObserver mRootObserver; 41 private TriggeredObserver mBookmarksObserver; 42 private TriggeredObserver mHistoryObserver; 43 private TriggeredObserver mWidgetObserver; 44 45 @Override 46 protected void setUp() throws Exception { 47 super.setUp(); 48 mLegacyObserver = new TriggeredObserver(Browser.BOOKMARKS_URI); 49 mRootObserver = new TriggeredObserver(BrowserContract.AUTHORITY_URI); 50 mBookmarksObserver = new TriggeredObserver(Bookmarks.CONTENT_URI); 51 mHistoryObserver = new TriggeredObserver(History.CONTENT_URI); 52 mWidgetObserver = new TriggeredObserver(); 53 // We don't need to worry about setting this back to null since this 54 // is a private instance local to the MockContentResolver 55 getProvider().setWidgetObserver(mWidgetObserver); 56 } 57 58 public BP2TestCaseHelper() { 59 super(BrowserProvider2.class, 60 BrowserContract.AUTHORITY, BrowserProvider2.LEGACY_AUTHORITY); 61 } 62 63 public void perfIdeallyUntriggered(TriggeredObserver... obs) { 64 for (TriggeredObserver ob : obs) { 65 if (ob.checkTriggered()) { 66 // Not ideal, unnecessary notification 67 Log.i(PERFTAG, ob.mUri + " onChange called but content unaltered!"); 68 } 69 } 70 } 71 72 public void assertObserversTriggered(boolean triggered, 73 TriggeredObserver... observers) { 74 for (TriggeredObserver obs : observers) { 75 assertEquals(obs.mUri + ", descendents:" + obs.mNotifyForDescendents, 76 triggered, obs.checkTriggered()); 77 } 78 } 79 80 public class TriggeredObserver extends ContentObserver { 81 private boolean mTriggered; 82 Uri mUri; 83 boolean mNotifyForDescendents; 84 85 /** 86 * Creates an unmanaged TriggeredObserver 87 */ 88 public TriggeredObserver() { 89 super(null); 90 } 91 92 /** 93 * Same as TriggeredObserver(uri, true); 94 */ 95 public TriggeredObserver(Uri uri) { 96 this(uri, true); 97 } 98 99 /** 100 * Creates a managed TriggeredObserver that self-registers with the 101 * mock ContentResolver 102 */ 103 public TriggeredObserver(Uri uri, boolean notifyForDescendents) { 104 super(null); 105 mUri = uri; 106 mNotifyForDescendents = notifyForDescendents; 107 registerContentObserver(uri, notifyForDescendents, this); 108 } 109 110 @Override 111 public void onChange(boolean selfChange) { 112 super.onChange(selfChange); 113 mTriggered = true; 114 } 115 116 public boolean checkTriggered() { 117 boolean ret = mTriggered; 118 mTriggered = false; 119 return ret; 120 } 121 } 122 123 Uri mockInsert(Uri uri, ContentValues values) { 124 assertObserversTriggered(false, mLegacyObserver, mRootObserver); 125 Uri ret = getMockContentResolver().insert(uri, values); 126 assertObserversTriggered(true, mLegacyObserver, mRootObserver); 127 return ret; 128 } 129 130 int mockUpdate(Uri uri, ContentValues values, String where, 131 String[] selectionArgs) { 132 assertObserversTriggered(false, mLegacyObserver, mRootObserver); 133 int ret = getMockContentResolver().update(uri, values, where, selectionArgs); 134 if (ret > 0) { 135 assertObserversTriggered(true, mLegacyObserver, mRootObserver); 136 } else { 137 perfIdeallyUntriggered(mLegacyObserver); 138 perfIdeallyUntriggered(mRootObserver); 139 } 140 return ret; 141 } 142 143 public Uri insertBookmark(String url, String title) { 144 ContentValues values = new ContentValues(); 145 values.put(BrowserContract.Bookmarks.TITLE, title); 146 values.put(BrowserContract.Bookmarks.URL, url); 147 values.put(BrowserContract.Bookmarks.IS_FOLDER, 0); 148 return insertBookmark(values); 149 } 150 151 public Uri insertBookmark(ContentValues values) { 152 assertObserversTriggered(false, mBookmarksObserver, mWidgetObserver); 153 Uri ret = mockInsert(Bookmarks.CONTENT_URI, values); 154 assertObserversTriggered(true, mBookmarksObserver, mWidgetObserver); 155 perfIdeallyUntriggered(mHistoryObserver); 156 return ret; 157 } 158 159 public boolean updateBookmark(Uri uri, String url, String title) { 160 ContentValues values = new ContentValues(); 161 values.put(BrowserContract.Bookmarks.TITLE, title); 162 values.put(BrowserContract.Bookmarks.URL, url); 163 return updateBookmark(uri, values); 164 } 165 166 public boolean updateBookmark(Uri uri, ContentValues values) { 167 assertObserversTriggered(false, mBookmarksObserver, mWidgetObserver); 168 int modifyCount = mockUpdate(uri, values, null, null); 169 assertTrue("UpdatedBookmark modified too much! " + uri, modifyCount <= 1); 170 boolean updated = modifyCount == 1; 171 if (updated) { 172 assertObserversTriggered(updated, mBookmarksObserver, mWidgetObserver); 173 } else { 174 perfIdeallyUntriggered(mBookmarksObserver, mWidgetObserver); 175 } 176 perfIdeallyUntriggered(mHistoryObserver); 177 return updated; 178 } 179 180 public Uri insertHistory(String url, String title) { 181 ContentValues values = new ContentValues(); 182 values.put(BrowserContract.History.TITLE, title); 183 values.put(BrowserContract.History.URL, url); 184 assertObserversTriggered(false, mHistoryObserver); 185 Uri ret = mockInsert(History.CONTENT_URI, values); 186 assertObserversTriggered(true, mHistoryObserver); 187 perfIdeallyUntriggered(mBookmarksObserver, mWidgetObserver); 188 return ret; 189 } 190 191 public boolean updateHistory(Uri uri, String url, String title) { 192 ContentValues values = new ContentValues(); 193 values.put(BrowserContract.History.TITLE, title); 194 values.put(BrowserContract.History.URL, url); 195 return updateHistory(uri, values); 196 } 197 198 public boolean updateHistory(Uri uri, ContentValues values) { 199 assertObserversTriggered(false, mHistoryObserver); 200 int modifyCount = mockUpdate(uri, values, null, null); 201 assertTrue("UpdatedHistory modified too much! " + uri, modifyCount <= 1); 202 boolean updated = modifyCount == 1; 203 if (updated) { 204 assertObserversTriggered(updated, mHistoryObserver); 205 } else { 206 perfIdeallyUntriggered(mHistoryObserver); 207 } 208 perfIdeallyUntriggered(mBookmarksObserver, mWidgetObserver); 209 return updated; 210 } 211} 212