diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-03-18 22:20:26 -0700 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-18 22:20:26 -0700 |
commit | 7b0b1ed979aa665175bf3952c8902ce13c763ab8 (patch) | |
tree | 8e2e55aab35489506403dfe0f701317bc20d599e /core/java | |
parent | 105925376f8d0f6b318c9938c7b83ef7fef094da (diff) | |
download | frameworks_base-7b0b1ed979aa665175bf3952c8902ce13c763ab8.zip frameworks_base-7b0b1ed979aa665175bf3952c8902ce13c763ab8.tar.gz frameworks_base-7b0b1ed979aa665175bf3952c8902ce13c763ab8.tar.bz2 |
auto import //branches/master/...@140412
Diffstat (limited to 'core/java')
-rw-r--r-- | core/java/android/ddm/DdmHandleHeap.java | 44 | ||||
-rw-r--r-- | core/java/android/ddm/DdmHandleHello.java | 51 | ||||
-rw-r--r-- | core/java/android/ddm/DdmHandleProfiling.java | 137 | ||||
-rw-r--r-- | core/java/android/ddm/DdmRegister.java | 1 | ||||
-rw-r--r-- | core/java/android/os/Debug.java | 8 | ||||
-rw-r--r-- | core/java/android/os/RemoteCallbackList.java | 64 | ||||
-rw-r--r-- | core/java/android/webkit/HttpDateTime.java | 39 | ||||
-rw-r--r-- | core/java/android/widget/AutoCompleteTextView.java | 79 |
8 files changed, 374 insertions, 49 deletions
diff --git a/core/java/android/ddm/DdmHandleHeap.java b/core/java/android/ddm/DdmHandleHeap.java index 54457c2..95fa0a2 100644 --- a/core/java/android/ddm/DdmHandleHeap.java +++ b/core/java/android/ddm/DdmHandleHeap.java @@ -20,17 +20,20 @@ import org.apache.harmony.dalvik.ddmc.Chunk; import org.apache.harmony.dalvik.ddmc.ChunkHandler; import org.apache.harmony.dalvik.ddmc.DdmServer; import org.apache.harmony.dalvik.ddmc.DdmVmInternal; +import android.os.Debug; import android.util.Config; import android.util.Log; +import java.io.IOException; import java.nio.ByteBuffer; /** - * Handle thread-related traffic. + * Handle native and virtual heap requests. */ public class DdmHandleHeap extends ChunkHandler { public static final int CHUNK_HPIF = type("HPIF"); public static final int CHUNK_HPSG = type("HPSG"); + public static final int CHUNK_HPDU = type("HPDU"); public static final int CHUNK_NHSG = type("NHSG"); public static final int CHUNK_HPGC = type("HPGC"); public static final int CHUNK_REAE = type("REAE"); @@ -49,6 +52,7 @@ public class DdmHandleHeap extends ChunkHandler { public static void register() { DdmServer.registerHandler(CHUNK_HPIF, mInstance); DdmServer.registerHandler(CHUNK_HPSG, mInstance); + DdmServer.registerHandler(CHUNK_HPDU, mInstance); DdmServer.registerHandler(CHUNK_NHSG, mInstance); DdmServer.registerHandler(CHUNK_HPGC, mInstance); DdmServer.registerHandler(CHUNK_REAE, mInstance); @@ -80,6 +84,8 @@ public class DdmHandleHeap extends ChunkHandler { return handleHPIF(request); } else if (type == CHUNK_HPSG) { return handleHPSGNHSG(request, false); + } else if (type == CHUNK_HPDU) { + return handleHPDU(request); } else if (type == CHUNK_NHSG) { return handleHPSGNHSG(request, true); } else if (type == CHUNK_HPGC) { @@ -97,7 +103,7 @@ public class DdmHandleHeap extends ChunkHandler { } /* - * Handle a "HeaP InFo request". + * Handle a "HeaP InFo" request. */ private Chunk handleHPIF(Chunk request) { ByteBuffer in = wrapChunk(request); @@ -137,6 +143,40 @@ public class DdmHandleHeap extends ChunkHandler { } /* + * Handle a "HeaP DUmp" request. + * + * This currently just returns a result code. We could pull up + * the entire contents of the file and return them, but hprof dump + * files can be a few megabytes. + */ + private Chunk handleHPDU(Chunk request) { + ByteBuffer in = wrapChunk(request); + byte result; + + /* get the filename for the output file */ + int len = in.getInt(); + String fileName = getString(in, len); + if (Config.LOGD) + Log.d("ddm-heap", "Heap dump: file='" + fileName + "'"); + + try { + Debug.dumpHprofData(fileName); + result = 0; + } catch (UnsupportedOperationException uoe) { + Log.w("ddm-heap", "hprof dumps not supported in this VM"); + result = -1; + } catch (IOException ioe) { + result = -1; + } catch (RuntimeException ioe) { + result = -1; + } + + /* create a non-empty reply so the handler fires on completion */ + byte[] reply = { result }; + return new Chunk(CHUNK_HPDU, reply, 0, reply.length); + } + + /* * Handle a "HeaP Garbage Collection" request. */ private Chunk handleHPGC(Chunk request) { diff --git a/core/java/android/ddm/DdmHandleHello.java b/core/java/android/ddm/DdmHandleHello.java index e4d630e..c5d591f 100644 --- a/core/java/android/ddm/DdmHandleHello.java +++ b/core/java/android/ddm/DdmHandleHello.java @@ -26,12 +26,13 @@ import android.os.Debug; import java.nio.ByteBuffer; /** - * Handle a HELO chunk. + * Handle "hello" messages and feature discovery. */ public class DdmHandleHello extends ChunkHandler { public static final int CHUNK_HELO = type("HELO"); public static final int CHUNK_WAIT = type("WAIT"); + public static final int CHUNK_FEAT = type("FEAT"); private static DdmHandleHello mInstance = new DdmHandleHello(); @@ -44,6 +45,7 @@ public class DdmHandleHello extends ChunkHandler { */ public static void register() { DdmServer.registerHandler(CHUNK_HELO, mInstance); + DdmServer.registerHandler(CHUNK_FEAT, mInstance); } /** @@ -73,12 +75,27 @@ public class DdmHandleHello extends ChunkHandler { } /** - * Handle a chunk of data. We're only registered for "HELO". + * Handle a chunk of data. */ public Chunk handleChunk(Chunk request) { if (Config.LOGV) - Log.v("ddm-hello", "Handling " + name(request.type) + " chunk"); + Log.v("ddm-heap", "Handling " + name(request.type) + " chunk"); + int type = request.type; + + if (type == CHUNK_HELO) { + return handleHELO(request); + } else if (type == CHUNK_FEAT) { + return handleFEAT(request); + } else { + throw new RuntimeException("Unknown packet " + + ChunkHandler.name(type)); + } + } + /* + * Handle introductory packet. + */ + private Chunk handleHELO(Chunk request) { if (false) return createFailChunk(123, "This is a test"); @@ -125,6 +142,34 @@ public class DdmHandleHello extends ChunkHandler { return reply; } + /* + * Handle request for list of supported features. + */ + private Chunk handleFEAT(Chunk request) { + // TODO: query the VM to ensure that support for these features + // is actually compiled in + final String[] features = { + "hprof-heap-dump", "method-trace-profiling" + }; + + if (Config.LOGD) + Log.d("ddm-heap", "Got feature list request"); + + int size = 4 + 4 * features.length; + for (int i = features.length-1; i >= 0; i--) + size += features[i].length() * 2; + + ByteBuffer out = ByteBuffer.allocate(size); + out.order(ChunkHandler.CHUNK_ORDER); + out.putInt(features.length); + for (int i = features.length-1; i >= 0; i--) { + out.putInt(features[i].length()); + putString(out, features[i]); + } + + return new Chunk(CHUNK_FEAT, out); + } + /** * Send up a WAIT chunk. The only currently defined value for "reason" * is zero, which means "waiting for a debugger". diff --git a/core/java/android/ddm/DdmHandleProfiling.java b/core/java/android/ddm/DdmHandleProfiling.java new file mode 100644 index 0000000..beed505 --- /dev/null +++ b/core/java/android/ddm/DdmHandleProfiling.java @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2009 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 android.ddm; + +import org.apache.harmony.dalvik.ddmc.Chunk; +import org.apache.harmony.dalvik.ddmc.ChunkHandler; +import org.apache.harmony.dalvik.ddmc.DdmServer; +import android.os.Debug; +import android.util.Config; +import android.util.Log; +import java.io.IOException; +import java.nio.ByteBuffer; + +/** + * Handle profiling requests. + */ +public class DdmHandleProfiling extends ChunkHandler { + + public static final int CHUNK_MPRS = type("MPRS"); + public static final int CHUNK_MPRE = type("MPRE"); + public static final int CHUNK_MPRQ = type("MPRQ"); + + private static DdmHandleProfiling mInstance = new DdmHandleProfiling(); + + + /* singleton, do not instantiate */ + private DdmHandleProfiling() {} + + /** + * Register for the messages we're interested in. + */ + public static void register() { + DdmServer.registerHandler(CHUNK_MPRS, mInstance); + DdmServer.registerHandler(CHUNK_MPRE, mInstance); + DdmServer.registerHandler(CHUNK_MPRQ, mInstance); + } + + /** + * Called when the DDM server connects. The handler is allowed to + * send messages to the server. + */ + public void connected() {} + + /** + * Called when the DDM server disconnects. Can be used to disable + * periodic transmissions or clean up saved state. + */ + public void disconnected() {} + + /** + * Handle a chunk of data. + */ + public Chunk handleChunk(Chunk request) { + if (Config.LOGV) + Log.v("ddm-heap", "Handling " + name(request.type) + " chunk"); + int type = request.type; + + if (type == CHUNK_MPRS) { + return handleMPRS(request); + } else if (type == CHUNK_MPRE) { + return handleMPRE(request); + } else if (type == CHUNK_MPRQ) { + return handleMPRQ(request); + } else { + throw new RuntimeException("Unknown packet " + + ChunkHandler.name(type)); + } + } + + /* + * Handle a "Method PRofiling Start" request. + */ + private Chunk handleMPRS(Chunk request) { + ByteBuffer in = wrapChunk(request); + + int bufferSize = in.getInt(); + int flags = in.getInt(); + int len = in.getInt(); + String fileName = getString(in, len); + if (Config.LOGV) + Log.v("ddm-heap", "Method profiling start: filename='" + fileName + + "', size=" + bufferSize + ", flags=" + flags); + + try { + Debug.startMethodTracing(fileName, bufferSize, flags); + return null; // empty response + } catch (RuntimeException re) { + return createFailChunk(1, re.getMessage()); + } + } + + /* + * Handle a "Method PRofiling End" request. + */ + private Chunk handleMPRE(Chunk request) { + byte result; + + try { + Debug.stopMethodTracing(); + result = 0; + } catch (RuntimeException re) { + Log.w("ddm-heap", "Method profiling end failed: " + + re.getMessage()); + result = 1; + } + + /* create a non-empty reply so the handler fires on completion */ + byte[] reply = { result }; + return new Chunk(CHUNK_MPRE, reply, 0, reply.length); + } + + /* + * Handle a "Method PRofiling Query" request. + */ + private Chunk handleMPRQ(Chunk request) { + int result = Debug.isMethodTracingActive() ? 1 : 0; + + /* create a non-empty reply so the handler fires on completion */ + byte[] reply = { (byte) result }; + return new Chunk(CHUNK_MPRQ, reply, 0, reply.length); + } +} + diff --git a/core/java/android/ddm/DdmRegister.java b/core/java/android/ddm/DdmRegister.java index b7f1ab8..debf189 100644 --- a/core/java/android/ddm/DdmRegister.java +++ b/core/java/android/ddm/DdmRegister.java @@ -50,6 +50,7 @@ public class DdmRegister { DdmHandleThread.register(); DdmHandleHeap.register(); DdmHandleNativeHeap.register(); + DdmHandleProfiling.register(); DdmHandleExit.register(); DdmServer.registrationComplete(); diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java index 950bb09..5ea5aae 100644 --- a/core/java/android/os/Debug.java +++ b/core/java/android/os/Debug.java @@ -364,6 +364,14 @@ href="{@docRoot}guide/developing/tools/traceview.html">Traceview: A Graphical Lo } /** + * Determine whether method tracing is currently active. + * @hide + */ + public static boolean isMethodTracingActive() { + return VMDebug.isMethodTracingActive(); + } + + /** * Stop method tracing. */ public static void stopMethodTracing() { diff --git a/core/java/android/os/RemoteCallbackList.java b/core/java/android/os/RemoteCallbackList.java index 63f6dff..50a9a83 100644 --- a/core/java/android/os/RemoteCallbackList.java +++ b/core/java/android/os/RemoteCallbackList.java @@ -22,7 +22,7 @@ import java.util.HashMap; * Takes care of the grunt work of maintaining a list of remote interfaces, * typically for the use of performing callbacks from a * {@link android.app.Service} to its clients. In particular, this: - * + * * <ul> * <li> Keeps track of a set of registered {@link IInterface} callbacks, * taking care to identify them through their underlying unique {@link IBinder} @@ -34,13 +34,13 @@ import java.util.HashMap; * multithreaded incoming calls, and a thread-safe way to iterate over a * snapshot of the list without holding its lock. * </ul> - * + * * <p>To use this class, simply create a single instance along with your * service, and call its {@link #register} and {@link #unregister} methods * as client register and unregister with your service. To call back on to * the registered clients, use {@link #beginBroadcast}, * {@link #getBroadcastItem}, and {@link #finishBroadcast}. - * + * * <p>If a registered callback's process goes away, this class will take * care of automatically removing it from the list. If you want to do * additional work in this situation, you can create a subclass that @@ -51,14 +51,14 @@ public class RemoteCallbackList<E extends IInterface> { = new HashMap<IBinder, Callback>(); private IInterface[] mActiveBroadcast; private boolean mKilled = false; - + private final class Callback implements IBinder.DeathRecipient { final E mCallback; - + Callback(E callback) { mCallback = callback; } - + public void binderDied() { synchronized (mCallbacks) { mCallbacks.remove(mCallback.asBinder()); @@ -66,7 +66,7 @@ public class RemoteCallbackList<E extends IInterface> { onCallbackDied(mCallback); } } - + /** * Add a new callback to the list. This callback will remain in the list * until a corresponding call to {@link #unregister} or its hosting process @@ -75,17 +75,17 @@ public class RemoteCallbackList<E extends IInterface> { * object is already in the list), then it will be left as-is. * Registrations are not counted; a single call to {@link #unregister} * will remove a callback after any number calls to register it. - * + * * @param callback The callback interface to be added to the list. Must * not be null -- passing null here will cause a NullPointerException. * Most services will want to check for null before calling this with * an object given from a client, so that clients can't crash the * service with bad data. - * + * * @return Returns true if the callback was successfully added to the list. * Returns false if it was not added, either because {@link #kill} had * previously been called or the callback's process has gone away. - * + * * @see #unregister * @see #kill * @see #onCallbackDied @@ -106,7 +106,7 @@ public class RemoteCallbackList<E extends IInterface> { } } } - + /** * Remove from the list a callback that was previously added with * {@link #register}. This uses the @@ -114,14 +114,14 @@ public class RemoteCallbackList<E extends IInterface> { * find the previous registration. * Registrations are not counted; a single unregister call will remove * a callback after any number calls to {@link #register} for it. - * + * * @param callback The callback to be removed from the list. Passing * null here will cause a NullPointerException, so you will generally want * to check for null before calling. - * + * * @return Returns true if the callback was found and unregistered. Returns * false if the given callback was not found on the list. - * + * * @see #register */ public boolean unregister(E callback) { @@ -134,13 +134,13 @@ public class RemoteCallbackList<E extends IInterface> { return false; } } - + /** * Disable this callback list. All registered callbacks are unregistered, * and the list is disabled so that future calls to {@link #register} will * fail. This should be used when a Service is stopping, to prevent clients * from registering callbacks after it is stopped. - * + * * @see #register */ public void kill() { @@ -152,21 +152,21 @@ public class RemoteCallbackList<E extends IInterface> { mKilled = true; } } - + /** * Called when the process hosting a callback in the list has gone away. * The default implementation does nothing. - * + * * @param callback The callback whose process has died. Note that, since * its process has died, you can not make any calls on to this interface. * You can, however, retrieve its IBinder and compare it with another * IBinder to see if it is the same object. - * + * * @see #register */ public void onCallbackDied(E callback) { } - + /** * Prepare to start making calls to the currently registered callbacks. * This creates a copy of the callback list, which you can retrieve items @@ -175,12 +175,12 @@ public class RemoteCallbackList<E extends IInterface> { * same thread (usually by scheduling with {@link Handler} or * do your own synchronization. You must call {@link #finishBroadcast} * when done. - * + * * <p>A typical loop delivering a broadcast looks like this: - * + * * <pre> * final int N = callbacks.beginBroadcast(); - * for (int i=0; i<N; i++) { + * for (int i=0; i<N; i++) { * try { * callbacks.getBroadcastItem(i).somethingHappened(); * } catch (RemoteException e) { @@ -189,11 +189,11 @@ public class RemoteCallbackList<E extends IInterface> { * } * } * callbacks.finishBroadcast();</pre> - * + * * @return Returns the number of callbacks in the broadcast, to be used * with {@link #getBroadcastItem} to determine the range of indices you * can supply. - * + * * @see #getBroadcastItem * @see #finishBroadcast */ @@ -214,37 +214,37 @@ public class RemoteCallbackList<E extends IInterface> { return i; } } - + /** * Retrieve an item in the active broadcast that was previously started * with {@link #beginBroadcast}. This can <em>only</em> be called after * the broadcast is started, and its data is no longer valid after * calling {@link #finishBroadcast}. - * + * * <p>Note that it is possible for the process of one of the returned * callbacks to go away before you call it, so you will need to catch * {@link RemoteException} when calling on to the returned object. * The callback list itself, however, will take care of unregistering * these objects once it detects that it is no longer valid, so you can * handle such an exception by simply ignoring it. - * + * * @param index Which of the registered callbacks you would like to * retrieve. Ranges from 0 to 1-{@link #beginBroadcast}. - * + * * @return Returns the callback interface that you can call. This will * always be non-null. - * + * * @see #beginBroadcast */ public E getBroadcastItem(int index) { return (E)mActiveBroadcast[index]; } - + /** * Clean up the state of a broadcast previously initiated by calling * {@link #beginBroadcast}. This must always be called when you are done * with a broadcast. - * + * * @see #beginBroadcast */ public void finishBroadcast() { diff --git a/core/java/android/webkit/HttpDateTime.java b/core/java/android/webkit/HttpDateTime.java index c6ec2d2..48b2081 100644 --- a/core/java/android/webkit/HttpDateTime.java +++ b/core/java/android/webkit/HttpDateTime.java @@ -47,14 +47,16 @@ class HttpDateTime { * Wdy, DD Mon YYYY HH:MM:SS * Wdy Mon (SP)D HH:MM:SS YYYY * Wdy Mon DD HH:MM:SS YYYY GMT + * + * HH can be H if the first digit is zero. */ private static final String HTTP_DATE_RFC_REGEXP = "([0-9]{1,2})[- ]([A-Za-z]{3,3})[- ]([0-9]{2,4})[ ]" - + "([0-9][0-9]:[0-9][0-9]:[0-9][0-9])"; + + "([0-9]{1,2}:[0-9][0-9]:[0-9][0-9])"; private static final String HTTP_DATE_ANSIC_REGEXP = "[ ]([A-Za-z]{3,3})[ ]+([0-9]{1,2})[ ]" - + "([0-9][0-9]:[0-9][0-9]:[0-9][0-9])[ ]([0-9]{2,4})"; + + "([0-9]{1,2}:[0-9][0-9]:[0-9][0-9])[ ]([0-9]{2,4})"; /** * The compiled version of the HTTP-date regular expressions. @@ -65,6 +67,12 @@ class HttpDateTime { Pattern.compile(HTTP_DATE_ANSIC_REGEXP); private static class TimeOfDay { + TimeOfDay(int h, int m, int s) { + this.hour = h; + this.minute = m; + this.second = s; + } + int hour; int minute; int second; @@ -76,7 +84,7 @@ class HttpDateTime { int date = 1; int month = Calendar.JANUARY; int year = 1970; - TimeOfDay timeOfDay = new TimeOfDay(); + TimeOfDay timeOfDay; Matcher rfcMatcher = HTTP_DATE_RFC_PATTERN.matcher(timeString); if (rfcMatcher.find()) { @@ -183,13 +191,22 @@ class HttpDateTime { } private static TimeOfDay getTime(String timeString) { - TimeOfDay time = new TimeOfDay(); - time.hour = (timeString.charAt(0) - '0') * 10 - + (timeString.charAt(1) - '0'); - time.minute = (timeString.charAt(3) - '0') * 10 - + (timeString.charAt(4) - '0'); - time.second = (timeString.charAt(6) - '0') * 10 - + (timeString.charAt(7) - '0'); - return time; + // HH might be H + int i = 0; + int hour = timeString.charAt(i++) - '0'; + if (timeString.charAt(i) != ':') + hour = hour * 10 + (timeString.charAt(i++) - '0'); + // Skip ':' + i++; + + int minute = (timeString.charAt(i++) - '0') * 10 + + (timeString.charAt(i++) - '0'); + // Skip ':' + i++; + + int second = (timeString.charAt(i++) - '0') * 10 + + (timeString.charAt(i++) - '0'); + + return new TimeOfDay(hour, minute, second); } } diff --git a/core/java/android/widget/AutoCompleteTextView.java b/core/java/android/widget/AutoCompleteTextView.java index e613541..a17c78d 100644 --- a/core/java/android/widget/AutoCompleteTextView.java +++ b/core/java/android/widget/AutoCompleteTextView.java @@ -211,6 +211,8 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe * {@link ViewGroup.LayoutParams#WRAP_CONTENT} to fit the width of its anchor view.</p> * * @return the width for the drop down list + * + * @attr ref android.R.styleable#AutoCompleteTextView_dropDownWidth */ public int getDropDownWidth() { return mDropDownWidth; @@ -222,6 +224,8 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe * {@link ViewGroup.LayoutParams#WRAP_CONTENT} to fit the width of its anchor view.</p> * * @param width the width to use + * + * @attr ref android.R.styleable#AutoCompleteTextView_dropDownWidth */ public void setDropDownWidth(int width) { mDropDownWidth = width; @@ -231,6 +235,8 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe * <p>Returns the id for the view that the auto-complete drop down list is anchored to.</p> * * @return the view's id, or {@link View#NO_ID} if none specified + * + * @attr ref android.R.styleable#AutoCompleteTextView_dropDownAnchor */ public int getDropDownAnchor() { return mDropDownAnchorId; @@ -242,12 +248,83 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe * loading a view which is not yet instantiated.</p> * * @param id the id to anchor the drop down list view to + * + * @attr ref android.R.styleable#AutoCompleteTextView_dropDownAnchor */ public void setDropDownAnchor(int id) { mDropDownAnchorId = id; mDropDownAnchorView = null; } - + + /** + * <p>Gets the background of the auto-complete drop-down list.</p> + * + * @return the background drawable + * + * @attr ref android.R.styleable#PopupWindow_popupBackground + */ + public Drawable getDropDownBackground() { + return mPopup.getBackground(); + } + + /** + * <p>Sets the background of the auto-complete drop-down list.</p> + * + * @param d the drawable to set as the background + * + * @attr ref android.R.styleable#PopupWindow_popupBackground + */ + public void setDropDownBackgroundDrawable(Drawable d) { + mPopup.setBackgroundDrawable(d); + } + + /** + * <p>Sets the background of the auto-complete drop-down list.</p> + * + * @param id the id of the drawable to set as the background + * + * @attr ref android.R.styleable#PopupWindow_popupBackground + */ + public void setDropDownBackgroundResource(int id) { + mPopup.setBackgroundDrawable(getResources().getDrawable(id)); + } + + /** + * <p>Sets the vertical offset used for the auto-complete drop-down list.</p> + * + * @param offset the vertical offset + */ + public void setDropDownVerticalOffset(int offset) { + mDropDownVerticalOffset = offset; + } + + /** + * <p>Gets the vertical offset used for the auto-complete drop-down list.</p> + * + * @return the vertical offset + */ + public int getDropDownVerticalOffset() { + return mDropDownVerticalOffset; + } + + /** + * <p>Sets the horizontal offset used for the auto-complete drop-down list.</p> + * + * @param offset the horizontal offset + */ + public void setDropDownHorizontalOffset(int offset) { + mDropDownHorizontalOffset = offset; + } + + /** + * <p>Gets the horizontal offset used for the auto-complete drop-down list.</p> + * + * @return the horizontal offset + */ + public int getDropDownHorizontalOffset() { + return mDropDownHorizontalOffset; + } + /** * <p>Returns the number of characters the user must type before the drop * down list is shown.</p> |