diff options
78 files changed, 7297 insertions, 1780 deletions
diff --git a/api/current.txt b/api/current.txt index f2b35a8f6881..46e3aa05c96c 100644 --- a/api/current.txt +++ b/api/current.txt @@ -5713,7 +5713,7 @@ package android.content { field public static final java.lang.String ACTION_USER_PRESENT = "android.intent.action.USER_PRESENT"; field public static final java.lang.String ACTION_VIEW = "android.intent.action.VIEW"; field public static final java.lang.String ACTION_VOICE_COMMAND = "android.intent.action.VOICE_COMMAND"; - field public static final java.lang.String ACTION_WALLPAPER_CHANGED = "android.intent.action.WALLPAPER_CHANGED"; + field public static final deprecated java.lang.String ACTION_WALLPAPER_CHANGED = "android.intent.action.WALLPAPER_CHANGED"; field public static final java.lang.String ACTION_WEB_SEARCH = "android.intent.action.WEB_SEARCH"; field public static final java.lang.String CATEGORY_ALTERNATIVE = "android.intent.category.ALTERNATIVE"; field public static final java.lang.String CATEGORY_APP_BROWSER = "android.intent.category.APP_BROWSER"; @@ -11076,15 +11076,20 @@ package android.media { method public boolean hasCacheReachedEndOfStream(); method public int readSampleData(java.nio.ByteBuffer, int); method public final void release(); - method public void seekTo(long); + method public void seekTo(long, int); method public void selectTrack(int); method public final void setDataSource(android.content.Context, android.net.Uri, java.util.Map<java.lang.String, java.lang.String>) throws java.io.IOException; method public final void setDataSource(java.lang.String, java.util.Map<java.lang.String, java.lang.String>); method public final void setDataSource(java.lang.String); method public final void setDataSource(java.io.FileDescriptor); method public final void setDataSource(java.io.FileDescriptor, long, long); + method public void unselectTrack(int); field public static final int SAMPLE_FLAG_ENCRYPTED = 2; // 0x2 field public static final int SAMPLE_FLAG_SYNC = 1; // 0x1 + field public static final int SEEK_TO_CLOSEST = 3; // 0x3 + field public static final int SEEK_TO_CLOSEST_SYNC = 2; // 0x2 + field public static final int SEEK_TO_NEXT_SYNC = 1; // 0x1 + field public static final int SEEK_TO_PREVIOUS_SYNC = 0; // 0x0 } public class MediaMetadataRetriever { @@ -11251,6 +11256,7 @@ package android.media { public final class MediaRecorder.AudioEncoder { field public static final int AAC = 3; // 0x3 + field public static final int AAC_ELD = 6; // 0x6 field public static final int AMR_NB = 1; // 0x1 field public static final int AMR_WB = 2; // 0x2 field public static final int DEFAULT = 0; // 0x0 @@ -26608,7 +26614,7 @@ package android.widget { method public abstract void onNothingSelected(android.widget.AdapterView<?>); } - public abstract class AdapterViewAnimator extends android.widget.AdapterView { + public abstract class AdapterViewAnimator extends android.widget.AdapterView implements android.widget.Advanceable { ctor public AdapterViewAnimator(android.content.Context); ctor public AdapterViewAnimator(android.content.Context, android.util.AttributeSet); ctor public AdapterViewAnimator(android.content.Context, android.util.AttributeSet, int); @@ -26650,6 +26656,11 @@ package android.widget { method public void stopFlipping(); } + public abstract interface Advanceable { + method public abstract void advance(); + method public abstract void fyiWillBeAdvancedByHostKThx(); + } + public class AlphabetIndexer extends android.database.DataSetObserver implements android.widget.SectionIndexer { ctor public AlphabetIndexer(android.database.Cursor, int, java.lang.CharSequence); method protected int compare(java.lang.String, java.lang.String); diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index 11b4c3ad831e..7dce2d3d9950 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -502,7 +502,16 @@ public class ActivityManager { /** * Return a list of the tasks that the user has recently launched, with * the most recent being first and older ones after in order. - * + * + * <p><b>Note: this method is only intended for debugging and presenting + * task management user interfaces</b>. This should never be used for + * core logic in an application, such as deciding between different + * behaviors based on the information found here. Such uses are + * <em>not</em> supported, and will likely break in the future. For + * example, if multiple applications can be actively running at the + * same time, assumptions made about the meaning of the data here for + * purposes of control flow will be incorrect.</p> + * * @param maxNum The maximum number of entries to return in the list. The * actual number returned may be smaller, depending on how many tasks the * user has started and the maximum number the system can remember. @@ -669,6 +678,15 @@ public class ActivityManager { * can be restarted in its previous state when next brought to the * foreground. * + * <p><b>Note: this method is only intended for debugging and presenting + * task management user interfaces</b>. This should never be used for + * core logic in an application, such as deciding between different + * behaviors based on the information found here. Such uses are + * <em>not</em> supported, and will likely break in the future. For + * example, if multiple applications can be actively running at the + * same time, assumptions made about the meaning of the data here for + * purposes of control flow will be incorrect.</p> + * * @param maxNum The maximum number of entries to return in the list. The * actual number returned may be smaller, depending on how many tasks the * user has started. @@ -1016,7 +1034,10 @@ public class ActivityManager { /** * Return a list of the services that are currently running. - * + * + * <p><b>Note: this method is only intended for debugging or implementing + * service management type user interfaces.</b></p> + * * @param maxNum The maximum number of entries to return in the list. The * actual number returned may be smaller, depending on how many services * are running. @@ -1128,6 +1149,16 @@ public class ActivityManager { } } + /** + * Return general information about the memory state of the system. This + * can be used to help decide how to manage your own memory, though note + * that polling is not recommended and + * {@link android.content.ComponentCallbacks2#onTrimMemory(int) + * ComponentCallbacks2.onTrimMemory(int)} is the preferred way to do this. + * Also see {@link #getMyMemoryState} for how to retrieve the current trim + * level of your process as needed, which gives a better hint for how to + * manage its memory. + */ public void getMemoryInfo(MemoryInfo outInfo) { try { ActivityManagerNative.getDefault().getMemoryInfo(outInfo); @@ -1497,6 +1528,9 @@ public class ActivityManager { * Returns a list of application processes installed on external media * that are running on the device. * + * <p><b>Note: this method is only intended for debugging or building + * a user-facing process management UI.</b></p> + * * @return Returns a list of ApplicationInfo records, or null if none * This list ordering is not specified. * @hide @@ -1511,7 +1545,10 @@ public class ActivityManager { /** * Returns a list of application processes that are running on the device. - * + * + * <p><b>Note: this method is only intended for debugging or building + * a user-facing process management UI.</b></p> + * * @return Returns a list of RunningAppProcessInfo records, or null if there are no * running processes (it will not return an empty list). This list ordering is not * specified. @@ -1544,7 +1581,10 @@ public class ActivityManager { /** * Return information about the memory usage of one or more processes. - * + * + * <p><b>Note: this method is only intended for debugging or building + * a user-facing process management UI.</b></p> + * * @param pids The pids of the processes whose memory usage is to be * retrieved. * @return Returns an array of memory information, one for each diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java index 0519d3ebf1b5..7e1daa49f049 100644 --- a/core/java/android/app/FragmentManager.java +++ b/core/java/android/app/FragmentManager.java @@ -1890,7 +1890,7 @@ final class FragmentManagerImpl extends FragmentManager { if (mActive != null) { for (int i=0; i<mAdded.size(); i++) { Fragment f = mAdded.get(i); - if (f != null && !f.mHidden) { + if (f != null && !f.mHidden && f.mUserVisibleHint) { if (f.onContextItemSelected(item)) { return true; } diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java index 6f19934a1bf0..3824f44ffc4d 100644 --- a/core/java/android/app/WallpaperManager.java +++ b/core/java/android/app/WallpaperManager.java @@ -637,6 +637,14 @@ public class WallpaperManager { * wallpaper it would like to use. This allows such applications to have * a virtual wallpaper that is larger than the physical screen, matching * the size of their workspace. + * + * <p>Note developers, who don't seem to be reading this. This is + * for <em>home screens</em> to tell what size wallpaper they would like. + * Nobody else should be calling this! Certainly not other non-home-screen + * apps that change the wallpaper. Those apps are supposed to + * <b>retrieve</b> the suggested size so they can construct a wallpaper + * that matches it. + * * @param minimumWidth Desired minimum width * @param minimumHeight Desired minimum height */ diff --git a/core/java/android/content/ComponentCallbacks2.java b/core/java/android/content/ComponentCallbacks2.java index 85294dd00c9c..a3b4e5efb583 100644 --- a/core/java/android/content/ComponentCallbacks2.java +++ b/core/java/android/content/ComponentCallbacks2.java @@ -88,7 +88,11 @@ public interface ComponentCallbacks2 extends ComponentCallbacks { * should never compare to exact values of the level, since new intermediate * values may be added -- you will typically want to compare if the value * is greater or equal to a level you are interested in. - * + * + * <p>To retrieve the processes current trim level at any point, you can + * use {@link android.app.ActivityManager#getMyMemoryState + * ActivityManager.getMyMemoryState(RunningAppProcessInfo)}. + * * @param level The context of the trim, giving a hint of the amount of * trimming the application may like to perform. May be * {@link #TRIM_MEMORY_COMPLETE}, {@link #TRIM_MEMORY_MODERATE}, diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index 665333693e1a..d0d9bd6c5e30 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -1624,8 +1624,20 @@ public class Intent implements Parcelable, Cloneable { /** * Broadcast Action: The current system wallpaper has changed. See * {@link android.app.WallpaperManager} for retrieving the new wallpaper. - */ - @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + * This should <em>only</em> be used to determine when the wallpaper + * has changed to show the new wallpaper to the user. You should certainly + * never, in response to this, change the wallpaper or other attributes of + * it such as the suggested size. That would be crazy, right? You'd cause + * all kinds of loops, especially if other apps are doing similar things, + * right? Of course. So please don't do this. + * + * @deprecated Modern applications should use + * {@link android.view.WindowManager.LayoutParams#FLAG_SHOW_WALLPAPER + * WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER} to have the wallpaper + * shown behind their UI, rather than watching for this broadcast and + * rendering the wallpaper on their own. + */ + @Deprecated @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_WALLPAPER_CHANGED = "android.intent.action.WALLPAPER_CHANGED"; /** * Broadcast Action: The current device {@link android.content.res.Configuration} diff --git a/core/java/android/os/storage/IMountService.java b/core/java/android/os/storage/IMountService.java index 0640d7e9852b..f4abda6cd35c 100644 --- a/core/java/android/os/storage/IMountService.java +++ b/core/java/android/os/storage/IMountService.java @@ -252,7 +252,7 @@ public interface IMountService extends IInterface { * an int consistent with MountServiceResultCode */ public int createSecureContainer(String id, int sizeMb, String fstype, String key, - int ownerUid) throws RemoteException { + int ownerUid, boolean external) throws RemoteException { Parcel _data = Parcel.obtain(); Parcel _reply = Parcel.obtain(); int _result; @@ -263,6 +263,7 @@ public interface IMountService extends IInterface { _data.writeString(fstype); _data.writeString(key); _data.writeInt(ownerUid); + _data.writeInt(external ? 1 : 0); mRemote.transact(Stub.TRANSACTION_createSecureContainer, _data, _reply, 0); _reply.readException(); _result = _reply.readInt(); @@ -711,6 +712,31 @@ public interface IMountService extends IInterface { } return _result; } + + /** + * Fix permissions in a container which has just been created and + * populated. Returns an int consistent with MountServiceResultCode + */ + public int fixPermissionsSecureContainer(String id, int gid, String filename) + throws RemoteException { + Parcel _data = Parcel.obtain(); + Parcel _reply = Parcel.obtain(); + int _result; + try { + _data.writeInterfaceToken(DESCRIPTOR); + _data.writeString(id); + _data.writeInt(gid); + _data.writeString(filename); + mRemote.transact(Stub.TRANSACTION_fixPermissionsSecureContainer, _data, _reply, 0); + _reply.readException(); + _result = _reply.readInt(); + } finally { + _reply.recycle(); + _data.recycle(); + } + return _result; + + } } private static final String DESCRIPTOR = "IMountService"; @@ -781,6 +807,8 @@ public interface IMountService extends IInterface { static final int TRANSACTION_verifyEncryptionPassword = IBinder.FIRST_CALL_TRANSACTION + 32; + static final int TRANSACTION_fixPermissionsSecureContainer = IBinder.FIRST_CALL_TRANSACTION + 33; + /** * Cast an IBinder object into an IMountService interface, generating a * proxy if needed. @@ -909,7 +937,10 @@ public interface IMountService extends IInterface { key = data.readString(); int ownerUid; ownerUid = data.readInt(); - int resultCode = createSecureContainer(id, sizeMb, fstype, key, ownerUid); + boolean external; + external = 0 != data.readInt(); + int resultCode = createSecureContainer(id, sizeMb, fstype, key, ownerUid, + external); reply.writeNoException(); reply.writeInt(resultCode); return true; @@ -1109,6 +1140,19 @@ public interface IMountService extends IInterface { reply.writeInt(result); return true; } + case TRANSACTION_fixPermissionsSecureContainer: { + data.enforceInterface(DESCRIPTOR); + String id; + id = data.readString(); + int gid; + gid = data.readInt(); + String filename; + filename = data.readString(); + int resultCode = fixPermissionsSecureContainer(id, gid, filename); + reply.writeNoException(); + reply.writeInt(resultCode); + return true; + } } return super.onTransact(code, data, reply, flags); } @@ -1118,8 +1162,8 @@ public interface IMountService extends IInterface { * Creates a secure container with the specified parameters. Returns an int * consistent with MountServiceResultCode */ - public int createSecureContainer(String id, int sizeMb, String fstype, String key, int ownerUid) - throws RemoteException; + public int createSecureContainer(String id, int sizeMb, String fstype, String key, + int ownerUid, boolean external) throws RemoteException; /* * Destroy a secure container, and free up all resources associated with it. @@ -1317,4 +1361,11 @@ public interface IMountService extends IInterface { public Parcelable[] getVolumeList() throws RemoteException; public String getSecureContainerFilesystemPath(String id) throws RemoteException; + + /* + * Fix permissions in a container which has just been created and populated. + * Returns an int consistent with MountServiceResultCode + */ + public int fixPermissionsSecureContainer(String id, int gid, String filename) + throws RemoteException; } diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java index 7d41e649c338..018785bb8294 100644 --- a/core/java/android/provider/ContactsContract.java +++ b/core/java/android/provider/ContactsContract.java @@ -5411,8 +5411,9 @@ public final class ContactsContract { /** * The phone number's E164 representation. This value can be omitted in which - * case the provider will try to automatically infer it. If present, {@link #NUMBER} - * has to be set as well (it will be ignored otherwise). + * case the provider will try to automatically infer it. (It'll be left null if the + * provider fails to infer.) + * If present, {@link #NUMBER} has to be set as well (it will be ignored otherwise). * <P>Type: TEXT</P> */ public static final String NORMALIZED_NUMBER = DATA4; diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java index 2dcea80c5b21..c453a5db42c7 100644 --- a/core/java/android/text/Layout.java +++ b/core/java/android/text/Layout.java @@ -45,8 +45,7 @@ public abstract class Layout { private static final ParagraphStyle[] NO_PARA_SPANS = ArrayUtils.emptyArray(ParagraphStyle.class); - /* package */ static final EmojiFactory EMOJI_FACTORY = - EmojiFactory.newAvailableInstance(); + /* package */ static final EmojiFactory EMOJI_FACTORY = EmojiFactory.newAvailableInstance(); /* package */ static final int MIN_EMOJI, MAX_EMOJI; static { @@ -363,15 +362,15 @@ public abstract class Layout { // direction of the layout or line. XXX: Should they? // They are evaluated at each line. if (mSpannedText) { - if (lineBackgroundSpans == null) { - lineBackgroundSpans = new SpanSet<LineBackgroundSpan>(LineBackgroundSpan.class); + if (mLineBackgroundSpans == null) { + mLineBackgroundSpans = new SpanSet<LineBackgroundSpan>(LineBackgroundSpan.class); } Spanned buffer = (Spanned) mText; int textLength = buffer.length(); - lineBackgroundSpans.init(buffer, 0, textLength); + mLineBackgroundSpans.init(buffer, 0, textLength); - if (lineBackgroundSpans.numberOfSpans > 0) { + if (mLineBackgroundSpans.numberOfSpans > 0) { int previousLineBottom = getLineTop(firstLine); int previousLineEnd = getLineStart(firstLine); ParagraphStyle[] spans = NO_PARA_SPANS; @@ -392,17 +391,18 @@ public abstract class Layout { if (start >= spanEnd) { // These should be infrequent, so we'll use this so that // we don't have to check as often. - spanEnd = lineBackgroundSpans.getNextTransition(start, textLength); + spanEnd = mLineBackgroundSpans.getNextTransition(start, textLength); // All LineBackgroundSpans on a line contribute to its background. spansLength = 0; // Duplication of the logic of getParagraphSpans if (start != end || start == 0) { // Equivalent to a getSpans(start, end), but filling the 'spans' local // array instead to reduce memory allocation - for (int j = 0; j < lineBackgroundSpans.numberOfSpans; j++) { - // equal test is valid since both intervals are not empty by construction - if (lineBackgroundSpans.spanStarts[j] >= end || - lineBackgroundSpans.spanEnds[j] <= start) continue; + for (int j = 0; j < mLineBackgroundSpans.numberOfSpans; j++) { + // equal test is valid since both intervals are not empty by + // construction + if (mLineBackgroundSpans.spanStarts[j] >= end || + mLineBackgroundSpans.spanEnds[j] <= start) continue; if (spansLength == spans.length) { // The spans array needs to be expanded int newSize = ArrayUtils.idealObjectArraySize(2 * spansLength); @@ -410,7 +410,7 @@ public abstract class Layout { System.arraycopy(spans, 0, newSpans, 0, spansLength); spans = newSpans; } - spans[spansLength++] = lineBackgroundSpans.spans[j]; + spans[spansLength++] = mLineBackgroundSpans.spans[j]; } } } @@ -423,7 +423,7 @@ public abstract class Layout { } } } - lineBackgroundSpans.recycle(); + mLineBackgroundSpans.recycle(); } // There can be a highlight even without spans if we are drawing @@ -1687,7 +1687,7 @@ public abstract class Layout { * styles that are already applied to the buffer will apply to text that * is inserted into it. */ - /* package */ static <T> T[] getParagraphSpans(Spanned text, int start, int end, Class<T> type) { + /* package */static <T> T[] getParagraphSpans(Spanned text, int start, int end, Class<T> type) { if (start == end && start > 0) { return ArrayUtils.emptyArray(type); } @@ -1857,7 +1857,7 @@ public abstract class Layout { private static final Rect sTempRect = new Rect(); private boolean mSpannedText; private TextDirectionHeuristic mTextDir; - private SpanSet<LineBackgroundSpan> lineBackgroundSpans; + private SpanSet<LineBackgroundSpan> mLineBackgroundSpans; public static final int DIR_LEFT_TO_RIGHT = 1; public static final int DIR_RIGHT_TO_LEFT = -1; diff --git a/core/java/android/view/KeyCharacterMap.java b/core/java/android/view/KeyCharacterMap.java index 1c61c6c7d4ee..5b371ebf31cd 100644 --- a/core/java/android/view/KeyCharacterMap.java +++ b/core/java/android/view/KeyCharacterMap.java @@ -153,20 +153,26 @@ public class KeyCharacterMap implements Parcelable { private static final int ACCENT_BREVE = '\u02D8'; private static final int ACCENT_CARON = '\u02C7'; private static final int ACCENT_CEDILLA = '\u00B8'; + private static final int ACCENT_CIRCUMFLEX = '\u02C6'; private static final int ACCENT_COMMA_ABOVE = '\u1FBD'; private static final int ACCENT_COMMA_ABOVE_RIGHT = '\u02BC'; private static final int ACCENT_DOT_ABOVE = '\u02D9'; + private static final int ACCENT_DOT_BELOW = '.'; // approximate private static final int ACCENT_DOUBLE_ACUTE = '\u02DD'; private static final int ACCENT_GRAVE = '\u02CB'; - private static final int ACCENT_CIRCUMFLEX = '\u02C6'; + private static final int ACCENT_HOOK_ABOVE = '\u02C0'; + private static final int ACCENT_HORN = '\''; // approximate private static final int ACCENT_MACRON = '\u00AF'; private static final int ACCENT_MACRON_BELOW = '\u02CD'; private static final int ACCENT_OGONEK = '\u02DB'; private static final int ACCENT_REVERSED_COMMA_ABOVE = '\u02BD'; private static final int ACCENT_RING_ABOVE = '\u02DA'; + private static final int ACCENT_STROKE = '-'; // approximate private static final int ACCENT_TILDE = '\u02DC'; private static final int ACCENT_TURNED_COMMA_ABOVE = '\u02BB'; private static final int ACCENT_UMLAUT = '\u00A8'; + private static final int ACCENT_VERTICAL_LINE_ABOVE = '\u02C8'; + private static final int ACCENT_VERTICAL_LINE_BELOW = '\u02CC'; /* Legacy dead key display characters used in previous versions of the API. * We still support these characters by mapping them to their non-legacy version. */ @@ -188,11 +194,11 @@ public class KeyCharacterMap implements Parcelable { addCombining('\u0306', ACCENT_BREVE); addCombining('\u0307', ACCENT_DOT_ABOVE); addCombining('\u0308', ACCENT_UMLAUT); - //addCombining('\u0309', ACCENT_HOOK_ABOVE); + addCombining('\u0309', ACCENT_HOOK_ABOVE); addCombining('\u030A', ACCENT_RING_ABOVE); addCombining('\u030B', ACCENT_DOUBLE_ACUTE); addCombining('\u030C', ACCENT_CARON); - //addCombining('\u030D', ACCENT_VERTICAL_LINE_ABOVE); + addCombining('\u030D', ACCENT_VERTICAL_LINE_ABOVE); //addCombining('\u030E', ACCENT_DOUBLE_VERTICAL_LINE_ABOVE); //addCombining('\u030F', ACCENT_DOUBLE_GRAVE); //addCombining('\u0310', ACCENT_CANDRABINDU); @@ -201,13 +207,14 @@ public class KeyCharacterMap implements Parcelable { addCombining('\u0313', ACCENT_COMMA_ABOVE); addCombining('\u0314', ACCENT_REVERSED_COMMA_ABOVE); addCombining('\u0315', ACCENT_COMMA_ABOVE_RIGHT); - //addCombining('\u031B', ACCENT_HORN); - //addCombining('\u0323', ACCENT_DOT_BELOW); + addCombining('\u031B', ACCENT_HORN); + addCombining('\u0323', ACCENT_DOT_BELOW); //addCombining('\u0326', ACCENT_COMMA_BELOW); addCombining('\u0327', ACCENT_CEDILLA); addCombining('\u0328', ACCENT_OGONEK); - //addCombining('\u0329', ACCENT_VERTICAL_LINE_BELOW); + addCombining('\u0329', ACCENT_VERTICAL_LINE_BELOW); addCombining('\u0331', ACCENT_MACRON_BELOW); + addCombining('\u0335', ACCENT_STROKE); //addCombining('\u0342', ACCENT_PERISPOMENI); //addCombining('\u0344', ACCENT_DIALYTIKA_TONOS); //addCombining('\u0345', ACCENT_YPOGEGRAMMENI); @@ -235,6 +242,33 @@ public class KeyCharacterMap implements Parcelable { */ private static final SparseIntArray sDeadKeyCache = new SparseIntArray(); private static final StringBuilder sDeadKeyBuilder = new StringBuilder(); + static { + // Non-standard decompositions. + // Stroke modifier for Finnish multilingual keyboard and others. + addDeadKey(ACCENT_STROKE, 'D', '\u0110'); + addDeadKey(ACCENT_STROKE, 'G', '\u01e4'); + addDeadKey(ACCENT_STROKE, 'H', '\u0126'); + addDeadKey(ACCENT_STROKE, 'I', '\u0197'); + addDeadKey(ACCENT_STROKE, 'L', '\u0141'); + addDeadKey(ACCENT_STROKE, 'O', '\u00d8'); + addDeadKey(ACCENT_STROKE, 'T', '\u0166'); + addDeadKey(ACCENT_STROKE, 'd', '\u0111'); + addDeadKey(ACCENT_STROKE, 'g', '\u01e5'); + addDeadKey(ACCENT_STROKE, 'h', '\u0127'); + addDeadKey(ACCENT_STROKE, 'i', '\u0268'); + addDeadKey(ACCENT_STROKE, 'l', '\u0142'); + addDeadKey(ACCENT_STROKE, 'o', '\u00f8'); + addDeadKey(ACCENT_STROKE, 't', '\u0167'); + } + + private static void addDeadKey(int accent, int c, int result) { + final int combining = sAccentToCombining.get(accent); + if (combining == 0) { + throw new IllegalStateException("Invalid dead key declaration."); + } + final int combination = (combining << 16) | c; + sDeadKeyCache.put(combination, result); + } public static final Parcelable.Creator<KeyCharacterMap> CREATOR = new Parcelable.Creator<KeyCharacterMap>() { diff --git a/core/java/android/webkit/CacheManager.java b/core/java/android/webkit/CacheManager.java index 671c06446609..f0e6ff03a919 100644 --- a/core/java/android/webkit/CacheManager.java +++ b/core/java/android/webkit/CacheManager.java @@ -56,6 +56,7 @@ public final class CacheManager { * Represents a resource stored in the HTTP cache. Instances of this class * can be obtained by calling * {@link CacheManager#getCacheFile CacheManager.getCacheFile(String, Map<String, String>))}. + * * @deprecated Access to the HTTP cache will be removed in a future release. */ @Deprecated @@ -81,7 +82,8 @@ public final class CacheManager { /** * Gets the status code of this cache entry. - * @return The status code of this cache entry + * + * @return the status code of this cache entry */ public int getHttpStatusCode() { return httpStatusCode; @@ -89,7 +91,8 @@ public final class CacheManager { /** * Gets the content length of this cache entry. - * @return The content length of this cache entry + * + * @return the content length of this cache entry */ public long getContentLength() { return contentLength; @@ -99,7 +102,8 @@ public final class CacheManager { * Gets the path of the file used to store the content of this cache * entry, relative to the base directory of the cache. See * {@link CacheManager#getCacheFileBaseDir CacheManager.getCacheFileBaseDir()}. - * @return The path of the file used to store this cache entry + * + * @return the path of the file used to store this cache entry */ public String getLocalPath() { return localPath; @@ -108,7 +112,8 @@ public final class CacheManager { /** * Gets the expiry date of this cache entry, expressed in milliseconds * since midnight, January 1, 1970 UTC. - * @return The expiry date of this cache entry + * + * @return the expiry date of this cache entry */ public long getExpires() { return expires; @@ -116,7 +121,8 @@ public final class CacheManager { /** * Gets the expiry date of this cache entry, expressed as a string. - * @return The expiry date of this cache entry + * + * @return the expiry date of this cache entry * */ public String getExpiresString() { @@ -126,7 +132,8 @@ public final class CacheManager { /** * Gets the date at which this cache entry was last modified, expressed * as a string. - * @return The date at which this cache entry was last modified + * + * @return the date at which this cache entry was last modified */ public String getLastModified() { return lastModified; @@ -134,7 +141,8 @@ public final class CacheManager { /** * Gets the entity tag of this cache entry. - * @return The entity tag of this cache entry + * + * @return the entity tag of this cache entry */ public String getETag() { return etag; @@ -142,7 +150,8 @@ public final class CacheManager { /** * Gets the MIME type of this cache entry. - * @return The MIME type of this cache entry + * + * @return the MIME type of this cache entry */ public String getMimeType() { return mimeType; @@ -151,7 +160,8 @@ public final class CacheManager { /** * Gets the value of the HTTP 'Location' header with which this cache * entry was received. - * @return The HTTP 'Location' header for this cache entry + * + * @return the HTTP 'Location' header for this cache entry */ public String getLocation() { return location; @@ -159,7 +169,8 @@ public final class CacheManager { /** * Gets the encoding of this cache entry. - * @return The encoding of this cache entry + * + * @return the encoding of this cache entry */ public String getEncoding() { return encoding; @@ -168,7 +179,8 @@ public final class CacheManager { /** * Gets the value of the HTTP 'Content-Disposition' header with which * this cache entry was received. - * @return The HTTP 'Content-Disposition' header for this cache entry + * + * @return the HTTP 'Content-Disposition' header for this cache entry * */ public String getContentDisposition() { @@ -179,7 +191,8 @@ public final class CacheManager { * Gets the input stream to the content of this cache entry, to allow * content to be read. See * {@link CacheManager#getCacheFile CacheManager.getCacheFile(String, Map<String, String>)}. - * @return An input stream to the content of this cache entry + * + * @return an input stream to the content of this cache entry */ public InputStream getInputStream() { return inStream; @@ -189,7 +202,8 @@ public final class CacheManager { * Gets an output stream to the content of this cache entry, to allow * content to be written. See * {@link CacheManager#saveCacheFile CacheManager.saveCacheFile(String, CacheResult)}. - * @return An output stream to the content of this cache entry + * + * @return an output stream to the content of this cache entry */ // Note that this is always null for objects returned by getCacheFile()! public OutputStream getOutputStream() { @@ -199,7 +213,8 @@ public final class CacheManager { /** * Sets an input stream to the content of this cache entry. - * @param stream An input stream to the content of this cache entry + * + * @param stream an input stream to the content of this cache entry */ public void setInputStream(InputStream stream) { this.inStream = stream; @@ -207,7 +222,8 @@ public final class CacheManager { /** * Sets the encoding of this cache entry. - * @param encoding The encoding of this cache entry + * + * @param encoding the encoding of this cache entry */ public void setEncoding(String encoding) { this.encoding = encoding; @@ -225,7 +241,8 @@ public final class CacheManager { * Initializes the HTTP cache. This method must be called before any * CacheManager methods are used. Note that this is called automatically * when a {@link WebView} is created. - * @param context The application context + * + * @param context the application context */ static void init(Context context) { // This isn't actually where the real cache lives, but where we put files for the @@ -240,7 +257,8 @@ public final class CacheManager { * Gets the base directory in which the files used to store the contents of * cache entries are placed. See * {@link CacheManager.CacheResult#getLocalPath CacheManager.CacheResult.getLocalPath()}. - * @return The base directory of the cache + * + * @return the base directory of the cache * @deprecated Access to the HTTP cache will be removed in a future release. */ @Deprecated @@ -250,7 +268,8 @@ public final class CacheManager { /** * Gets whether the HTTP cache is disabled. - * @return True if the HTTP cache is disabled + * + * @return true if the HTTP cache is disabled * @deprecated Access to the HTTP cache will be removed in a future release. */ @Deprecated @@ -262,8 +281,9 @@ public final class CacheManager { * Starts a cache transaction. Returns true if this is the only running * transaction. Otherwise, this transaction is nested inside currently * running transactions and false is returned. - * @return True if this is the only running transaction - * @deprecated This method no longer has any effect and always returns false + * + * @return true if this is the only running transaction + * @deprecated This method no longer has any effect and always returns false. */ @Deprecated public static boolean startCacheTransaction() { @@ -273,8 +293,9 @@ public final class CacheManager { /** * Ends the innermost cache transaction and returns whether this was the * only running transaction. - * @return True if this was the only running transaction - * @deprecated This method no longer has any effect and always returns false + * + * @return true if this was the only running transaction + * @deprecated This method no longer has any effect and always returns false. */ @Deprecated public static boolean endCacheTransaction() { @@ -287,10 +308,11 @@ public final class CacheManager { * entry needs validation, appropriate headers will be added to the map. * The input stream of the CacheEntry object should be closed by the caller * when access to the underlying file is no longer required. - * @param url The URL for which a cache entry is requested - * @param headers A map from HTTP header name to value, to be populated + * + * @param url the URL for which a cache entry is requested + * @param headers a map from HTTP header name to value, to be populated * for the returned cache entry - * @return The cache entry for the specified URL + * @return the cache entry for the specified URL * @deprecated Access to the HTTP cache will be removed in a future release. */ @Deprecated @@ -345,14 +367,15 @@ public final class CacheManager { } /** - * Given a url and its full headers, returns CacheResult if a local cache + * Given a URL and its full headers, gets a CacheResult if a local cache * can be stored. Otherwise returns null. The mimetype is passed in so that * the function can use the mimetype that will be passed to WebCore which * could be different from the mimetype defined in the headers. * forceCache is for out-of-package callers to force creation of a * CacheResult, and is used to supply surrogate responses for URL * interception. - * @return CacheResult for a given url + * + * @return a CacheResult for a given URL */ static CacheResult createCacheFile(String url, int statusCode, Headers headers, String mimeType, boolean forceCache) { @@ -363,8 +386,9 @@ public final class CacheManager { /** * Adds a cache entry to the HTTP cache for the specicifed URL. Also closes * the cache entry's output stream. - * @param url The URL for which the cache entry should be added - * @param cacheResult The cache entry to add + * + * @param url the URL for which the cache entry should be added + * @param cacheResult the cache entry to add * @deprecated Access to the HTTP cache will be removed in a future release. */ @Deprecated @@ -401,9 +425,9 @@ public final class CacheManager { } /** - * Remove all cache files. + * Removes all cache files. * - * @return Whether the removal succeeded. + * @return whether the removal succeeded */ static boolean removeAllCacheFiles() { // delete cache files in a separate thread to not block UI. diff --git a/core/java/android/webkit/CookieManager.java b/core/java/android/webkit/CookieManager.java index 1e7f38ce5af2..30c713e814c0 100644 --- a/core/java/android/webkit/CookieManager.java +++ b/core/java/android/webkit/CookieManager.java @@ -40,7 +40,7 @@ public class CookieManager { * {@link CookieSyncManager#createInstance(Context)} must be called * first. * - * @return The singleton CookieManager instance + * @return the singleton CookieManager instance */ public static synchronized CookieManager getInstance() { return WebViewFactory.getProvider().getCookieManager(); @@ -49,7 +49,8 @@ public class CookieManager { /** * Sets whether the application's {@link WebView} instances should send and * accept cookies. - * @param accept Whether {@link WebView} instances should send and accept + * + * @param accept whether {@link WebView} instances should send and accept * cookies */ public synchronized void setAcceptCookie(boolean accept) { @@ -59,7 +60,8 @@ public class CookieManager { /** * Gets whether the application's {@link WebView} instances send and accept * cookies. - * @return True if {@link WebView} instances send and accept cookies + * + * @return true if {@link WebView} instances send and accept cookies */ public synchronized boolean acceptCookie() { throw new MustOverrideException(); @@ -70,8 +72,9 @@ public class CookieManager { * path and name will be replaced with the new cookie. The cookie being set * must not have expired and must not be a session cookie, otherwise it * will be ignored. - * @param url The URL for which the cookie is set - * @param value The cookie as a string, using the format of the 'Set-Cookie' + * + * @param url the URL for which the cookie is set + * @param value the cookie as a string, using the format of the 'Set-Cookie' * HTTP response header */ public void setCookie(String url, String value) { @@ -80,8 +83,9 @@ public class CookieManager { /** * Gets the cookies for the given URL. - * @param url The URL for which the cookies are requested - * @return value The cookies as a string, using the format of the 'Cookie' + * + * @param url the URL for which the cookies are requested + * @return value the cookies as a string, using the format of the 'Cookie' * HTTP request header */ public String getCookie(String url) { @@ -89,10 +93,11 @@ public class CookieManager { } /** - * See {@link #getCookie(String)} - * @param url The URL for which the cookies are requested - * @param privateBrowsing Whether to use the private browsing cookie jar - * @return value The cookies as a string, using the format of the 'Cookie' + * See {@link #getCookie(String)}. + * + * @param url the URL for which the cookies are requested + * @param privateBrowsing whether to use the private browsing cookie jar + * @return value the cookies as a string, using the format of the 'Cookie' * HTTP request header * @hide Used by Browser, no intention to publish. */ @@ -101,10 +106,11 @@ public class CookieManager { } /** - * Get cookie(s) for a given uri so that it can be set to "cookie:" in http + * Gets cookie(s) for a given uri so that it can be set to "cookie:" in http * request header. - * @param uri The WebAddress for which the cookies are requested - * @return value The cookies as a string, using the format of the 'Cookie' + * + * @param uri the WebAddress for which the cookies are requested + * @return value the cookies as a string, using the format of the 'Cookie' * HTTP request header * @hide Used by RequestHandle, no intention to publish. */ @@ -129,7 +135,8 @@ public class CookieManager { /** * Gets whether there are stored cookies. - * @return True if there are stored cookies. + * + * @return true if there are stored cookies */ public synchronized boolean hasCookies() { throw new MustOverrideException(); @@ -137,7 +144,8 @@ public class CookieManager { /** * See {@link #hasCookies()}. - * @param privateBrowsing Whether to use the private browsing cookie jar + * + * @param privateBrowsing whether to use the private browsing cookie jar * @hide Used by Browser, no intention to publish. */ public synchronized boolean hasCookies(boolean privateBrowsing) { @@ -152,7 +160,7 @@ public class CookieManager { } /** - * Flush all cookies managed by the Chrome HTTP stack to flash. + * Flushes all cookies managed by the Chrome HTTP stack to flash. * * @hide Package level api, called from CookieSyncManager */ @@ -163,7 +171,8 @@ public class CookieManager { /** * Gets whether the application's {@link WebView} instances send and accept * cookies for file scheme URLs. - * @return True if {@link WebView} instances send and accept cookies for + * + * @return true if {@link WebView} instances send and accept cookies for * file scheme URLs */ // Static for backward compatibility. @@ -172,7 +181,8 @@ public class CookieManager { } /** - * Implements {@link #allowFileSchemeCookies()} + * Implements {@link #allowFileSchemeCookies()}. + * * @hide Only for use by WebViewProvider implementations */ protected boolean allowFileSchemeCookiesImpl() { @@ -195,7 +205,8 @@ public class CookieManager { } /** - * Implements {@link #setAcceptFileSchemeCookies(boolean)} + * Implements {@link #setAcceptFileSchemeCookies(boolean)}. + * * @hide Only for use by WebViewProvider implementations */ protected void setAcceptFileSchemeCookiesImpl(boolean accept) { diff --git a/core/java/android/webkit/GeolocationPermissions.java b/core/java/android/webkit/GeolocationPermissions.java index cd5c9d136816..9c0f7541fbcf 100755 --- a/core/java/android/webkit/GeolocationPermissions.java +++ b/core/java/android/webkit/GeolocationPermissions.java @@ -48,28 +48,31 @@ public class GeolocationPermissions { */ public interface Callback { /** - * Set the Geolocation permission state for the supplied origin. - * @param origin The origin for which permissions are set. - * @param allow Whether or not the origin should be allowed to use the - * Geolocation API. - * @param retain Whether the permission should be retained beyond the + * Sets the Geolocation permission state for the supplied origin. + * + * @param origin the origin for which permissions are set + * @param allow whether or not the origin should be allowed to use the + * Geolocation API + * @param retain whether the permission should be retained beyond the * lifetime of a page currently being displayed by a - * WebView. + * WebView */ public void invoke(String origin, boolean allow, boolean retain); }; /** - * Get the singleton instance of this class. - * @return The singleton {@link GeolocationPermissions} instance. + * Gets the singleton instance of this class. + * + * @return the singleton {@link GeolocationPermissions} instance */ public static GeolocationPermissions getInstance() { return WebViewFactory.getProvider().getGeolocationPermissions(); } /** - * Get the set of origins for which Geolocation permissions are stored. - * @param callback A {@link ValueCallback} to receive the result of this + * Gets the set of origins for which Geolocation permissions are stored. + * + * @param callback a {@link ValueCallback} to receive the result of this * request. This object's * {@link ValueCallback#onReceiveValue(T) onReceiveValue()} * method will be invoked asynchronously with a set of @@ -85,9 +88,10 @@ public class GeolocationPermissions { } /** - * Get the Geolocation permission state for the specified origin. - * @param origin The origin for which Geolocation permission is requested. - * @param callback A {@link ValueCallback} to receive the result of this + * Gets the Geolocation permission state for the specified origin. + * + * @param origin the origin for which Geolocation permission is requested + * @param callback a {@link ValueCallback} to receive the result of this * request. This object's * {@link ValueCallback#onReceiveValue(T) onReceiveValue()} * method will be invoked asynchronously with a boolean @@ -99,23 +103,25 @@ public class GeolocationPermissions { } /** - * Clear the Geolocation permission state for the specified origin. - * @param origin The origin for which Geolocation permissions are cleared. + * Clears the Geolocation permission state for the specified origin. + * + * @param origin the origin for which Geolocation permissions are cleared */ public void clear(String origin) { // Must be a no-op for backward compatibility: see the hidden constructor for reason. } /** - * Allow the specified origin to use the Geolocation API. - * @param origin The origin for which Geolocation API use is allowed. + * Allows the specified origin to use the Geolocation API. + * + * @param origin the origin for which Geolocation API use is allowed */ public void allow(String origin) { // Must be a no-op for backward compatibility: see the hidden constructor for reason. } /** - * Clear the Geolocation permission state for all origins. + * Clears the Geolocation permission state for all origins. */ public void clearAll() { // Must be a no-op for backward compatibility: see the hidden constructor for reason. diff --git a/core/java/android/webkit/ViewStateSerializer.java b/core/java/android/webkit/ViewStateSerializer.java index 35168cf11c3d..c16108577a58 100644 --- a/core/java/android/webkit/ViewStateSerializer.java +++ b/core/java/android/webkit/ViewStateSerializer.java @@ -64,7 +64,6 @@ class ViewStateSerializer { draw.mViewState = new WebViewCore.ViewState(); draw.mContentSize = new Point(contentWidth, contentHeight); draw.mBaseLayer = baseLayer; - draw.mInvalRegion = new Region(0, 0, contentWidth, contentHeight); stream.close(); return draw; } diff --git a/core/java/android/webkit/WebResourceResponse.java b/core/java/android/webkit/WebResourceResponse.java index 650310e219a4..b7171eebfb3f 100644 --- a/core/java/android/webkit/WebResourceResponse.java +++ b/core/java/android/webkit/WebResourceResponse.java @@ -36,9 +36,10 @@ public class WebResourceResponse { * input stream. Callers must implement * {@link InputStream#read(byte[]) InputStream.read(byte[])} for the input * stream. - * @param mimeType The resource response's MIME type, for example text/html - * @param encoding The resource response's encoding - * @param data The input stream that provides the resource response's data + * + * @param mimeType the resource response's MIME type, for example text/html + * @param encoding the resource response's encoding + * @param data the input stream that provides the resource response's data */ public WebResourceResponse(String mimeType, String encoding, InputStream data) { @@ -49,7 +50,8 @@ public class WebResourceResponse { /** * Sets the resource response's MIME type, for example text/html. - * @param mimeType The resource response's MIME type + * + * @param mimeType the resource response's MIME type */ public void setMimeType(String mimeType) { mMimeType = mimeType; @@ -57,7 +59,8 @@ public class WebResourceResponse { /** * Gets the resource response's MIME type. - * @return The resource response's MIME type + * + * @return the resource response's MIME type */ public String getMimeType() { return mMimeType; @@ -66,7 +69,8 @@ public class WebResourceResponse { /** * Sets the resource response's encoding, for example UTF-8. This is used * to decode the data from the input stream. - * @param encoding The resource response's encoding + * + * @param encoding the resource response's encoding */ public void setEncoding(String encoding) { mEncoding = encoding; @@ -74,7 +78,8 @@ public class WebResourceResponse { /** * Gets the resource response's encoding. - * @return The resource response's encoding + * + * @return the resource response's encoding */ public String getEncoding() { return mEncoding; @@ -83,7 +88,8 @@ public class WebResourceResponse { /** * Sets the input stream that provides the resource respone's data. Callers * must implement {@link InputStream#read(byte[]) InputStream.read(byte[])}. - * @param data The input stream that provides the resource response's data + * + * @param data the input stream that provides the resource response's data */ public void setData(InputStream data) { mInputStream = data; @@ -91,7 +97,8 @@ public class WebResourceResponse { /** * Gets the input stream that provides the resource respone's data. - * @return The input stream that provides the resource response's data + * + * @return the input stream that provides the resource response's data */ public InputStream getData() { return mInputStream; diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java index 1bbf00f5fe62..901372bcceff 100644 --- a/core/java/android/webkit/WebSettings.java +++ b/core/java/android/webkit/WebSettings.java @@ -33,10 +33,12 @@ import android.os.Build; public abstract class WebSettings { /** * Enum for controlling the layout of html. - * NORMAL means no rendering changes. - * SINGLE_COLUMN moves all content into one column that is the width of the - * view. - * NARROW_COLUMNS makes all columns no wider than the screen if possible. + * <ul> + * <li>NORMAL means no rendering changes.</li> + * <li>SINGLE_COLUMN moves all content into one column that is the width of the + * view.</li> + * <li>NARROW_COLUMNS makes all columns no wider than the screen if possible.</li> + * </ul> */ // XXX: These must match LayoutAlgorithm in Settings.h in WebCore. public enum LayoutAlgorithm { @@ -51,11 +53,14 @@ public abstract class WebSettings { /** * Enum for specifying the text size. - * SMALLEST is 50% - * SMALLER is 75% - * NORMAL is 100% - * LARGER is 150% - * LARGEST is 200% + * <ul> + * <li>SMALLEST is 50%</li> + * <li>SMALLER is 75%</li> + * <li>NORMAL is 100%</li> + * <li>LARGER is 150%</li> + * <li>LARGEST is 200%</li> + * </ul> + * * @deprecated Use {@link WebSettings#setTextZoom(int)} and {@link WebSettings#getTextZoom()} instead. */ public enum TextSize { @@ -72,9 +77,11 @@ public abstract class WebSettings { /** * Enum for specifying the WebView's desired density. - * FAR makes 100% looking like in 240dpi - * MEDIUM makes 100% looking like in 160dpi - * CLOSE makes 100% looking like in 120dpi + * <ul> + * <li>FAR makes 100% looking like in 240dpi</li> + * <li>MEDIUM makes 100% looking like in 160dpi</li> + * <li>CLOSE makes 100% looking like in 120dpi</li> + * </ul> */ public enum ZoomDensity { FAR(150), // 240dpi @@ -87,24 +94,24 @@ public abstract class WebSettings { } /** - * Default cache usage pattern Use with {@link #setCacheMode}. + * Default cache usage pattern. Use with {@link #setCacheMode}. */ public static final int LOAD_DEFAULT = -1; /** - * Normal cache usage pattern Use with {@link #setCacheMode}. + * Normal cache usage pattern. Use with {@link #setCacheMode}. */ public static final int LOAD_NORMAL = 0; /** - * Use cache if content is there, even if expired (eg, history nav) + * Use cache if content is there, even if expired (eg, history nav). * If it is not in the cache, load from network. * Use with {@link #setCacheMode}. */ public static final int LOAD_CACHE_ELSE_NETWORK = 1; /** - * Don't use the cache, load from network + * Don't use the cache, load from network. * Use with {@link #setCacheMode}. */ public static final int LOAD_NO_CACHE = 2; @@ -139,6 +146,7 @@ public abstract class WebSettings { /** * Hidden constructor to prevent clients from creating a new settings * instance or deriving the class. + * * @hide */ protected WebSettings() { @@ -146,6 +154,7 @@ public abstract class WebSettings { /** * Enables dumping the pages navigation cache to a text file. + * * @deprecated This method is now obsolete. */ @Deprecated @@ -154,7 +163,8 @@ public abstract class WebSettings { } /** - * Returns true if dumping the navigation cache is enabled. + * Gets whether dumping the navigation cache is enabled. + * * @deprecated This method is now obsolete. */ @Deprecated @@ -167,16 +177,19 @@ public abstract class WebSettings { * controls and gestures. The particular zoom mechanisms that should be used * can be set with {@link #setBuiltInZoomControls}. This setting does not * affect zooming performed using the {@link WebView#zoomIn()} and - * {@link WebView#zoomOut()} methods. - * @param support Whether the WebView should support zoom. + * {@link WebView#zoomOut()} methods. The default is true. + * + * @param support whether the WebView should support zoom */ public void setSupportZoom(boolean support) { throw new MustOverrideException(); } /** - * Returns true if the WebView supports zoom. The default is true. - * @return True if the WebView supports zoom. + * Gets whether the WebView supports zoom. + * + * @return true if the WebView supports zoom + * @see #setSupportZoom */ public boolean supportZoom() { throw new MustOverrideException(); @@ -187,11 +200,12 @@ public abstract class WebSettings { * built-in zoom mechanisms comprise on-screen zoom controls, which are * displayed over the WebView's content, and the use of a pinch gesture to * control zooming. Whether or not these on-screen controls are displayed - * can be set with {@link #setDisplayZoomControls}. + * can be set with {@link #setDisplayZoomControls}. The default is false. * <p> * The built-in mechanisms are the only currently supported zoom * mechanisms, so it is recommended that this setting is always enabled. - * @param enabled Whether the WebView should use its built-in zoom mechanisms. + * + * @param enabled whether the WebView should use its built-in zoom mechanisms */ // This method was intended to select between the built-in zoom mechanisms // and the separate zoom controls. The latter were obtained using @@ -201,9 +215,10 @@ public abstract class WebSettings { } /** - * Returns true if the zoom mechanisms built into WebView are being used. - * The default is false. - * @return True if the zoom mechanisms built into WebView are being used. + * Gets whether the zoom mechanisms built into WebView are being used. + * + * @return true if the zoom mechanisms built into WebView are being used + * @see #setBuiltInZoomControls */ public boolean getBuiltInZoomControls() { throw new MustOverrideException(); @@ -212,24 +227,28 @@ public abstract class WebSettings { /** * Sets whether the WebView should display on-screen zoom controls when * using the built-in zoom mechanisms. See {@link #setBuiltInZoomControls}. - * @param enabled Whether the WebView should display on-screen zoom controls. + * The default is true. + * + * @param enabled whether the WebView should display on-screen zoom controls */ public void setDisplayZoomControls(boolean enabled) { throw new MustOverrideException(); } /** - * Returns true if the WebView displays on-screen zoom controls when using - * the built-in zoom mechanisms. The default is true. - * @return True if the WebView displays on-screen zoom controls when using + * Gets whether the WebView displays on-screen zoom controls when using * the built-in zoom mechanisms. + * + * @return true if the WebView displays on-screen zoom controls when using + * the built-in zoom mechanisms + * @see #setDisplayZoomControls */ public boolean getDisplayZoomControls() { throw new MustOverrideException(); } /** - * Enable or disable file access within WebView. File access is enabled by + * Enables or disables file access within WebView. File access is enabled by * default. Note that this enables or disables file system access only. * Assets and resources are still accessible using file:///android_asset and * file:///android_res. @@ -239,44 +258,48 @@ public abstract class WebSettings { } /** - * Returns true if this WebView supports file access. + * Gets whether this WebView supports file access. + * + * @see #setAllowFileAccess */ public boolean getAllowFileAccess() { throw new MustOverrideException(); } /** - * Enable or disable content url access within WebView. Content url access - * allows WebView to load content from a content provider installed in the - * system. The default is enabled. + * Enables or disables content URL access within WebView. Content URL + * access allows WebView to load content from a content provider installed + * in the system. The default is enabled. */ public void setAllowContentAccess(boolean allow) { throw new MustOverrideException(); } /** - * Returns true if this WebView supports content url access. + * Gets whether this WebView supports content URL access. + * + * @see #setAllowContentAccess */ public boolean getAllowContentAccess() { throw new MustOverrideException(); } /** - * Set whether the WebView loads a page with overview mode. + * Sets whether the WebView loads a page with overview mode. */ public void setLoadWithOverviewMode(boolean overview) { throw new MustOverrideException(); } /** - * Returns true if this WebView loads page with overview mode + * Gets whether this WebView loads pages with overview mode. */ public boolean getLoadWithOverviewMode() { throw new MustOverrideException(); } /** - * Set whether the WebView will enable smooth transition while panning or + * Sets whether the WebView will enable smooth transition while panning or * zooming or while the window hosting the WebView does not have focus. * If it is true, WebView will choose a solution to maximize the performance. * e.g. the WebView's content may not be updated during the transition. @@ -285,18 +308,22 @@ public abstract class WebSettings { public void setEnableSmoothTransition(boolean enable) { throw new MustOverrideException(); } + /** - * Returns true if the WebView enables smooth transition while panning or + * Gets whether the WebView enables smooth transition while panning or * zooming. + * + * @see #setEnableSmoothTransition */ public boolean enableSmoothTransition() { throw new MustOverrideException(); } /** - * Set whether the WebView uses its background for over scroll background. + * Sets whether the WebView uses its background for over scroll background. * If true, it will use the WebView's background. If false, it will use an * internal pattern. Default is true. + * * @deprecated This method is now obsolete. */ @Deprecated @@ -305,8 +332,10 @@ public abstract class WebSettings { } /** - * Returns true if this WebView uses WebView's background instead of + * Gets whether this WebView uses WebView's background instead of * internal pattern for over scroll background. + * + * @see #setUseWebViewBackgroundForOverscrollBackground * @deprecated This method is now obsolete. */ @Deprecated @@ -315,77 +344,82 @@ public abstract class WebSettings { } /** - * Store whether the WebView is saving form data. + * Sets whether the WebView is saving form data. */ public void setSaveFormData(boolean save) { throw new MustOverrideException(); } /** - * Return whether the WebView is saving form data and displaying prior - * entries/autofill++. Always false in private browsing mode. + * Gets whether the WebView is saving form data and displaying prior + * entries/autofill++. Always false in private browsing mode. */ public boolean getSaveFormData() { throw new MustOverrideException(); } /** - * Store whether the WebView is saving password. + * Stores whether the WebView is saving password. */ public void setSavePassword(boolean save) { throw new MustOverrideException(); } /** - * Return whether the WebView is saving password. + * Gets whether the WebView is saving password. */ public boolean getSavePassword() { throw new MustOverrideException(); } /** - * Set the text zoom of the page in percent. Default is 100. - * @param textZoom A percent value for increasing or decreasing the text. + * Sets the text zoom of the page in percent. Default is 100. + * + * @param textZoom the percent value for increasing or decreasing the text */ public synchronized void setTextZoom(int textZoom) { throw new MustOverrideException(); } /** - * Get the text zoom of the page in percent. - * @return A percent value describing the text zoom. - * @see setTextSizeZoom + * Gets the text zoom of the page in percent. + * + * @return a percent value describing the text zoom + * @see #setTextSizeZoom */ public synchronized int getTextZoom() { throw new MustOverrideException(); } /** - * Set the text size of the page. - * @param t A TextSize value for increasing or decreasing the text. + * Sets the text size of the page. + * + * @param t the TextSize value for increasing or decreasing the text * @see WebSettings.TextSize - * @deprecated Use {@link #setTextZoom(int)} instead + * @deprecated Use {@link #setTextZoom(int)} instead. */ public synchronized void setTextSize(TextSize t) { throw new MustOverrideException(); } /** - * Get the text size of the page. If the text size was previously specified + * Gets the text size of the page. If the text size was previously specified * in percent using {@link #setTextZoom(int)}, this will return * the closest matching {@link TextSize}. - * @return A TextSize enum value describing the text size. + * + * @return a TextSize enum value describing the text size * @see WebSettings.TextSize - * @deprecated Use {@link #getTextZoom()} instead + * @deprecated Use {@link #getTextZoom()} instead. */ public synchronized TextSize getTextSize() { throw new MustOverrideException(); } /** - * Set the default zoom density of the page. This should be called from UI + * Sets the default zoom density of the page. This should be called from UI * thread. - * @param zoom A ZoomDensity value + * + * @param zoom a ZoomDensity value * @see WebSettings.ZoomDensity */ public void setDefaultZoom(ZoomDensity zoom) { @@ -393,9 +427,9 @@ public abstract class WebSettings { } /** - * Get the default zoom density of the page. This should be called from UI + * Gets the default zoom density of the page. This should be called from UI * thread. - * @return A ZoomDensity value + * @return a ZoomDensity value * @see WebSettings.ZoomDensity */ public ZoomDensity getDefaultZoom() { @@ -410,15 +444,17 @@ public abstract class WebSettings { } /** - * Returns true if light touches are enabled. + * Gets whether light touches are enabled. */ public boolean getLightTouchEnabled() { throw new MustOverrideException(); } /** - * @deprecated This setting controlled a rendering optimization - * that is no longer present. Setting it now has no effect. + * Controlled a rendering optimization that is no longer present. Setting + * it now has no effect. + * + * @deprecated This setting now has no effect. */ @Deprecated public synchronized void setUseDoubleTree(boolean use) { @@ -426,8 +462,10 @@ public abstract class WebSettings { } /** - * @deprecated This setting controlled a rendering optimization - * that is no longer present. Setting it now has no effect. + * Controlled a rendering optimization that is no longer present. Setting + * it now has no effect. + * + * @deprecated This setting now has no effect. */ @Deprecated public synchronized boolean getUseDoubleTree() { @@ -436,10 +474,10 @@ public abstract class WebSettings { } /** - * Tell the WebView about user-agent string. - * @param ua 0 if the WebView should use an Android user-agent string, - * 1 if the WebView should use a desktop user-agent string. + * Tells the WebView about user-agent string. * + * @param ua 0 if the WebView should use an Android user-agent string, + * 1 if the WebView should use a desktop user-agent string * @deprecated Please use setUserAgentString instead. */ @Deprecated @@ -448,11 +486,11 @@ public abstract class WebSettings { } /** - * Return user-agent as int - * @return int 0 if the WebView is using an Android user-agent string. - * 1 if the WebView is using a desktop user-agent string. - * -1 if the WebView is using user defined user-agent string. + * Gets the user-agent as an int. * + * @return 0 if the WebView is using an Android user-agent string, + * 1 if the WebView is using a desktop user-agent string, + * -1 if the WebView is using user defined user-agent string * @deprecated Please use getUserAgentString instead. */ @Deprecated @@ -461,30 +499,34 @@ public abstract class WebSettings { } /** - * Tell the WebView to use the wide viewport + * Tells the WebView to use the wide viewport. */ public synchronized void setUseWideViewPort(boolean use) { throw new MustOverrideException(); } /** - * @return True if the WebView is using a wide viewport + * Gets whether the WebView is using a wide viewport. + * + * @return true if the WebView is using a wide viewport */ public synchronized boolean getUseWideViewPort() { throw new MustOverrideException(); } /** - * Tell the WebView whether it supports multiple windows. TRUE means - * that {@link WebChromeClient#onCreateWindow(WebView, boolean, - * boolean, Message)} is implemented by the host application. + * Tells the WebView whether it supports multiple windows. TRUE means + * that {@link WebChromeClient#onCreateWindow(WebView, boolean, + * boolean, Message)} is implemented by the host application. */ public synchronized void setSupportMultipleWindows(boolean support) { throw new MustOverrideException(); } /** - * @return True if the WebView is supporting multiple windows. This means + * Gets whether the WebView is supporting multiple windows. + * + * @return true if the WebView is supporting multiple windows. This means * that {@link WebChromeClient#onCreateWindow(WebView, boolean, * boolean, Message)} is implemented by the host application. */ @@ -493,9 +535,10 @@ public abstract class WebSettings { } /** - * Set the underlying layout algorithm. This will cause a relayout of the - * WebView. - * @param l A LayoutAlgorithm enum specifying the algorithm to use. + * Sets the underlying layout algorithm. This will cause a relayout of the + * WebView. The default is NARROW_COLUMNS. + * + * @param l a LayoutAlgorithm enum specifying the algorithm to use * @see WebSettings.LayoutAlgorithm */ public synchronized void setLayoutAlgorithm(LayoutAlgorithm l) { @@ -503,9 +546,11 @@ public abstract class WebSettings { } /** - * Return the current layout algorithm. The default is NARROW_COLUMNS. - * @return LayoutAlgorithm enum value describing the layout algorithm - * being used. + * Gets the current layout algorithm. + * + * @return a LayoutAlgorithm enum value describing the layout algorithm + * being used + * @see #setLayoutAlgorithm * @see WebSettings.LayoutAlgorithm */ public synchronized LayoutAlgorithm getLayoutAlgorithm() { @@ -513,164 +558,193 @@ public abstract class WebSettings { } /** - * Set the standard font family name. - * @param font A font family name. + * Sets the standard font family name. The default is "sans-serif". + * + * @param font a font family name */ public synchronized void setStandardFontFamily(String font) { throw new MustOverrideException(); } /** - * Get the standard font family name. The default is "sans-serif". - * @return The standard font family name as a string. + * Gets the standard font family name. + * + * @return the standard font family name as a string + * @see #setStandardFontFamily */ public synchronized String getStandardFontFamily() { throw new MustOverrideException(); } /** - * Set the fixed font family name. - * @param font A font family name. + * Sets the fixed font family name. The default is "monospace". + * + * @param font a font family name */ public synchronized void setFixedFontFamily(String font) { throw new MustOverrideException(); } /** - * Get the fixed font family name. The default is "monospace". - * @return The fixed font family name as a string. + * Gets the fixed font family name. + * + * @return the fixed font family name as a string + * @see #setFixedFontFamily */ public synchronized String getFixedFontFamily() { throw new MustOverrideException(); } /** - * Set the sans-serif font family name. - * @param font A font family name. + * Sets the sans-serif font family name. + * + * @param font a font family name */ public synchronized void setSansSerifFontFamily(String font) { throw new MustOverrideException(); } /** - * Get the sans-serif font family name. - * @return The sans-serif font family name as a string. + * Gets the sans-serif font family name. + * + * @return the sans-serif font family name as a string */ public synchronized String getSansSerifFontFamily() { throw new MustOverrideException(); } /** - * Set the serif font family name. The default is "sans-serif". - * @param font A font family name. + * Sets the serif font family name. The default is "sans-serif". + * + * @param font a font family name */ public synchronized void setSerifFontFamily(String font) { throw new MustOverrideException(); } /** - * Get the serif font family name. The default is "serif". - * @return The serif font family name as a string. + * Gets the serif font family name. The default is "serif". + * + * @return the serif font family name as a string + * @see #setSerifFontFamily */ public synchronized String getSerifFontFamily() { throw new MustOverrideException(); } /** - * Set the cursive font family name. - * @param font A font family name. + * Sets the cursive font family name. The default is "cursive". + * + * @param font a font family name */ public synchronized void setCursiveFontFamily(String font) { throw new MustOverrideException(); } /** - * Get the cursive font family name. The default is "cursive". - * @return The cursive font family name as a string. + * Gets the cursive font family name. + * + * @return the cursive font family name as a string + * @see #setCursiveFontFamily */ public synchronized String getCursiveFontFamily() { throw new MustOverrideException(); } /** - * Set the fantasy font family name. - * @param font A font family name. + * Sets the fantasy font family name. The default is "fantasy". + * + * @param font a font family name */ public synchronized void setFantasyFontFamily(String font) { throw new MustOverrideException(); } /** - * Get the fantasy font family name. The default is "fantasy". - * @return The fantasy font family name as a string. + * Gets the fantasy font family name. + * + * @return the fantasy font family name as a string + * @see #setFantasyFontFamily */ public synchronized String getFantasyFontFamily() { throw new MustOverrideException(); } /** - * Set the minimum font size. - * @param size A non-negative integer between 1 and 72. - * Any number outside the specified range will be pinned. + * Sets the minimum font size. The default is 8. + * + * @param size a non-negative integer between 1 and 72. Any number outside + * the specified range will be pinned. */ public synchronized void setMinimumFontSize(int size) { throw new MustOverrideException(); } /** - * Get the minimum font size. The default is 8. - * @return A non-negative integer between 1 and 72. + * Gets the minimum font size. + * + * @return a non-negative integer between 1 and 72 + * @see #setMinimumFontSize */ public synchronized int getMinimumFontSize() { throw new MustOverrideException(); } /** - * Set the minimum logical font size. - * @param size A non-negative integer between 1 and 72. - * Any number outside the specified range will be pinned. + * Sets the minimum logical font size. The default is 8. + * + * @param size a non-negative integer between 1 and 72. Any number outside + * the specified range will be pinned. */ public synchronized void setMinimumLogicalFontSize(int size) { throw new MustOverrideException(); } /** - * Get the minimum logical font size. The default is 8. - * @return A non-negative integer between 1 and 72. + * Gets the minimum logical font size. + * + * @return a non-negative integer between 1 and 72 + * @see #setMinimumLogicalFontSize */ public synchronized int getMinimumLogicalFontSize() { throw new MustOverrideException(); } /** - * Set the default font size. - * @param size A non-negative integer between 1 and 72. - * Any number outside the specified range will be pinned. + * Sets the default font size. The default is 16. + * + * @param size a non-negative integer between 1 and 72. Any number outside + * the specified range will be pinned. */ public synchronized void setDefaultFontSize(int size) { throw new MustOverrideException(); } /** - * Get the default font size. The default is 16. - * @return A non-negative integer between 1 and 72. + * Gets the default font size. + * + * @return a non-negative integer between 1 and 72 + * @see #setDefaultFontSize */ public synchronized int getDefaultFontSize() { throw new MustOverrideException(); } /** - * Set the default fixed font size. - * @param size A non-negative integer between 1 and 72. - * Any number outside the specified range will be pinned. + * Sets the default fixed font size. The default is 16. + * + * @param size a non-negative integer between 1 and 72. Any number outside + * the specified range will be pinned. */ public synchronized void setDefaultFixedFontSize(int size) { throw new MustOverrideException(); } /** - * Get the default fixed font size. The default is 16. - * @return A non-negative integer between 1 and 72. + * Gets the default fixed font size. + * + * @return a non-negative integer between 1 and 72 + * @see #setDefaultFixedFontSize */ public synchronized int getDefaultFixedFontSize() { throw new MustOverrideException(); @@ -683,16 +757,20 @@ public abstract class WebSettings { * of images specified using network URI schemes. Note that if the value of this * setting is changed from false to true, all images resources referenced * by content currently displayed by the WebView are loaded automatically. - * @param flag Whether the WebView should load image resources. + * The default is true. + * + * @param flag whether the WebView should load image resources */ public synchronized void setLoadsImagesAutomatically(boolean flag) { throw new MustOverrideException(); } /** - * Returns true if the WebView loads image resources. This includes - * images embedded using the data URI scheme. The default is true. - * @return True if the WebView loads image resources. + * Gets whether the WebView loads image resources. This includes + * images embedded using the data URI scheme. + * + * @return true if the WebView loads image resources + * @see #setLoadsImagesAutomatically */ public synchronized boolean getLoadsImagesAutomatically() { throw new MustOverrideException(); @@ -707,9 +785,10 @@ public abstract class WebSettings { * will also prevent network images from loading, even if this flag is set * to false. When the value of this setting is changed from true to false, * network images resources referenced by content currently displayed by - * the WebView are fetched automatically. - * @param flag Whether the WebView should not load image resources from - * the network. + * the WebView are fetched automatically. The default is false. + * + * @param flag whether the WebView should not load image resources from the + * network * @see #setBlockNetworkLoads */ public synchronized void setBlockNetworkImage(boolean flag) { @@ -717,9 +796,10 @@ public abstract class WebSettings { } /** - * Returns true if the WebView does not load image resources from the network. - * The default is false. - * @return True if the WebView does not load image resources from the network. + * Gets whether the WebView does not load image resources from the network. + * + * @return true if the WebView does not load image resources from the network + * @see #setBlockNetworkImage */ public synchronized boolean getBlockNetworkImage() { throw new MustOverrideException(); @@ -735,9 +815,12 @@ public abstract class WebSettings { * If the application does not have the * {@link android.Manifest.permission#INTERNET} permission, attempts to set * a value of false will cause a {@link java.lang.SecurityException} - * to be thrown. - * @param flag Whether the WebView should not load any resources - * from the network. + * to be thrown. The default value is false if the application has the + * {@link android.Manifest.permission#INTERNET} permission, otherwise it is + * true. + * + * @param flag whether the WebView should not load any resources from the + * network * @see android.webkit.WebView#reload */ public synchronized void setBlockNetworkLoads(boolean flag) { @@ -745,50 +828,52 @@ public abstract class WebSettings { } /** - * Returns true if the WebView does not load any resources from the network. - * The default value is false if the application has the - * {@link android.Manifest.permission#INTERNET} permission, otherwise it is - * true. - * @return True if the WebView does not load any resources from the network. + * Gets whether the WebView does not load any resources from the network. + * + * @return true if the WebView does not load any resources from the network + * @see #setBlockNetworkLoads */ public synchronized boolean getBlockNetworkLoads() { throw new MustOverrideException(); } /** - * Tell the WebView to enable javascript execution. - * @param flag True if the WebView should execute javascript. + * Tells the WebView to enable JavaScript execution. + * <b>The default is false.</b> + * + * @param flag true if the WebView should execute JavaScript */ public synchronized void setJavaScriptEnabled(boolean flag) { throw new MustOverrideException(); } /** - * Configure scripting (such as XmlHttpRequest) access from file scheme URLs + * Configures scripting (such as XmlHttpRequest) access from file scheme URLs * to any origin. Note, calling this method with a true argument value also * implies calling setAllowFileAccessFromFileURLs with a true. The default * value is false for API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN} * and higher and true otherwise. * - . * @param flag True if the WebView should allow scripting access from file - * scheme URLs to any origin + * @param flag true if the WebView should allow scripting access from file + * scheme URLs to any origin */ public abstract void setAllowUniversalAccessFromFileURLs(boolean flag); /** - * Configure scripting (such as XmlHttpRequest) access from file scheme URLs + * Configures scripting (such as XmlHttpRequest) access from file scheme URLs * to file origin. The default value is false for API level * {@link android.os.Build.VERSION_CODES#JELLY_BEAN} and higher and true * otherwise. * - * @param flag True if the WebView should allow scripting access from file - * scheme URLs to file origin + * @param flag true if the WebView should allow scripting access from file + * scheme URLs to file origin */ public abstract void setAllowFileAccessFromFileURLs(boolean flag); /** - * Tell the WebView to enable plugins. - * @param flag True if the WebView should load plugins. + * Tells the WebView to enable plugins. + * + * @param flag true if the WebView should load plugins * @deprecated This method has been deprecated in favor of * {@link #setPluginState} */ @@ -798,22 +883,24 @@ public abstract class WebSettings { } /** - * Tell the WebView to enable, disable, or have plugins on demand. On + * Tells the WebView to enable, disable, or have plugins on demand. On * demand mode means that if a plugin exists that can handle the embedded * content, a placeholder icon will be shown instead of the plugin. When * the placeholder is clicked, the plugin will be enabled. - * @param state One of the PluginState values. + * + * @param state a PluginState value */ public synchronized void setPluginState(PluginState state) { throw new MustOverrideException(); } /** - * Set a custom path to plugins used by the WebView. This method is + * Sets a custom path to plugins used by the WebView. This method is * obsolete since each plugin is now loaded from its own package. - * @param pluginsPath String path to the directory containing plugins. + * + * @param pluginsPath a String path to the directory containing plugins * @deprecated This method is no longer used as plugins are loaded from - * their own APK via the system's package manager. + * their own APK via the system's package manager. */ @Deprecated public synchronized void setPluginsPath(String pluginsPath) { @@ -821,91 +908,101 @@ public abstract class WebSettings { } /** - * Set the path to where database storage API databases should be saved. - * Nota that the WebCore Database Tracker only allows the path to be set once. - * This will update WebCore when the Sync runs in the C++ side. - * @param databasePath String path to the directory where databases should - * be saved. May be the empty string but should never be null. + * Sets the path to where database storage API databases should be saved. + * Note that the WebCore Database Tracker only allows the path to be set once. + * + * @param databasePath a String path to the directory where databases should + * be saved. May be the empty string but should never + * be null. */ + // This will update WebCore when the Sync runs in the C++ side. public synchronized void setDatabasePath(String databasePath) { throw new MustOverrideException(); } /** - * Set the path where the Geolocation permissions database should be saved. - * This will update WebCore when the Sync runs in the C++ side. - * @param databasePath String path to the directory where the Geolocation - * permissions database should be saved. May be the empty string but - * should never be null. + * Sets the path where the Geolocation permissions database should be saved. + * + * @param databasePath a String path to the directory where the Geolocation + * permissions database should be saved. May be the + * empty string but should never be null. */ + // This will update WebCore when the Sync runs in the C++ side. public synchronized void setGeolocationDatabasePath(String databasePath) { throw new MustOverrideException(); } /** - * Tell the WebView to enable Application Caches API. - * @param flag True if the WebView should enable Application Caches. + * Tells the WebView to enable Application Caches API. + * + * @param flag true if the WebView should enable Application Caches */ public synchronized void setAppCacheEnabled(boolean flag) { throw new MustOverrideException(); } /** - * Set a custom path to the Application Caches files. The client + * Sets a custom path to the Application Caches files. The client * must ensure it exists before this call. - * @param appCachePath String path to the directory containing Application - * Caches files. The appCache path can be the empty string but should not - * be null. Passing null for this parameter will result in a no-op. + * + * @param appCachePath a String path to the directory containing + * Application Caches files. The appCache path can be + * the empty string but should not be null. Passing + * null for this parameter will result in a no-op. */ public synchronized void setAppCachePath(String appCachePath) { throw new MustOverrideException(); } /** - * Set the maximum size for the Application Caches content. - * @param appCacheMaxSize the maximum size in bytes. + * Sets the maximum size for the Application Caches content. + * + * @param appCacheMaxSize the maximum size in bytes */ public synchronized void setAppCacheMaxSize(long appCacheMaxSize) { throw new MustOverrideException(); } /** - * Set whether the database storage API is enabled. - * @param flag boolean True if the WebView should use the database storage - * API. + * Sets whether the database storage API is enabled. + * + * @param flag true if the WebView should use the database storage API */ public synchronized void setDatabaseEnabled(boolean flag) { throw new MustOverrideException(); } /** - * Set whether the DOM storage API is enabled. - * @param flag boolean True if the WebView should use the DOM storage - * API. + * Sets whether the DOM storage API is enabled. + * + * @param flag true if the WebView should use the DOM storage API */ public synchronized void setDomStorageEnabled(boolean flag) { throw new MustOverrideException(); } /** - * Returns true if the DOM Storage API's are enabled. - * @return True if the DOM Storage API's are enabled. + * Gets whether the DOM Storage APIs are enabled. + * + * @return true if the DOM Storage APIs are enabled */ public synchronized boolean getDomStorageEnabled() { throw new MustOverrideException(); } /** - * Return the path to where database storage API databases are saved for + * Gets the path to where database storage API databases are saved for * the current WebView. - * @return the String path to the database storage API databases. + * + * @return the String path to the database storage API databases */ public synchronized String getDatabasePath() { throw new MustOverrideException(); } /** - * Returns true if database storage API is enabled. - * @return True if the database storage API is enabled. + * Gets whether the database storage API is enabled. + * + * @return true if the database storage API is enabled */ public synchronized boolean getDatabaseEnabled() { throw new MustOverrideException(); @@ -913,43 +1010,47 @@ public abstract class WebSettings { /** * Sets whether Geolocation is enabled. - * @param flag Whether Geolocation should be enabled. + * + * @param flag whether Geolocation should be enabled */ public synchronized void setGeolocationEnabled(boolean flag) { throw new MustOverrideException(); } /** - * Return true if javascript is enabled. <b>Note: The default is false.</b> - * @return True if javascript is enabled. + * Gets whether JavaScript is enabled. + * + * @return true if JavaScript is enabled + * @see #setJavaScriptEnabled */ public synchronized boolean getJavaScriptEnabled() { throw new MustOverrideException(); } /** - * Return true if scripting access {see @setAllowUniversalAccessFromFileURLs} from - * file URLs to any origin is enabled. The default value is false for API level - * {@link android.os.Build.VERSION_CODES#JELLY_BEAN} and higher and true otherwise. + * Gets whether scripting access {see @setAllowUniversalAccessFromFileURLs} from + * file URLs to any origin is enabled. * - * @return True if the WebView allows scripting access from file scheme requests - * to any origin + * @return true if the WebView allows scripting access from file scheme requests + * to any origin + * @see #setAllowUniversalAccessFromFileURLs */ public abstract boolean getAllowUniversalAccessFromFileURLs(); /** - * Return true if scripting access {see @setAllowFileAccessFromFileURLs} from file - * URLs to file origin is enabled. The default value is false for API level - * {@link android.os.Build.VERSION_CODES#JELLY_BEAN} and higher, and true otherwise. + * Gets whether scripting access {see @setAllowFileAccessFromFileURLs} from file + * URLs to file origin is enabled. * - * @return True if the WebView allows scripting access from file scheme requests - * to file origin + * @return true if the WebView allows scripting access from file scheme requests + * to file origin + * @see #setAllowFileAccessFromFileURLs */ public abstract boolean getAllowFileAccessFromFileURLs(); /** - * Return true if plugins are enabled. - * @return True if plugins are enabled. + * Gets whether plugins are enabled. + * + * @return true if plugins are enabled * @deprecated This method has been replaced by {@link #getPluginState} */ @Deprecated @@ -958,17 +1059,19 @@ public abstract class WebSettings { } /** - * Return the current plugin state. - * @return A value corresponding to the enum PluginState. + * Gets the current plugin state. + * + * @return a value corresponding to the enum PluginState */ public synchronized PluginState getPluginState() { throw new MustOverrideException(); } /** - * Returns the directory that contains the plugin libraries. This method is + * Gets the directory that contains the plugin libraries. This method is * obsolete since each plugin is now loaded from its own package. - * @return An empty string. + * + * @return an empty string * @deprecated This method is no longer used as plugins are loaded from * their own APK via the system's package manager. */ @@ -979,41 +1082,47 @@ public abstract class WebSettings { } /** - * Tell javascript to open windows automatically. This applies to the - * javascript function window.open(). - * @param flag True if javascript can open windows automatically. + * Tells JavaScript to open windows automatically. This applies to the + * JavaScript function window.open(). The default is false. + * + * @param flag true if JavaScript can open windows automatically */ public synchronized void setJavaScriptCanOpenWindowsAutomatically(boolean flag) { throw new MustOverrideException(); } /** - * Return true if javascript can open windows automatically. The default - * is false. - * @return True if javascript can open windows automatically during - * window.open(). + * Gets whether JavaScript can open windows automatically. + * + * @return true if JavaScript can open windows automatically during + * window.open() + * @see #setJavaScriptCanOpenWindowsAutomatically */ public synchronized boolean getJavaScriptCanOpenWindowsAutomatically() { throw new MustOverrideException(); } /** - * Set the default text encoding name to use when decoding html pages. - * @param encoding The text encoding name. + * Sets the default text encoding name to use when decoding html pages. + * The default is "Latin-1". + * + * @param encoding the text encoding name */ public synchronized void setDefaultTextEncodingName(String encoding) { throw new MustOverrideException(); } /** - * Get the default text encoding name. The default is "Latin-1". - * @return The default text encoding name as a string. + * Gets the default text encoding name. + * + * @return the default text encoding name as a string + * @see #setDefaultTextEncodingName */ public synchronized String getDefaultTextEncodingName() { throw new MustOverrideException(); } /** - * Set the WebView's user-agent string. If the string "ua" is null or empty, + * Sets the WebView's user-agent string. If the string "ua" is null or empty, * it will use the system default user-agent string. */ public synchronized void setUserAgentString(String ua) { @@ -1021,46 +1130,47 @@ public abstract class WebSettings { } /** - * Return the WebView's user-agent string. + * Gets the WebView's user-agent string. */ public synchronized String getUserAgentString() { throw new MustOverrideException(); } /** - * Tell the WebView whether it needs to set a node to have focus when + * Tells the WebView whether it needs to set a node to have focus when * {@link WebView#requestFocus(int, android.graphics.Rect)} is called. * - * @param flag + * @param flag whether the WebView needs to set a node */ public void setNeedInitialFocus(boolean flag) { throw new MustOverrideException(); } /** - * Set the priority of the Render thread. Unlike the other settings, this + * Sets the priority of the Render thread. Unlike the other settings, this * one only needs to be called once per process. The default is NORMAL. * - * @param priority RenderPriority, can be normal, high or low. + * @param priority a RenderPriority */ public synchronized void setRenderPriority(RenderPriority priority) { throw new MustOverrideException(); } /** - * Override the way the cache is used. The way the cache is used is based + * Overrides the way the cache is used. The way the cache is used is based * on the navigation option. For a normal page load, the cache is checked * and content is re-validated as needed. When navigating back, content is * not revalidated, instead the content is just pulled from the cache. * This function allows the client to override this behavior. - * @param mode One of the LOAD_ values. + * + * @param mode one of the LOAD_ values */ public void setCacheMode(int mode) { throw new MustOverrideException(); } /** - * Return the current setting for overriding the cache mode. For a full + * Gets the current setting for overriding the cache mode. For a full * description, see the {@link #setCacheMode(int)} function. */ public int getCacheMode() { diff --git a/core/java/android/webkit/WebStorage.java b/core/java/android/webkit/WebStorage.java index c46d16122bfd..76674f42194b 100644 --- a/core/java/android/webkit/WebStorage.java +++ b/core/java/android/webkit/WebStorage.java @@ -44,8 +44,9 @@ public class WebStorage { // otherwise the WebCore thread will remain asleep. public interface QuotaUpdater { /** - * Provide a new quota, specified in bytes. - * @param newQuota The new quota, in bytes + * Provides a new quota, specified in bytes. + * + * @param newQuota the new quota, in bytes */ public void updateQuota(long newQuota); }; @@ -79,8 +80,9 @@ public class WebStorage { } /** - * Get the string representation of this origin. - * @return The string representation of this origin + * Gets the string representation of this origin. + * + * @return the string representation of this origin */ // An origin string is created using WebCore::SecurityOrigin::toString(). // Note that WebCore::SecurityOrigin uses 0 (which is not printed) for @@ -92,19 +94,21 @@ public class WebStorage { } /** - * Get the quota for this origin, for the Web SQL Database API, in + * Gets the quota for this origin, for the Web SQL Database API, in * bytes. If this origin does not use the Web SQL Database API, this * quota will be set to zero. - * @return The quota, in bytes. + * + * @return the quota, in bytes */ public long getQuota() { return mQuota; } /** - * Get the total amount of storage currently being used by this origin, + * Gets the total amount of storage currently being used by this origin, * for all JavaScript storage APIs, in bytes. - * @return The total amount of storage, in bytes. + * + * @return the total amount of storage, in bytes */ public long getUsage() { return mUsage; @@ -124,7 +128,7 @@ public class WebStorage { */ /** - * Get the origins currently using either the Application Cache or Web SQL + * Gets the origins currently using either the Application Cache or Web SQL * Database APIs. This method operates asynchronously, with the result * being provided via a {@link ValueCallback}. The origins are provided as * a map, of type {@code Map<String, WebStorage.Origin>}, from the string @@ -135,7 +139,7 @@ public class WebStorage { } /** - * Get the amount of storage currently being used by both the Application + * Gets the amount of storage currently being used by both the Application * Cache and Web SQL Database APIs by the given origin. The amount is given * in bytes and the origin is specified using its string representation. * This method operates asynchronously, with the result being provided via @@ -146,7 +150,7 @@ public class WebStorage { } /** - * Get the storage quota for the Web SQL Database API for the given origin. + * Gets the storage quota for the Web SQL Database API for the given origin. * The quota is given in bytes and the origin is specified using its string * representation. This method operates asynchronously, with the result * being provided via a {@link ValueCallback}. Note that a quota is not @@ -157,7 +161,7 @@ public class WebStorage { } /** - * Set the storage quota for the Web SQL Database API for the given origin. + * Sets the storage quota for the Web SQL Database API for the given origin. * The quota is specified in bytes and the origin is specified using its string * representation. Note that a quota is not enforced on a per-origin basis * for the Application Cache API. @@ -167,7 +171,7 @@ public class WebStorage { } /** - * Clear the storage currently being used by both the Application Cache and + * Clears the storage currently being used by both the Application Cache and * Web SQL Database APIs by the given origin. The origin is specified using * its string representation. */ @@ -176,7 +180,7 @@ public class WebStorage { } /** - * Clear all storage currently being used by the JavaScript storage APIs. + * Clears all storage currently being used by the JavaScript storage APIs. * This includes the Application Cache, Web SQL Database and the HTML5 Web * Storage APIs. */ @@ -185,8 +189,9 @@ public class WebStorage { } /** - * Get the singleton instance of this class. - * @return The singleton {@link WebStorage} instance. + * Gets the singleton instance of this class. + * + * @return the singleton {@link WebStorage} instance */ public static WebStorage getInstance() { return WebViewFactory.getProvider().getWebStorage(); diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index 74605e2d2a94..ba5a417529d1 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -274,16 +274,18 @@ public class WebView extends AbsoluteLayout private WebView mWebview; /** - * Set the WebView to the transportation object. - * @param webview The WebView to transport. + * Sets the WebView to the transportation object. + * + * @param webview the WebView to transport */ public synchronized void setWebView(WebView webview) { mWebview = webview; } /** - * Return the WebView object. - * @return WebView The transported WebView object. + * Gets the WebView object. + * + * @return the transported WebView object */ public synchronized WebView getWebView() { return mWebview; @@ -291,15 +293,15 @@ public class WebView extends AbsoluteLayout } /** - * URI scheme for telephone number + * URI scheme for telephone number. */ public static final String SCHEME_TEL = "tel:"; /** - * URI scheme for email address + * URI scheme for email address. */ public static final String SCHEME_MAILTO = "mailto:"; /** - * URI scheme for map address + * URI scheme for map address. */ public static final String SCHEME_GEO = "geo:0,0?q="; @@ -308,13 +310,15 @@ public class WebView extends AbsoluteLayout */ public interface FindListener { /** - * Notify the listener about progress made by a find operation. + * Notifies the listener about progress made by a find operation. * - * @param numberOfMatches How many matches have been found. - * @param activeMatchOrdinal The zero-based ordinal of the currently selected match. - * @param isDoneCounting Whether the find operation has actually completed. The listener - * may be notified multiple times while the operation is underway, and the numberOfMatches - * value should not be considered final unless isDoneCounting is true. + * @param numberOfMatches how many matches have been found + * @param activeMatchOrdinal the zero-based ordinal of the currently selected match + * @param isDoneCounting whether the find operation has actually completed. The listener + * may be notified multiple times while the + * operation is underway, and the numberOfMatches + * value should not be considered final unless + * isDoneCounting is true. */ public void onFindResultReceived(int numberOfMatches, int activeMatchOrdinal, boolean isDoneCounting); @@ -322,19 +326,22 @@ public class WebView extends AbsoluteLayout /** * Interface to listen for new pictures as they change. + * * @deprecated This interface is now obsolete. */ @Deprecated public interface PictureListener { /** - * Notify the listener that the picture has changed. - * @param view The WebView that owns the picture. - * @param picture The new picture. + * Notifies the listener that the picture has changed. + * + * @param view the WebView that owns the picture + * @param picture the new picture * @deprecated Due to internal changes, the picture does not include - * composited layers such as fixed position elements or scrollable divs. - * While the PictureListener API can still be used to detect changes in - * the WebView content, you are advised against its usage until a replacement - * is provided in a future Android release + * composited layers such as fixed position elements or + * scrollable divs. While the PictureListener API can still + * be used to detect changes in the WebView content, you + * are advised against its usage until a replacement is + * provided in a future Android release. */ @Deprecated public void onNewPicture(WebView view, Picture picture); @@ -342,7 +349,7 @@ public class WebView extends AbsoluteLayout public static class HitTestResult { /** - * Default HitTestResult, where the target is unknown + * Default HitTestResult, where the target is unknown. */ public static final int UNKNOWN_TYPE = 0; /** @@ -351,19 +358,19 @@ public class WebView extends AbsoluteLayout @Deprecated public static final int ANCHOR_TYPE = 1; /** - * HitTestResult for hitting a phone number + * HitTestResult for hitting a phone number. */ public static final int PHONE_TYPE = 2; /** - * HitTestResult for hitting a map address + * HitTestResult for hitting a map address. */ public static final int GEO_TYPE = 3; /** - * HitTestResult for hitting an email address + * HitTestResult for hitting an email address. */ public static final int EMAIL_TYPE = 4; /** - * HitTestResult for hitting an HTML::img tag + * HitTestResult for hitting an HTML::img tag. */ public static final int IMAGE_TYPE = 5; /** @@ -372,15 +379,15 @@ public class WebView extends AbsoluteLayout @Deprecated public static final int IMAGE_ANCHOR_TYPE = 6; /** - * HitTestResult for hitting a HTML::a tag with src=http + * HitTestResult for hitting a HTML::a tag with src=http. */ public static final int SRC_ANCHOR_TYPE = 7; /** - * HitTestResult for hitting a HTML::a tag with src=http + HTML::img + * HitTestResult for hitting a HTML::a tag with src=http + HTML::img. */ public static final int SRC_IMAGE_ANCHOR_TYPE = 8; /** - * HitTestResult for hitting an edit text area + * HitTestResult for hitting an edit text area. */ public static final int EDIT_TEXT_TYPE = 9; @@ -409,17 +416,21 @@ public class WebView extends AbsoluteLayout } /** - * Gets the type of the hit test result. - * @return See the XXX_TYPE constants defined in this class. + * Gets the type of the hit test result. See the XXX_TYPE constants + * defined in this class. + * + * @return the type of the hit test result */ public int getType() { return mType; } /** - * Gets additional type-dependant information about the result, see - * {@link WebView#getHitTestResult()} for details. - * @return may either be null or contain extra information about this result. + * Gets additional type-dependant information about the result. See + * {@link WebView#getHitTestResult()} for details. May either be null + * or contain extra information about this result. + * + * @return additional type-dependant information about the result */ public String getExtra() { return mExtra; @@ -427,38 +438,43 @@ public class WebView extends AbsoluteLayout } /** - * Construct a new WebView with a Context object. - * @param context A Context object used to access application assets. + * Constructs a new WebView with a Context object. + * + * @param context a Context object used to access application assets */ public WebView(Context context) { this(context, null); } /** - * Construct a new WebView with layout parameters. - * @param context A Context object used to access application assets. - * @param attrs An AttributeSet passed to our parent. + * Constructs a new WebView with layout parameters. + * + * @param context a Context object used to access application assets + * @param attrs an AttributeSet passed to our parent */ public WebView(Context context, AttributeSet attrs) { this(context, attrs, com.android.internal.R.attr.webViewStyle); } /** - * Construct a new WebView with layout parameters and a default style. - * @param context A Context object used to access application assets. - * @param attrs An AttributeSet passed to our parent. - * @param defStyle The default style resource ID. + * Constructs a new WebView with layout parameters and a default style. + * + * @param context a Context object used to access application assets + * @param attrs an AttributeSet passed to our parent + * @param defStyle the default style resource ID */ public WebView(Context context, AttributeSet attrs, int defStyle) { this(context, attrs, defStyle, false); } /** - * Construct a new WebView with layout parameters and a default style. - * @param context A Context object used to access application assets. - * @param attrs An AttributeSet passed to our parent. - * @param defStyle The default style resource ID. - * @param privateBrowsing If true the web view will be initialized in private mode. + * Constructs a new WebView with layout parameters and a default style. + * + * @param context a Context object used to access application assets + * @param attrs an AttributeSet passed to our parent + * @param defStyle the default style resource ID + * @param privateBrowsing whether this WebView will be initialized in + * private mode */ public WebView(Context context, AttributeSet attrs, int defStyle, boolean privateBrowsing) { @@ -466,18 +482,21 @@ public class WebView extends AbsoluteLayout } /** - * Construct a new WebView with layout parameters, a default style and a set - * of custom Javscript interfaces to be added to the WebView at initialization + * Constructs a new WebView with layout parameters, a default style and a set + * of custom Javscript interfaces to be added to this WebView at initialization * time. This guarantees that these interfaces will be available when the JS * context is initialized. - * @param context A Context object used to access application assets. - * @param attrs An AttributeSet passed to our parent. - * @param defStyle The default style resource ID. - * @param javaScriptInterfaces is a Map of interface names, as keys, and - * object implementing those interfaces, as values. - * @param privateBrowsing If true the web view will be initialized in private mode. + * + * @param context a Context object used to access application assets + * @param attrs an AttributeSet passed to our parent + * @param defStyle the default style resource ID + * @param javaScriptInterfaces a Map of interface names, as keys, and + * object implementing those interfaces, as + * values + * @param privateBrowsing whether this WebView will be initialized in + * private mode * @hide This is used internally by dumprendertree, as it requires the javaScript interfaces to - * be added synchronously, before a subsequent loadUrl call takes effect. + * be added synchronously, before a subsequent loadUrl call takes effect. */ @SuppressWarnings("deprecation") // for super() call into deprecated base class constructor. protected WebView(Context context, AttributeSet attrs, int defStyle, @@ -493,8 +512,9 @@ public class WebView extends AbsoluteLayout } /** - * Specify whether the horizontal scrollbar has overlay style. - * @param overlay TRUE if horizontal scrollbar should have overlay style. + * Specifies whether the horizontal scrollbar has overlay style. + * + * @param overlay true if horizontal scrollbar should have overlay style */ public void setHorizontalScrollbarOverlay(boolean overlay) { checkThread(); @@ -502,8 +522,9 @@ public class WebView extends AbsoluteLayout } /** - * Specify whether the vertical scrollbar has overlay style. - * @param overlay TRUE if vertical scrollbar should have overlay style. + * Specifies whether the vertical scrollbar has overlay style. + * + * @param overlay true if vertical scrollbar should have overlay style */ public void setVerticalScrollbarOverlay(boolean overlay) { checkThread(); @@ -511,8 +532,9 @@ public class WebView extends AbsoluteLayout } /** - * Return whether horizontal scrollbar has overlay style - * @return TRUE if horizontal scrollbar has overlay style. + * Gets whether horizontal scrollbar has overlay style. + * + * @return true if horizontal scrollbar has overlay style */ public boolean overlayHorizontalScrollbar() { checkThread(); @@ -520,8 +542,9 @@ public class WebView extends AbsoluteLayout } /** - * Return whether vertical scrollbar has overlay style - * @return TRUE if vertical scrollbar has overlay style. + * Gets whether vertical scrollbar has overlay style. + * + * @return true if vertical scrollbar has overlay style */ public boolean overlayVerticalScrollbar() { checkThread(); @@ -529,7 +552,7 @@ public class WebView extends AbsoluteLayout } /** - * Return the visible height (in pixels) of the embedded title bar (if any). + * Gets the visible height (in pixels) of the embedded title bar (if any). * * @deprecated This method is now obsolete. */ @@ -539,8 +562,10 @@ public class WebView extends AbsoluteLayout } /** - * @return The SSL certificate for the main top-level page or null if - * there is no certificate (the site is not secure). + * Gets the SSL certificate for the main top-level page or null if there is + * no certificate (the site is not secure). + * + * @return the SSL certificate for the main top-level page */ public SslCertificate getCertificate() { checkThread(); @@ -560,11 +585,12 @@ public class WebView extends AbsoluteLayout //------------------------------------------------------------------------- /** - * Save the username and password for a particular host in the WebView's + * Saves the username and password for a particular host in this WebView's * internal database. - * @param host The host that required the credentials. - * @param username The username for the given host. - * @param password The password for the given host. + * + * @param host the host that required the credentials + * @param username the username for the given host + * @param password the password for the given host */ public void savePassword(String host, String username, String password) { checkThread(); @@ -572,13 +598,13 @@ public class WebView extends AbsoluteLayout } /** - * Set the HTTP authentication credentials for a given host and realm. + * Sets the HTTP authentication credentials for a given host and realm. * - * @param host The host for the credentials. - * @param realm The realm for the credentials. - * @param username The username for the password. If it is null, it means + * @param host the host for the credentials + * @param realm the realm for the credentials + * @param username the username for the password. If it is null, it means * password can't be saved. - * @param password The password + * @param password the password */ public void setHttpAuthUsernamePassword(String host, String realm, String username, String password) { @@ -587,12 +613,12 @@ public class WebView extends AbsoluteLayout } /** - * Retrieve the HTTP authentication username and password for a given - * host & realm pair + * Retrieves the HTTP authentication username and password for a given + * host and realm pair * - * @param host The host for which the credentials apply. - * @param realm The realm for which the credentials apply. - * @return String[] if found, String[0] is username, which can be null and + * @param host the host for which the credentials apply + * @param realm the realm for which the credentials apply + * @return String[] if found. String[0] is username, which can be null and * String[1] is password. Return null if it can't find anything. */ public String[] getHttpAuthUsernamePassword(String host, String realm) { @@ -601,9 +627,9 @@ public class WebView extends AbsoluteLayout } /** - * Destroy the internal state of the WebView. This method should be called - * after the WebView has been removed from the view system. No other - * methods may be called on a WebView after destroy. + * Destroys the internal state of this WebView. This method should be called + * after this WebView has been removed from the view system. No other + * methods may be called on this WebView after destroy. */ public void destroy() { checkThread(); @@ -635,10 +661,11 @@ public class WebView extends AbsoluteLayout } /** - * Inform WebView of the network state. This is used to set + * Informs WebView of the network state. This is used to set * the JavaScript property window.navigator.isOnline and * generates the online/offline event as specified in HTML5, sec. 5.7.7 - * @param networkUp boolean indicating if network is available + * + * @param networkUp a boolean indicating if network is available */ public void setNetworkAvailable(boolean networkUp) { checkThread(); @@ -646,14 +673,15 @@ public class WebView extends AbsoluteLayout } /** - * Save the state of this WebView used in + * Saves the state of this WebView used in * {@link android.app.Activity#onSaveInstanceState}. Please note that this * method no longer stores the display data for this WebView. The previous * behavior could potentially leak files if {@link #restoreState} was never * called. See {@link #savePicture} and {@link #restorePicture} for saving * and restoring the display data. - * @param outState The Bundle to store the WebView state. - * @return The same copy of the back/forward list used to save the state. If + * + * @param outState the Bundle to store this WebView's state + * @return the same copy of the back/forward list used to save the state. If * saveState fails, the returned list will be null. * @see #savePicture * @see #restorePicture @@ -664,12 +692,12 @@ public class WebView extends AbsoluteLayout } /** - * Save the current display data to the Bundle given. Used in conjunction + * Saves the current display data to the Bundle given. Used in conjunction * with {@link #saveState}. - * @param b A Bundle to store the display data. - * @param dest The file to store the serialized picture data. Will be + * @param b a Bundle to store the display data + * @param dest the file to store the serialized picture data. Will be * overwritten with this WebView's picture data. - * @return True if the picture was successfully saved. + * @return true if the picture was successfully saved * @deprecated This method is now obsolete. */ @Deprecated @@ -679,13 +707,13 @@ public class WebView extends AbsoluteLayout } /** - * Restore the display data that was save in {@link #savePicture}. Used in - * conjunction with {@link #restoreState}. + * Restores the display data that was saved in {@link #savePicture}. Used in + * conjunction with {@link #restoreState}. Note that this will not work if + * this WebView is hardware accelerated. * - * Note that this will not work if the WebView is hardware accelerated. - * @param b A Bundle containing the saved display data. - * @param src The file where the picture data was stored. - * @return True if the picture was successfully restored. + * @param b a Bundle containing the saved display data + * @param src the file where the picture data was stored + * @return true if the picture was successfully restored * @deprecated This method is now obsolete. */ @Deprecated @@ -695,16 +723,17 @@ public class WebView extends AbsoluteLayout } /** - * Restore the state of this WebView from the given map used in + * Restores the state of this WebView from the given map used in * {@link android.app.Activity#onRestoreInstanceState}. This method should - * be called to restore the state of the WebView before using the object. If - * it is called after the WebView has had a chance to build state (load + * be called to restore the state of this WebView before using the object. If + * it is called after this WebView has had a chance to build state (load * pages, create a back/forward list, etc.) there may be undesirable * side-effects. Please note that this method no longer restores the * display data for this WebView. See {@link #savePicture} and {@link * #restorePicture} for saving and restoring the display data. - * @param inState The incoming Bundle of state. - * @return The restored back/forward list or null if restoreState failed. + * + * @param inState the incoming Bundle of state + * @return the restored back/forward list or null if restoreState failed * @see #savePicture * @see #restorePicture */ @@ -714,14 +743,15 @@ public class WebView extends AbsoluteLayout } /** - * Load the given URL with the specified additional HTTP headers. - * @param url The URL of the resource to load. - * @param additionalHttpHeaders The additional headers to be used in the + * Loads the given URL with the specified additional HTTP headers. + * + * @param url the URL of the resource to load + * @param additionalHttpHeaders the additional headers to be used in the * HTTP request for this URL, specified as a map from name to * value. Note that if this map contains any of the headers - * that are set by default by the WebView, such as those + * that are set by default by this WebView, such as those * controlling caching, accept types or the User-Agent, their - * values may be overriden by the WebView's defaults. + * values may be overriden by this WebView's defaults. */ public void loadUrl(String url, Map<String, String> additionalHttpHeaders) { checkThread(); @@ -729,8 +759,9 @@ public class WebView extends AbsoluteLayout } /** - * Load the given URL. - * @param url The URL of the resource to load. + * Loads the given URL. + * + * @param url the URL of the resource to load */ public void loadUrl(String url) { checkThread(); @@ -738,12 +769,12 @@ public class WebView extends AbsoluteLayout } /** - * Load the url with postData using "POST" method into the WebView. If url - * is not a network url, it will be loaded with {link + * Loads the URL with postData using "POST" method into this WebView. If url + * is not a network URL, it will be loaded with {link * {@link #loadUrl(String)} instead. * - * @param url The url of the resource to load. - * @param postData The data will be passed to "POST" request. + * @param url the URL of the resource to load + * @param postData the data will be passed to "POST" request */ public void postUrl(String url, byte[] postData) { checkThread(); @@ -751,7 +782,7 @@ public class WebView extends AbsoluteLayout } /** - * Load the given data into the WebView using a 'data' scheme URL. + * Loads the given data into this WebView using a 'data' scheme URL. * <p> * Note that JavaScript's same origin policy means that script running in a * page loaded using this method will be unable to access content loaded @@ -772,9 +803,10 @@ public class WebView extends AbsoluteLayout * mediatype portion of the URL and call {@link #loadUrl(String)} instead. * Note that the charset obtained from the mediatype portion of a data URL * always overrides that specified in the HTML or XML document itself. - * @param data A String of data in the given encoding. - * @param mimeType The MIME type of the data, e.g. 'text/html'. - * @param encoding The encoding of the data. + * + * @param data a String of data in the given encoding + * @param mimeType the MIME type of the data, e.g. 'text/html' + * @param encoding the encoding of the data */ public void loadData(String data, String mimeType, String encoding) { checkThread(); @@ -782,7 +814,7 @@ public class WebView extends AbsoluteLayout } /** - * Load the given data into the WebView, using baseUrl as the base URL for + * Loads the given data into this WebView, using baseUrl as the base URL for * the content. The base URL is used both to resolve relative URLs and when * applying JavaScript's same origin policy. The historyUrl is used for the * history entry. @@ -794,14 +826,15 @@ public class WebView extends AbsoluteLayout * If the base URL uses the data scheme, this method is equivalent to * calling {@link #loadData(String,String,String) loadData()} and the * historyUrl is ignored. - * @param baseUrl URL to use as the page's base URL. If null defaults to - * 'about:blank' - * @param data A String of data in the given encoding. - * @param mimeType The MIMEType of the data, e.g. 'text/html'. If null, - * defaults to 'text/html'. - * @param encoding The encoding of the data. - * @param historyUrl URL to use as the history entry, if null defaults to - * 'about:blank'. + * + * @param baseUrl the URL to use as the page's base URL. If null defaults to + * 'about:blank'. + * @param data a String of data in the given encoding + * @param mimeType the MIMEType of the data, e.g. 'text/html'. If null, + * defaults to 'text/html'. + * @param encoding the encoding of the data + * @param historyUrl the URL to use as the history entry. If null defaults + * to 'about:blank'. */ public void loadDataWithBaseURL(String baseUrl, String data, String mimeType, String encoding, String historyUrl) { @@ -812,7 +845,7 @@ public class WebView extends AbsoluteLayout /** * Saves the current view as a web archive. * - * @param filename The filename where the archive should be placed. + * @param filename the filename where the archive should be placed */ public void saveWebArchive(String filename) { checkThread(); @@ -822,11 +855,11 @@ public class WebView extends AbsoluteLayout /** * Saves the current view as a web archive. * - * @param basename The filename where the archive should be placed. - * @param autoname If false, takes basename to be a file. If true, basename + * @param basename the filename where the archive should be placed + * @param autoname if false, takes basename to be a file. If true, basename * is assumed to be a directory in which a filename will be - * chosen according to the url of the current page. - * @param callback Called after the web archive has been saved. The + * chosen according to the URL of the current page. + * @param callback called after the web archive has been saved. The * parameter for onReceiveValue will either be the filename * under which the file was saved, or null if saving the * file failed. @@ -837,7 +870,7 @@ public class WebView extends AbsoluteLayout } /** - * Stop the current load. + * Stops the current load. */ public void stopLoading() { checkThread(); @@ -845,7 +878,7 @@ public class WebView extends AbsoluteLayout } /** - * Reload the current url. + * Reloads the current URL. */ public void reload() { checkThread(); @@ -853,8 +886,9 @@ public class WebView extends AbsoluteLayout } /** - * Return true if this WebView has a back history item. - * @return True iff this WebView has a back history item. + * Gets whether this WebView has a back history item. + * + * @return true iff this WebView has a back history item */ public boolean canGoBack() { checkThread(); @@ -862,7 +896,7 @@ public class WebView extends AbsoluteLayout } /** - * Go back in the history of this WebView. + * Goes back in the history of this WebView. */ public void goBack() { checkThread(); @@ -870,8 +904,9 @@ public class WebView extends AbsoluteLayout } /** - * Return true if this WebView has a forward history item. - * @return True iff this Webview has a forward history item. + * Gets whether this WebView has a forward history item. + * + * @return true iff this Webview has a forward history item */ public boolean canGoForward() { checkThread(); @@ -879,7 +914,7 @@ public class WebView extends AbsoluteLayout } /** - * Go forward in the history of this WebView. + * Goes forward in the history of this WebView. */ public void goForward() { checkThread(); @@ -887,10 +922,11 @@ public class WebView extends AbsoluteLayout } /** - * Return true if the page can go back or forward the given + * Gets whether the page can go back or forward the given * number of steps. - * @param steps The negative or positive number of steps to move the - * history. + * + * @param steps the negative or positive number of steps to move the + * history */ public boolean canGoBackOrForward(int steps) { checkThread(); @@ -898,11 +934,12 @@ public class WebView extends AbsoluteLayout } /** - * Go to the history item that is the number of steps away from + * Goes to the history item that is the number of steps away from * the current item. Steps is negative if backward and positive * if forward. - * @param steps The number of steps to take back or forward in the back - * forward list. + * + * @param steps the number of steps to take back or forward in the back + * forward list */ public void goBackOrForward(int steps) { checkThread(); @@ -910,7 +947,7 @@ public class WebView extends AbsoluteLayout } /** - * Returns true if private browsing is enabled in this WebView. + * Gets whether private browsing is enabled in this WebView. */ public boolean isPrivateBrowsingEnabled() { checkThread(); @@ -918,7 +955,8 @@ public class WebView extends AbsoluteLayout } /** - * Scroll the contents of the view up by half the view size + * Scrolls the contents of this WebView up by half the view size. + * * @param top true to jump to the top of the page * @return true if the page was scrolled */ @@ -928,7 +966,8 @@ public class WebView extends AbsoluteLayout } /** - * Scroll the contents of the view down by half the page size + * Scrolls the contents of this WebView down by half the page size. + * * @param bottom true to jump to bottom of page * @return true if the page was scrolled */ @@ -938,8 +977,8 @@ public class WebView extends AbsoluteLayout } /** - * Clear the view so that onDraw() will draw nothing but white background, - * and onMeasure() will return 0 if MeasureSpec is not MeasureSpec.EXACTLY + * Clears this WebView so that onDraw() will draw nothing but white background, + * and onMeasure() will return 0 if MeasureSpec is not MeasureSpec.EXACTLY. */ public void clearView() { checkThread(); @@ -947,13 +986,13 @@ public class WebView extends AbsoluteLayout } /** - * Return a new picture that captures the current display of the webview. - * This is a copy of the display, and will be unaffected if the webview + * Gets a new picture that captures the current display of this WebView. + * This is a copy of the display, and will be unaffected if this WebView * later loads a different URL. * - * @return a picture containing the current contents of the view. Note this - * picture is of the entire document, and is not restricted to the - * bounds of the view. + * @return a picture containing the current contents of this WebView. Note + * this picture is of the entire document, and is not restricted to + * the bounds of the view. */ public Picture capturePicture() { checkThread(); @@ -961,8 +1000,9 @@ public class WebView extends AbsoluteLayout } /** - * Return the current scale of the WebView - * @return The current scale. + * Gets the current scale of this WebView. + * + * @return the current scale */ public float getScale() { checkThread(); @@ -970,14 +1010,14 @@ public class WebView extends AbsoluteLayout } /** - * Set the initial scale for the WebView. 0 means default. If + * Sets the initial scale for this WebView. 0 means default. If * {@link WebSettings#getUseWideViewPort()} is true, it zooms out all the * way. Otherwise it starts with 100%. If initial scale is greater than 0, * WebView starts with this value as initial scale. * Please note that unlike the scale properties in the viewport meta tag, * this method doesn't take the screen density into account. * - * @param scaleInPercent The initial scale in percent. + * @param scaleInPercent the initial scale in percent */ public void setInitialScale(int scaleInPercent) { checkThread(); @@ -985,7 +1025,7 @@ public class WebView extends AbsoluteLayout } /** - * Invoke the graphical zoom picker widget for this WebView. This will + * Invokes the graphical zoom picker widget for this WebView. This will * result in the zoom widget appearing on the screen to control the zoom * level of this WebView. */ @@ -995,15 +1035,15 @@ public class WebView extends AbsoluteLayout } /** - * Return a HitTestResult based on the current cursor node. If a HTML::a tag - * is found and the anchor has a non-JavaScript url, the HitTestResult type - * is set to SRC_ANCHOR_TYPE and the url is set in the "extra" field. If the - * anchor does not have a url or if it is a JavaScript url, the type will - * be UNKNOWN_TYPE and the url has to be retrieved through + * Gets a HitTestResult based on the current cursor node. If a HTML::a + * tag is found and the anchor has a non-JavaScript URL, the HitTestResult + * type is set to SRC_ANCHOR_TYPE and the URL is set in the "extra" field. + * If the anchor does not have a URL or if it is a JavaScript URL, the type + * will be UNKNOWN_TYPE and the URL has to be retrieved through * {@link #requestFocusNodeHref} asynchronously. If a HTML::img tag is - * found, the HitTestResult type is set to IMAGE_TYPE and the url is set in + * found, the HitTestResult type is set to IMAGE_TYPE and the URL is set in * the "extra" field. A type of - * SRC_IMAGE_ANCHOR_TYPE indicates an anchor with a url that has an image as + * SRC_IMAGE_ANCHOR_TYPE indicates an anchor with a URL that has an image as * a child node. If a phone number is found, the HitTestResult type is set * to PHONE_TYPE and the phone number is set in the "extra" field of * HitTestResult. If a map address is found, the HitTestResult type is set @@ -1018,18 +1058,17 @@ public class WebView extends AbsoluteLayout } /** - * Request the anchor or image element URL at the last tapped point. + * Requests the anchor or image element URL at the last tapped point. * If hrefMsg is null, this method returns immediately and does not * dispatch hrefMsg to its target. If the tapped point hits an image, * an anchor, or an image in an anchor, the message associates * strings in named keys in its data. The value paired with the key * may be an empty string. * - * @param hrefMsg This message will be dispatched with the result of the - * request. The message data contains three keys: - * - "url" returns the anchor's href attribute. - * - "title" returns the anchor's text. - * - "src" returns the image's src attribute. + * @param hrefMsg the message to be dispatched with the result of the + * request. The message data contains three keys. "url" + * returns the anchor's href attribute. "title" returns the + * anchor's text. "src" returns the image's src attribute. */ public void requestFocusNodeHref(Message hrefMsg) { checkThread(); @@ -1037,10 +1076,10 @@ public class WebView extends AbsoluteLayout } /** - * Request the url of the image last touched by the user. msg will be sent - * to its target with a String representing the url as its object. + * Requests the URL of the image last touched by the user. msg will be sent + * to its target with a String representing the URL as its object. * - * @param msg This message will be dispatched with the result of the request + * @param msg the message to be dispatched with the result of the request * as the data member with "url" as key. The result can be null. */ public void requestImageRef(Message msg) { @@ -1049,10 +1088,11 @@ public class WebView extends AbsoluteLayout } /** - * Get the url for the current page. This is not always the same as the url + * Gets the URL for the current page. This is not always the same as the URL * passed to WebViewClient.onPageStarted because although the load for - * that url has begun, the current page may not have changed. - * @return The url for the current page. + * that URL has begun, the current page may not have changed. + * + * @return the URL for the current page */ public String getUrl() { checkThread(); @@ -1060,12 +1100,13 @@ public class WebView extends AbsoluteLayout } /** - * Get the original url for the current page. This is not always the same - * as the url passed to WebViewClient.onPageStarted because although the - * load for that url has begun, the current page may not have changed. - * Also, there may have been redirects resulting in a different url to that + * Gets the original URL for the current page. This is not always the same + * as the URL passed to WebViewClient.onPageStarted because although the + * load for that URL has begun, the current page may not have changed. + * Also, there may have been redirects resulting in a different URL to that * originally requested. - * @return The url that was originally requested for the current page. + * + * @return the URL that was originally requested for the current page */ public String getOriginalUrl() { checkThread(); @@ -1073,9 +1114,10 @@ public class WebView extends AbsoluteLayout } /** - * Get the title for the current page. This is the title of the current page + * Gets the title for the current page. This is the title of the current page * until WebViewClient.onReceivedTitle is called. - * @return The title for the current page. + * + * @return the title for the current page */ public String getTitle() { checkThread(); @@ -1083,9 +1125,10 @@ public class WebView extends AbsoluteLayout } /** - * Get the favicon for the current page. This is the favicon of the current + * Gets the favicon for the current page. This is the favicon of the current * page until WebViewClient.onReceivedIcon is called. - * @return The favicon for the current page. + * + * @return the favicon for the current page */ public Bitmap getFavicon() { checkThread(); @@ -1093,9 +1136,10 @@ public class WebView extends AbsoluteLayout } /** - * Get the touch icon url for the apple-touch-icon <link> element, or + * Gets the touch icon URL for the apple-touch-icon <link> element, or * a URL on this site's server pointing to the standard location of a * touch icon. + * * @hide */ public String getTouchIconUrl() { @@ -1103,8 +1147,9 @@ public class WebView extends AbsoluteLayout } /** - * Get the progress for the current page. - * @return The progress for the current page between 0 and 100. + * Gets the progress for the current page. + * + * @return the progress for the current page between 0 and 100 */ public int getProgress() { checkThread(); @@ -1112,7 +1157,9 @@ public class WebView extends AbsoluteLayout } /** - * @return the height of the HTML content. + * Gets the height of the HTML content. + * + * @return the height of the HTML content */ public int getContentHeight() { checkThread(); @@ -1120,7 +1167,9 @@ public class WebView extends AbsoluteLayout } /** - * @return the width of the HTML content. + * Gets the width of the HTML content. + * + * @return the width of the HTML content * @hide */ public int getContentWidth() { @@ -1128,8 +1177,8 @@ public class WebView extends AbsoluteLayout } /** - * Pause all layout, parsing, and JavaScript timers for all webviews. This - * is a global requests, not restricted to just this webview. This can be + * Pauses all layout, parsing, and JavaScript timers for all WebViews. This + * is a global requests, not restricted to just this WebView. This can be * useful if the application has been paused. */ public void pauseTimers() { @@ -1138,7 +1187,7 @@ public class WebView extends AbsoluteLayout } /** - * Resume all layout, parsing, and JavaScript timers for all webviews. + * Resumes all layout, parsing, and JavaScript timers for all WebViews. * This will resume dispatching all timers. */ public void resumeTimers() { @@ -1147,11 +1196,10 @@ public class WebView extends AbsoluteLayout } /** - * Call this to pause any extra processing associated with this WebView and - * its associated DOM, plugins, JavaScript etc. For example, if the WebView - * is taken offscreen, this could be called to reduce unnecessary CPU or - * network traffic. When the WebView is again "active", call onResume(). - * + * Pauses any extra processing associated with this WebView and its + * associated DOM, plugins, JavaScript etc. For example, if this WebView is + * taken offscreen, this could be called to reduce unnecessary CPU or + * network traffic. When this WebView is again "active", call onResume(). * Note that this differs from pauseTimers(), which affects all WebViews. */ public void onPause() { @@ -1160,7 +1208,7 @@ public class WebView extends AbsoluteLayout } /** - * Call this to resume a WebView after a previous call to onPause(). + * Resumes a WebView after a previous call to onPause(). */ public void onResume() { checkThread(); @@ -1168,8 +1216,9 @@ public class WebView extends AbsoluteLayout } /** - * Returns true if the view is paused, meaning onPause() was called. Calling - * onResume() sets the paused state back to false. + * Gets whether this WebView is paused, meaning onPause() was called. + * Calling onResume() sets the paused state back to false. + * * @hide */ public boolean isPaused() { @@ -1177,8 +1226,8 @@ public class WebView extends AbsoluteLayout } /** - * Call this to inform the view that memory is low so that it can - * free any available memory. + * Informs this WebView that memory is low so that it can free any available + * memory. */ public void freeMemory() { checkThread(); @@ -1186,10 +1235,10 @@ public class WebView extends AbsoluteLayout } /** - * Clear the resource cache. Note that the cache is per-application, so + * Clears the resource cache. Note that the cache is per-application, so * this will clear the cache for all WebViews used. * - * @param includeDiskFiles If false, only the RAM cache is cleared. + * @param includeDiskFiles if false, only the RAM cache is cleared */ public void clearCache(boolean includeDiskFiles) { checkThread(); @@ -1197,7 +1246,7 @@ public class WebView extends AbsoluteLayout } /** - * Make sure that clearing the form data removes the adapter from the + * Makes sure that clearing the form data removes the adapter from the * currently focused textfield if there is one. */ public void clearFormData() { @@ -1206,7 +1255,7 @@ public class WebView extends AbsoluteLayout } /** - * Tell the WebView to clear its internal back/forward list. + * Tells this WebView to clear its internal back/forward list. */ public void clearHistory() { checkThread(); @@ -1214,8 +1263,8 @@ public class WebView extends AbsoluteLayout } /** - * Clear the SSL preferences table stored in response to proceeding with SSL - * certificate errors. + * Clears the SSL preferences table stored in response to proceeding with + * SSL certificate errors. */ public void clearSslPreferences() { checkThread(); @@ -1223,7 +1272,7 @@ public class WebView extends AbsoluteLayout } /** - * Return the WebBackForwardList for this WebView. This contains the + * Gets the WebBackForwardList for this WebView. This contains the * back/forward list for use in querying each item in the history stack. * This is a copy of the private WebBackForwardList so it contains only a * snapshot of the current state. Multiple calls to this method may return @@ -1237,10 +1286,10 @@ public class WebView extends AbsoluteLayout } /** - * Register the listener to be notified as find-on-page operations progress. - * This will replace the current listener. + * Registers the listener to be notified as find-on-page operations + * progress. This will replace the current listener. * - * @param listener An implementation of {@link FindListener}. + * @param listener an implementation of {@link FindListener} */ public void setFindListener(FindListener listener) { checkThread(); @@ -1248,14 +1297,14 @@ public class WebView extends AbsoluteLayout } /** - * Highlight and scroll to the next match found by {@link #findAll} or + * Highlights and scrolls to the next match found by {@link #findAll} or * {@link #findAllAsync}, wrapping around page boundaries as necessary. * Notifies any registered {@link FindListener}. If neither * {@link #findAll} nor {@link #findAllAsync(String)} has been called yet, * or if {@link #clearMatches} has been called since the last find * operation, this function does nothing. * - * @param forward Direction to search. + * @param forward the direction to search * @see #setFindListener */ public void findNext(boolean forward) { @@ -1264,12 +1313,11 @@ public class WebView extends AbsoluteLayout } /** - * Find all instances of find on the page and highlight them. + * Finds all instances of find on the page and highlights them. * Notifies any registered {@link FindListener}. * - * @param find String to find. - * @return int The number of occurances of the String "find" - * that were found. + * @param find the string to find + * @return the number of occurances of the String "find" that were found * @deprecated {@link #findAllAsync} is preferred. * @see #setFindListener */ @@ -1281,12 +1329,12 @@ public class WebView extends AbsoluteLayout } /** - * Find all instances of find on the page and highlight them, + * Finds all instances of find on the page and highlights them, * asynchronously. Notifies any registered {@link FindListener}. * Successive calls to this or {@link #findAll} will cancel any * pending searches. * - * @param find String to find. + * @param find the string to find. * @see #setFindListener */ public void findAllAsync(String find) { @@ -1295,14 +1343,15 @@ public class WebView extends AbsoluteLayout } /** - * Start an ActionMode for finding text in this WebView. Only works if this - * WebView is attached to the view system. - * @param text If non-null, will be the initial text to search for. + * Starts an ActionMode for finding text in this WebView. Only works if this + * WebView is attached to the view system. + * + * @param text if non-null, will be the initial text to search for. * Otherwise, the last String searched for in this WebView will * be used to start. - * @param showIme If true, show the IME, assuming the user will begin typing. - * If false and text is non-null, perform a find all. - * @return boolean True if the find dialog is shown, false otherwise. + * @param showIme if true, show the IME, assuming the user will begin typing. + * If false and text is non-null, perform a find all. + * @return true if the find dialog is shown, false otherwise */ public boolean showFindDialog(String text, boolean showIme) { checkThread(); @@ -1310,24 +1359,26 @@ public class WebView extends AbsoluteLayout } /** - * Return the first substring consisting of the address of a physical + * Gets the first substring consisting of the address of a physical * location. Currently, only addresses in the United States are detected, * and consist of: - * - a house number - * - a street name - * - a street type (Road, Circle, etc), either spelled out or abbreviated - * - a city name - * - a state or territory, either spelled out or two-letter abbr. - * - an optional 5 digit or 9 digit zip code. - * + * <ul> + * <li>a house number</li> + * <li>a street name</li> + * <li>a street type (Road, Circle, etc), either spelled out or + * abbreviated</li> + * <li>a city name</li> + * <li>a state or territory, either spelled out or two-letter abbr</li> + * <li>an optional 5 digit or 9 digit zip code</li> + * </ul> * All names must be correctly capitalized, and the zip code, if present, * must be valid for the state. The street type must be a standard USPS * spelling or abbreviation. The state or territory must also be spelled * or abbreviated using USPS standards. The house number may not exceed * five digits. - * @param addr The string to search for addresses. * - * @return the address, or if no address is found, return null. + * @param addr the string to search for addresses + * @return the address, or if no address is found, null */ public static String findAddress(String addr) { checkThread(); @@ -1335,7 +1386,7 @@ public class WebView extends AbsoluteLayout } /** - * Clear the highlighting surrounding text matches created by + * Clears the highlighting surrounding text matches created by * {@link #findAll} or {@link #findAllAsync}. */ public void clearMatches() { @@ -1344,10 +1395,11 @@ public class WebView extends AbsoluteLayout } /** - * Query the document to see if it contains any image references. The + * Queries the document to see if it contains any image references. The * message object will be dispatched with arg1 being set to 1 if images * were found and 0 if the document does not reference any images. - * @param response The message that will be dispatched with the result. + * + * @param response the message that will be dispatched with the result */ public void documentHasImages(Message response) { checkThread(); @@ -1355,9 +1407,10 @@ public class WebView extends AbsoluteLayout } /** - * Set the WebViewClient that will receive various notifications and + * Sets the WebViewClient that will receive various notifications and * requests. This will replace the current handler. - * @param client An implementation of WebViewClient. + * + * @param client an implementation of WebViewClient */ public void setWebViewClient(WebViewClient client) { checkThread(); @@ -1365,10 +1418,11 @@ public class WebView extends AbsoluteLayout } /** - * Register the interface to be used when content can not be handled by + * Registers the interface to be used when content can not be handled by * the rendering engine, and should be downloaded instead. This will replace * the current handler. - * @param listener An implementation of DownloadListener. + * + * @param listener an implementation of DownloadListener */ public void setDownloadListener(DownloadListener listener) { checkThread(); @@ -1376,10 +1430,11 @@ public class WebView extends AbsoluteLayout } /** - * Set the chrome handler. This is an implementation of WebChromeClient for + * Sets the chrome handler. This is an implementation of WebChromeClient for * use in handling JavaScript dialogs, favicons, titles, and the progress. * This will replace the current handler. - * @param client An implementation of WebChromeClient. + * + * @param client an implementation of WebChromeClient */ public void setWebChromeClient(WebChromeClient client) { checkThread(); @@ -1387,9 +1442,10 @@ public class WebView extends AbsoluteLayout } /** - * Set the Picture listener. This is an interface used to receive + * Sets the Picture listener. This is an interface used to receive * notifications of a new Picture. - * @param listener An implementation of WebView.PictureListener. + * + * @param listener an implementation of WebView.PictureListener * @deprecated This method is now obsolete. */ @Deprecated @@ -1419,7 +1475,7 @@ public class WebView extends AbsoluteLayout * permissions of the host application. Use extreme care when using this * method in a WebView which could contain untrusted content.</li> * <li> JavaScript interacts with Java object on a private, background - * thread of the WebView. Care is therefore required to maintain thread + * thread of this WebView. Care is therefore required to maintain thread * safety.</li> * </ul> * @@ -1445,10 +1501,11 @@ public class WebView extends AbsoluteLayout } /** - * Return the WebSettings object used to control the settings for this + * Gets the WebSettings object used to control the settings for this * WebView. - * @return A WebSettings object that can be used to control this WebView's - * settings. + * + * @return a WebSettings object that can be used to control this WebView's + * settings */ public WebSettings getSettings() { checkThread(); @@ -1456,11 +1513,11 @@ public class WebView extends AbsoluteLayout } /** - * Return the list of currently loaded plugins. - * @return The list of currently loaded plugins. + * Gets the list of currently loaded plugins. * - * @hide + * @return the list of currently loaded plugins * @deprecated This was used for Gears, which has been deprecated. + * @hide */ @Deprecated public static synchronized PluginList getPluginList() { @@ -1469,8 +1526,8 @@ public class WebView extends AbsoluteLayout } /** - * @hide * @deprecated This was used for Gears, which has been deprecated. + * @hide */ @Deprecated public void refreshPlugins(boolean reloadOpenPages) { @@ -1478,8 +1535,9 @@ public class WebView extends AbsoluteLayout } /** - * Use this method to put the WebView into text selection mode. - * Do not rely on this functionality; it will be deprecated in the future. + * Puts this WebView into text selection mode. Do not rely on this + * functionality; it will be deprecated in the future. + * * @deprecated This method is now obsolete. */ @Deprecated @@ -1528,15 +1586,15 @@ public class WebView extends AbsoluteLayout } /** - * Gets the zoom controls for the WebView, as a separate View. The caller is - * responsible for inserting this View into the layout hierarchy. + * Gets the zoom controls for this WebView, as a separate View. The caller + * is responsible for inserting this View into the layout hierarchy. * <p/> * API level {@link android.os.Build.VERSION_CODES#CUPCAKE} introduced * built-in zoom mechanisms for the WebView, as opposed to these separate * zoom controls. The built-in mechanisms are preferred and can be enabled * using {@link WebSettings#setBuiltInZoomControls}. * - * @deprecated The built-in zoom mechanisms are preferred. + * @deprecated the built-in zoom mechanisms are preferred * @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN} */ @Deprecated @@ -1546,7 +1604,9 @@ public class WebView extends AbsoluteLayout } /** - * @return TRUE if the WebView can be zoomed in. + * Gets whether this WebView can be zoomed in. + * + * @return true if this WebView can be zoomed in */ public boolean canZoomIn() { checkThread(); @@ -1554,7 +1614,9 @@ public class WebView extends AbsoluteLayout } /** - * @return TRUE if the WebView can be zoomed out. + * Gets whether this WebView can be zoomed out. + * + * @return true if this WebView can be zoomed out */ public boolean canZoomOut() { checkThread(); @@ -1562,8 +1624,9 @@ public class WebView extends AbsoluteLayout } /** - * Perform zoom in in the webview - * @return TRUE if zoom in succeeds. FALSE if no zoom changes. + * Performs zoom in in this WebView. + * + * @return true if zoom in succeeds, false if no zoom changes */ public boolean zoomIn() { checkThread(); @@ -1571,8 +1634,9 @@ public class WebView extends AbsoluteLayout } /** - * Perform zoom out in the webview - * @return TRUE if zoom out succeeds. FALSE if no zoom changes. + * Performs zoom out in this WebView. + * + * @return true if zoom out succeeds, false if no zoom changes */ public boolean zoomOut() { checkThread(); @@ -1593,8 +1657,9 @@ public class WebView extends AbsoluteLayout //------------------------------------------------------------------------- /** - * Used by providers to obtain the underlying implementation, e.g. when the appliction - * responds to WebViewClient.onCreateWindow() request. + * Gets the WebViewProvider. Used by providers to obtain the underlying + * implementation, e.g. when the appliction responds to + * WebViewClient.onCreateWindow() request. * * @hide WebViewProvider is not public API. */ diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java index 05b3e643cca4..9cf0d54d3b68 100644 --- a/core/java/android/webkit/WebViewClassic.java +++ b/core/java/android/webkit/WebViewClassic.java @@ -2598,7 +2598,8 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc */ @Override public boolean isPrivateBrowsingEnabled() { - return getSettings().isPrivateBrowsingEnabled(); + WebSettingsClassic settings = getSettings(); + return (settings != null) ? settings.isPrivateBrowsingEnabled() : false; } private void startPrivateBrowsing() { @@ -2668,7 +2669,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc public void clearView() { mContentWidth = 0; mContentHeight = 0; - setBaseLayer(0, null, false, false); + setBaseLayer(0, false, false); mWebViewCore.sendMessage(EventHub.CLEAR_CONTENT); } @@ -3039,14 +3040,14 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc // the scale factor is not 1) private void calcOurContentVisibleRectF(RectF r) { calcOurVisibleRect(mContentVisibleRect); - r.left = viewToContentXf(mContentVisibleRect.left); + r.left = viewToContentXf(mContentVisibleRect.left) / mWebView.getScaleX(); // viewToContentY will remove the total height of the title bar. Add // the visible height back in to account for the fact that if the title // bar is partially visible, the part of the visible rect which is // displaying our content is displaced by that amount. - r.top = viewToContentYf(mContentVisibleRect.top + getVisibleTitleHeightImpl()); - r.right = viewToContentXf(mContentVisibleRect.right); - r.bottom = viewToContentYf(mContentVisibleRect.bottom); + r.top = viewToContentYf(mContentVisibleRect.top + getVisibleTitleHeightImpl()) / mWebView.getScaleY(); + r.right = viewToContentXf(mContentVisibleRect.right) / mWebView.getScaleX(); + r.bottom = viewToContentYf(mContentVisibleRect.bottom) / mWebView.getScaleY(); } static class ViewSizeData { @@ -4447,12 +4448,12 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc */ private SelectActionModeCallback mSelectCallback; - void setBaseLayer(int layer, Region invalRegion, boolean showVisualIndicator, + void setBaseLayer(int layer, boolean showVisualIndicator, boolean isPictureAfterFirstLayout) { if (mNativeClass == 0) return; boolean queueFull; - queueFull = nativeSetBaseLayer(mNativeClass, layer, invalRegion, + queueFull = nativeSetBaseLayer(mNativeClass, layer, showVisualIndicator, isPictureAfterFirstLayout); if (queueFull) { @@ -7847,7 +7848,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc boolean isPictureAfterFirstLayout = viewState != null; if (updateBaseLayer) { - setBaseLayer(draw.mBaseLayer, draw.mInvalRegion, + setBaseLayer(draw.mBaseLayer, getSettings().getShowVisualIndicator(), isPictureAfterFirstLayout); } @@ -7879,15 +7880,17 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc } mSendScrollEvent = true; - if (DebugFlags.WEB_VIEW) { - Rect b = draw.mInvalRegion.getBounds(); - Log.v(LOGTAG, "NEW_PICTURE_MSG_ID {" + - b.left+","+b.top+","+b.right+","+b.bottom+"}"); + int functor = 0; + if (mWebView.isHardwareAccelerated() + || mWebView.getLayerType() != View.LAYER_TYPE_HARDWARE) { + functor = nativeGetDrawGLFunction(mNativeClass); } - Rect invalBounds = draw.mInvalRegion.getBounds(); - if (!invalBounds.isEmpty()) { - invalidateContentRect(invalBounds); + + if (functor != 0) { + mWebView.getViewRootImpl().attachFunctor(functor); } else { + // invalidate the screen so that the next repaint will show new content + // TODO: partial invalidate mWebView.invalidate(); } @@ -8575,8 +8578,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc private native Rect nativeLayerBounds(int layer); private native void nativeSetHeightCanMeasure(boolean measure); private native boolean nativeSetBaseLayer(int nativeInstance, - int layer, Region invalRegion, - boolean showVisualIndicator, boolean isPictureAfterFirstLayout); + int layer, boolean showVisualIndicator, boolean isPictureAfterFirstLayout); private native int nativeGetBaseLayer(); private native void nativeReplaceBaseContent(int content); private native void nativeCopyBaseContentToPicture(Picture pict); diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java index 75141fd37575..12c9d69bc74c 100644 --- a/core/java/android/webkit/WebViewCore.java +++ b/core/java/android/webkit/WebViewCore.java @@ -601,8 +601,7 @@ public final class WebViewCore { * Redraw a portion of the picture set. The Point wh returns the * width and height of the overall picture. */ - private native int nativeRecordContent(int nativeClass, Region invalRegion, - Point wh); + private native int nativeRecordContent(int nativeClass, Point wh); /** * Notify webkit that animations have begun (on the hardware accelerated content) @@ -2180,11 +2179,9 @@ public final class WebViewCore { static class DrawData { DrawData() { mBaseLayer = 0; - mInvalRegion = new Region(); mContentSize = new Point(); } int mBaseLayer; - Region mInvalRegion; // view size that was used by webkit during the most recent layout Point mViewSize; Point mContentSize; @@ -2230,8 +2227,7 @@ public final class WebViewCore { mDrawIsScheduled = false; DrawData draw = new DrawData(); if (DebugFlags.WEB_VIEW_CORE) Log.v(LOGTAG, "webkitDraw start"); - draw.mBaseLayer = nativeRecordContent(mNativeClass, draw.mInvalRegion, - draw.mContentSize); + draw.mBaseLayer = nativeRecordContent(mNativeClass, draw.mContentSize); if (draw.mBaseLayer == 0) { if (mWebViewClassic != null && !mWebViewClassic.isPaused()) { if (DebugFlags.WEB_VIEW_CORE) Log.v(LOGTAG, "webkitDraw abort, resending draw message"); @@ -2277,8 +2273,7 @@ public final class WebViewCore { // the draw path (and fix saving <canvas>) DrawData draw = new DrawData(); if (DebugFlags.WEB_VIEW_CORE) Log.v(LOGTAG, "saveViewState start"); - draw.mBaseLayer = nativeRecordContent(mNativeClass, draw.mInvalRegion, - draw.mContentSize); + draw.mBaseLayer = nativeRecordContent(mNativeClass, draw.mContentSize); boolean result = false; try { result = ViewStateSerializer.serializeViewState(stream, draw); diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index 53d5e0b4c497..a2531f860174 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -58,6 +58,8 @@ import android.view.ViewParent; import android.view.ViewTreeObserver; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityNodeInfo; +import android.view.animation.Interpolator; +import android.view.animation.LinearInterpolator; import android.view.inputmethod.BaseInputConnection; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputConnection; @@ -660,6 +662,11 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te private int mLastHandledItemCount; /** + * Used for smooth scrolling at a consistent rate + */ + static final Interpolator sLinearInterpolator = new LinearInterpolator(); + + /** * Interface definition for a callback to be invoked when the list or grid * has been scrolled. */ @@ -3753,6 +3760,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te void start(int initialVelocity) { int initialY = initialVelocity < 0 ? Integer.MAX_VALUE : 0; mLastFlingY = initialY; + mScroller.setInterpolator(null); mScroller.fling(0, initialY, 0, initialVelocity, 0, Integer.MAX_VALUE, 0, Integer.MAX_VALUE); mTouchMode = TOUCH_MODE_FLING; @@ -3782,6 +3790,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } void startOverfling(int initialVelocity) { + mScroller.setInterpolator(null); mScroller.fling(0, mScrollY, 0, initialVelocity, 0, 0, Integer.MIN_VALUE, Integer.MAX_VALUE, 0, getHeight()); mTouchMode = TOUCH_MODE_OVERFLING; @@ -3811,9 +3820,10 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te postOnAnimation(this); } - void startScroll(int distance, int duration) { + void startScroll(int distance, int duration, boolean linear) { int initialY = distance < 0 ? Integer.MAX_VALUE : 0; mLastFlingY = initialY; + mScroller.setInterpolator(linear ? sLinearInterpolator : null); mScroller.startScroll(0, initialY, 0, distance, duration); mTouchMode = TOUCH_MODE_FLING; postOnAnimation(this); @@ -4107,14 +4117,14 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } else { // On-screen, just scroll. final int targetTop = getChildAt(position - firstPos).getTop(); - smoothScrollBy(targetTop - offset, duration); + smoothScrollBy(targetTop - offset, duration, true); return; } // Estimate how many screens we should travel final float screenTravelCount = (float) viewTravelCount / childCount; - mScrollDuration = screenTravelCount < 1 ? (int) (screenTravelCount * duration) : - (int) (duration / screenTravelCount); + mScrollDuration = screenTravelCount < 1 ? + duration : (int) (duration / screenTravelCount); mLastSeenPos = INVALID_POSITION; postOnAnimation(this); @@ -4151,7 +4161,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te Math.max(mListPadding.bottom, mExtraScroll) : mListPadding.bottom; final int scrollBy = lastViewHeight - lastViewPixelsShowing + extraScroll; - smoothScrollBy(scrollBy, mScrollDuration); + smoothScrollBy(scrollBy, mScrollDuration, true); mLastSeenPos = lastPos; if (lastPos < mTargetPos) { @@ -4182,14 +4192,14 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te final int extraScroll = Math.max(mListPadding.bottom, mExtraScroll); if (nextPos < mBoundPos) { smoothScrollBy(Math.max(0, nextViewHeight + nextViewTop - extraScroll), - mScrollDuration); + mScrollDuration, true); mLastSeenPos = nextPos; postOnAnimation(this); } else { if (nextViewTop > extraScroll) { - smoothScrollBy(nextViewTop - extraScroll, mScrollDuration); + smoothScrollBy(nextViewTop - extraScroll, mScrollDuration, true); } } break; @@ -4210,7 +4220,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te final int extraScroll = firstPos > 0 ? Math.max(mExtraScroll, mListPadding.top) : mListPadding.top; - smoothScrollBy(firstViewTop - extraScroll, mScrollDuration); + smoothScrollBy(firstViewTop - extraScroll, mScrollDuration, true); mLastSeenPos = firstPos; @@ -4229,7 +4239,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te if (lastPos == mLastSeenPos) { // No new views, let things keep going. - post(this); + postOnAnimation(this); return; } @@ -4240,13 +4250,13 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te final int extraScroll = Math.max(mListPadding.top, mExtraScroll); mLastSeenPos = lastPos; if (lastPos > mBoundPos) { - smoothScrollBy(-(lastViewPixelsShowing - extraScroll), mScrollDuration); + smoothScrollBy(-(lastViewPixelsShowing - extraScroll), mScrollDuration, true); postOnAnimation(this); } else { final int bottom = listHeight - extraScroll; final int lastViewBottom = lastViewTop + lastViewHeight; if (bottom > lastViewBottom) { - smoothScrollBy(-(bottom - lastViewBottom), mScrollDuration); + smoothScrollBy(-(bottom - lastViewBottom), mScrollDuration, true); } } break; @@ -4255,7 +4265,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te case MOVE_OFFSET: { if (mLastSeenPos == firstPos) { // No new views, let things keep going. - post(this); + postOnAnimation(this); return; } @@ -4277,17 +4287,22 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te final float modifier = Math.min(Math.abs(screenTravelCount), 1.f); if (position < firstPos) { - smoothScrollBy((int) (-getHeight() * modifier), mScrollDuration); + final int distance = (int) (-getHeight() * modifier); + final int duration = (int) (mScrollDuration * modifier); + smoothScrollBy(distance, duration, true); postOnAnimation(this); } else if (position > lastPos) { - smoothScrollBy((int) (getHeight() * modifier), mScrollDuration); + final int distance = (int) (getHeight() * modifier); + final int duration = (int) (mScrollDuration * modifier); + smoothScrollBy(distance, duration, true); postOnAnimation(this); } else { // On-screen, just scroll. final int targetTop = getChildAt(position - firstPos).getTop(); final int distance = targetTop - mOffsetFromTop; - smoothScrollBy(distance, - (int) (mScrollDuration * ((float) distance / getHeight()))); + final int duration = (int) (mScrollDuration * + ((float) Math.abs(distance) / getHeight())); + smoothScrollBy(distance, duration, true); } break; } @@ -4393,6 +4408,10 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te * @param duration Duration of the scroll animation in milliseconds. */ public void smoothScrollBy(int distance, int duration) { + smoothScrollBy(distance, duration, false); + } + + void smoothScrollBy(int distance, int duration, boolean linear) { if (mFlingRunnable == null) { mFlingRunnable = new FlingRunnable(); } @@ -4414,7 +4433,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } } else { reportScrollStateChange(OnScrollListener.SCROLL_STATE_FLING); - mFlingRunnable.startScroll(distance, duration); + mFlingRunnable.startScroll(distance, duration, linear); } } diff --git a/core/java/android/widget/Advanceable.java b/core/java/android/widget/Advanceable.java index dc13ebb7764f..ad8e101b1caa 100644 --- a/core/java/android/widget/Advanceable.java +++ b/core/java/android/widget/Advanceable.java @@ -21,7 +21,6 @@ package android.widget; * progressing through its set of children. The interface exists to give AppWidgetHosts a way of * taking responsibility for automatically advancing such collections. * - * @hide */ public interface Advanceable { diff --git a/core/java/android/widget/OverScroller.java b/core/java/android/widget/OverScroller.java index 6aee5a07e030..1c72a0d08a03 100644 --- a/core/java/android/widget/OverScroller.java +++ b/core/java/android/widget/OverScroller.java @@ -35,7 +35,7 @@ public class OverScroller { private final SplineOverScroller mScrollerX; private final SplineOverScroller mScrollerY; - private final Interpolator mInterpolator; + private Interpolator mInterpolator; private final boolean mFlywheel; @@ -113,6 +113,10 @@ public class OverScroller { this(context, interpolator, flywheel); } + void setInterpolator(Interpolator interpolator) { + mInterpolator = interpolator; + } + /** * The amount of friction applied to flings. The default value * is {@link ViewConfiguration#getScrollFriction}. diff --git a/core/java/android/widget/SpellChecker.java b/core/java/android/widget/SpellChecker.java index a91b16e87601..98e45fbe3e4c 100644 --- a/core/java/android/widget/SpellChecker.java +++ b/core/java/android/widget/SpellChecker.java @@ -457,7 +457,16 @@ public class SpellChecker implements SpellCheckerSessionListener { public void parse() { Editable editable = (Editable) mTextView.getText(); // Iterate over the newly added text and schedule new SpellCheckSpans - final int start = editable.getSpanStart(mRange); + final int start; + if (mIsSentenceSpellCheckSupported) { + // TODO: Find the start position of the sentence. + // Set span with the context + start = Math.max( + 0, editable.getSpanStart(mRange) - MIN_SENTENCE_LENGTH); + } else { + start = editable.getSpanStart(mRange); + } + final int end = editable.getSpanEnd(mRange); int wordIteratorWindowEnd = Math.min(end, start + WORD_ITERATOR_INTERVAL); @@ -512,9 +521,7 @@ public class SpellChecker implements SpellCheckerSessionListener { return; } // TODO: Find the start position of the sentence. - // Set span with the context - final int spellCheckStart = Math.max( - 0, Math.min(wordStart, regionEnd - MIN_SENTENCE_LENGTH)); + final int spellCheckStart = wordStart; if (regionEnd <= spellCheckStart) { return; } diff --git a/core/java/com/android/internal/app/IMediaContainerService.aidl b/core/java/com/android/internal/app/IMediaContainerService.aidl index 4322a200d303..727c09442dca 100755 --- a/core/java/com/android/internal/app/IMediaContainerService.aidl +++ b/core/java/com/android/internal/app/IMediaContainerService.aidl @@ -22,14 +22,14 @@ import android.content.pm.PackageInfoLite; import android.content.res.ObbInfo; interface IMediaContainerService { - String copyResourceToContainer(in Uri packageURI, - String containerId, - String key, String resFileName); + String copyResourceToContainer(in Uri packageURI, String containerId, String key, + String resFileName, String publicResFileName, boolean isExternal, + boolean isForwardLocked); int copyResource(in Uri packageURI, in ParcelFileDescriptor outStream); PackageInfoLite getMinimalPackageInfo(in Uri fileUri, in int flags, in long threshold); - boolean checkInternalFreeStorage(in Uri fileUri, in long threshold); - boolean checkExternalFreeStorage(in Uri fileUri); + boolean checkInternalFreeStorage(in Uri fileUri, boolean isForwardLocked, in long threshold); + boolean checkExternalFreeStorage(in Uri fileUri, boolean isForwardLocked); ObbInfo getObbInfo(in String filename); long calculateDirectorySize(in String directory); /** Return file system stats: [0] is total bytes, [1] is available bytes */ diff --git a/core/java/com/android/internal/app/RingtonePickerActivity.java b/core/java/com/android/internal/app/RingtonePickerActivity.java deleted file mode 100644 index 36fc24ea7210..000000000000 --- a/core/java/com/android/internal/app/RingtonePickerActivity.java +++ /dev/null @@ -1,362 +0,0 @@ -/* - * Copyright (C) 2007 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.internal.app; - -import com.android.internal.app.AlertActivity; -import com.android.internal.app.AlertController; - -import android.content.DialogInterface; -import android.content.Intent; -import android.database.Cursor; -import android.media.Ringtone; -import android.media.RingtoneManager; -import android.net.Uri; -import android.os.Bundle; -import android.os.Handler; -import android.provider.MediaStore; -import android.provider.Settings; -import android.view.View; -import android.widget.AdapterView; -import android.widget.ListView; -import android.widget.TextView; - -/** - * The {@link RingtonePickerActivity} allows the user to choose one from all of the - * available ringtones. The chosen ringtone's URI will be persisted as a string. - * - * @see RingtoneManager#ACTION_RINGTONE_PICKER - */ -public final class RingtonePickerActivity extends AlertActivity implements - AdapterView.OnItemSelectedListener, Runnable, DialogInterface.OnClickListener, - AlertController.AlertParams.OnPrepareListViewListener { - - private static final String TAG = "RingtonePickerActivity"; - - private static final int DELAY_MS_SELECTION_PLAYED = 300; - - private static final String SAVE_CLICKED_POS = "clicked_pos"; - - private RingtoneManager mRingtoneManager; - - private Cursor mCursor; - private Handler mHandler; - - /** The position in the list of the 'Silent' item. */ - private int mSilentPos = -1; - - /** The position in the list of the 'Default' item. */ - private int mDefaultRingtonePos = -1; - - /** The position in the list of the last clicked item. */ - private int mClickedPos = -1; - - /** The position in the list of the ringtone to sample. */ - private int mSampleRingtonePos = -1; - - /** Whether this list has the 'Silent' item. */ - private boolean mHasSilentItem; - - /** The Uri to place a checkmark next to. */ - private Uri mExistingUri; - - /** The number of static items in the list. */ - private int mStaticItemCount; - - /** Whether this list has the 'Default' item. */ - private boolean mHasDefaultItem; - - /** The Uri to play when the 'Default' item is clicked. */ - private Uri mUriForDefaultItem; - - /** - * A Ringtone for the default ringtone. In most cases, the RingtoneManager - * will stop the previous ringtone. However, the RingtoneManager doesn't - * manage the default ringtone for us, so we should stop this one manually. - */ - private Ringtone mDefaultRingtone; - - private DialogInterface.OnClickListener mRingtoneClickListener = - new DialogInterface.OnClickListener() { - - /* - * On item clicked - */ - public void onClick(DialogInterface dialog, int which) { - // Save the position of most recently clicked item - mClickedPos = which; - - // Play clip - playRingtone(which, 0); - } - - }; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - mHandler = new Handler(); - - Intent intent = getIntent(); - - /* - * Get whether to show the 'Default' item, and the URI to play when the - * default is clicked - */ - mHasDefaultItem = intent.getBooleanExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, true); - mUriForDefaultItem = intent.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_DEFAULT_URI); - if (mUriForDefaultItem == null) { - mUriForDefaultItem = Settings.System.DEFAULT_RINGTONE_URI; - } - - if (savedInstanceState != null) { - mClickedPos = savedInstanceState.getInt(SAVE_CLICKED_POS, -1); - } - // Get whether to show the 'Silent' item - mHasSilentItem = intent.getBooleanExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT, true); - - // Give the Activity so it can do managed queries - mRingtoneManager = new RingtoneManager(this); - - // Get whether to include DRM ringtones - boolean includeDrm = intent.getBooleanExtra(RingtoneManager.EXTRA_RINGTONE_INCLUDE_DRM, - true); - mRingtoneManager.setIncludeDrm(includeDrm); - - // Get the types of ringtones to show - int types = intent.getIntExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, -1); - if (types != -1) { - mRingtoneManager.setType(types); - } - - mCursor = mRingtoneManager.getCursor(); - - // The volume keys will control the stream that we are choosing a ringtone for - setVolumeControlStream(mRingtoneManager.inferStreamType()); - - // Get the URI whose list item should have a checkmark - mExistingUri = intent - .getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI); - - final AlertController.AlertParams p = mAlertParams; - p.mCursor = mCursor; - p.mOnClickListener = mRingtoneClickListener; - p.mLabelColumn = MediaStore.Audio.Media.TITLE; - p.mIsSingleChoice = true; - p.mOnItemSelectedListener = this; - p.mPositiveButtonText = getString(com.android.internal.R.string.ok); - p.mPositiveButtonListener = this; - p.mNegativeButtonText = getString(com.android.internal.R.string.cancel); - p.mPositiveButtonListener = this; - p.mOnPrepareListViewListener = this; - - p.mTitle = intent.getCharSequenceExtra(RingtoneManager.EXTRA_RINGTONE_TITLE); - if (p.mTitle == null) { - p.mTitle = getString(com.android.internal.R.string.ringtone_picker_title); - } - - setupAlert(); - } - - @Override - public void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - outState.putInt(SAVE_CLICKED_POS, mClickedPos); - } - - public void onPrepareListView(ListView listView) { - - if (mHasDefaultItem) { - mDefaultRingtonePos = addDefaultRingtoneItem(listView); - - if (RingtoneManager.isDefault(mExistingUri)) { - mClickedPos = mDefaultRingtonePos; - } - } - - if (mHasSilentItem) { - mSilentPos = addSilentItem(listView); - - // The 'Silent' item should use a null Uri - if (mExistingUri == null) { - mClickedPos = mSilentPos; - } - } - - if (mClickedPos == -1) { - mClickedPos = getListPosition(mRingtoneManager.getRingtonePosition(mExistingUri)); - } - - // Put a checkmark next to an item. - mAlertParams.mCheckedItem = mClickedPos; - } - - /** - * Adds a static item to the top of the list. A static item is one that is not from the - * RingtoneManager. - * - * @param listView The ListView to add to. - * @param textResId The resource ID of the text for the item. - * @return The position of the inserted item. - */ - private int addStaticItem(ListView listView, int textResId) { - TextView textView = (TextView) getLayoutInflater().inflate( - com.android.internal.R.layout.select_dialog_singlechoice_holo, listView, false); - textView.setText(textResId); - listView.addHeaderView(textView); - mStaticItemCount++; - return listView.getHeaderViewsCount() - 1; - } - - private int addDefaultRingtoneItem(ListView listView) { - return addStaticItem(listView, com.android.internal.R.string.ringtone_default); - } - - private int addSilentItem(ListView listView) { - return addStaticItem(listView, com.android.internal.R.string.ringtone_silent); - } - - /* - * On click of Ok/Cancel buttons - */ - public void onClick(DialogInterface dialog, int which) { - boolean positiveResult = which == DialogInterface.BUTTON_POSITIVE; - - // Stop playing the previous ringtone - mRingtoneManager.stopPreviousRingtone(); - - if (positiveResult) { - Intent resultIntent = new Intent(); - Uri uri = null; - - if (mClickedPos == mDefaultRingtonePos) { - // Set it to the default Uri that they originally gave us - uri = mUriForDefaultItem; - } else if (mClickedPos == mSilentPos) { - // A null Uri is for the 'Silent' item - uri = null; - } else { - uri = mRingtoneManager.getRingtoneUri(getRingtoneManagerPosition(mClickedPos)); - } - - resultIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI, uri); - setResult(RESULT_OK, resultIntent); - } else { - setResult(RESULT_CANCELED); - } - - getWindow().getDecorView().post(new Runnable() { - public void run() { - mCursor.deactivate(); - } - }); - - finish(); - } - - /* - * On item selected via keys - */ - public void onItemSelected(AdapterView parent, View view, int position, long id) { - playRingtone(position, DELAY_MS_SELECTION_PLAYED); - } - - public void onNothingSelected(AdapterView parent) { - } - - private void playRingtone(int position, int delayMs) { - mHandler.removeCallbacks(this); - mSampleRingtonePos = position; - mHandler.postDelayed(this, delayMs); - } - - public void run() { - - if (mSampleRingtonePos == mSilentPos) { - mRingtoneManager.stopPreviousRingtone(); - return; - } - - /* - * Stop the default ringtone, if it's playing (other ringtones will be - * stopped by the RingtoneManager when we get another Ringtone from it. - */ - if (mDefaultRingtone != null && mDefaultRingtone.isPlaying()) { - mDefaultRingtone.stop(); - mDefaultRingtone = null; - } - - Ringtone ringtone; - if (mSampleRingtonePos == mDefaultRingtonePos) { - if (mDefaultRingtone == null) { - mDefaultRingtone = RingtoneManager.getRingtone(this, mUriForDefaultItem); - } - ringtone = mDefaultRingtone; - - /* - * Normally the non-static RingtoneManager.getRingtone stops the - * previous ringtone, but we're getting the default ringtone outside - * of the RingtoneManager instance, so let's stop the previous - * ringtone manually. - */ - mRingtoneManager.stopPreviousRingtone(); - - } else { - ringtone = mRingtoneManager.getRingtone(getRingtoneManagerPosition(mSampleRingtonePos)); - } - - if (ringtone != null) { - ringtone.play(); - } - } - - @Override - protected void onStop() { - super.onStop(); - stopAnyPlayingRingtone(); - } - - @Override - protected void onPause() { - super.onPause(); - stopAnyPlayingRingtone(); - } - - private void stopAnyPlayingRingtone() { - - if (mDefaultRingtone != null && mDefaultRingtone.isPlaying()) { - mDefaultRingtone.stop(); - } - - if (mRingtoneManager != null) { - mRingtoneManager.stopPreviousRingtone(); - } - } - - private int getRingtoneManagerPosition(int listPos) { - return listPos - mStaticItemCount; - } - - private int getListPosition(int ringtoneManagerPos) { - - // If the manager position is -1 (for not found), return that - if (ringtoneManagerPos < 0) return ringtoneManagerPos; - - return ringtoneManagerPos + mStaticItemCount; - } - -} diff --git a/core/java/com/android/internal/content/PackageHelper.java b/core/java/com/android/internal/content/PackageHelper.java index 61866e5fb7de..48ed5613e385 100644 --- a/core/java/com/android/internal/content/PackageHelper.java +++ b/core/java/com/android/internal/content/PackageHelper.java @@ -67,8 +67,8 @@ public class PackageHelper { return null; } - public static String createSdDir(int sizeMb, String cid, - String sdEncKey, int uid) { + public static String createSdDir(int sizeMb, String cid, String sdEncKey, int uid, + boolean isExternal) { // Create mount point via MountService IMountService mountService = getMountService(); @@ -76,8 +76,8 @@ public class PackageHelper { Log.i(TAG, "Size of container " + sizeMb + " MB"); try { - int rc = mountService.createSecureContainer( - cid, sizeMb, "fat", sdEncKey, uid); + int rc = mountService.createSecureContainer(cid, sizeMb, "ext4", sdEncKey, uid, + isExternal); if (rc != StorageResultCode.OperationSucceeded) { Log.e(TAG, "Failed to create secure container " + cid); return null; @@ -206,10 +206,21 @@ public class PackageHelper { return false; } - public static void extractPublicFiles(String packagePath, File publicZipFile) + public static int extractPublicFiles(String packagePath, File publicZipFile) throws IOException { - final FileOutputStream fstr = new FileOutputStream(publicZipFile); - final ZipOutputStream publicZipOutStream = new ZipOutputStream(fstr); + final FileOutputStream fstr; + final ZipOutputStream publicZipOutStream; + + if (publicZipFile == null) { + fstr = null; + publicZipOutStream = null; + } else { + fstr = new FileOutputStream(publicZipFile); + publicZipOutStream = new ZipOutputStream(fstr); + } + + int size = 0; + try { final ZipFile privateZip = new ZipFile(packagePath); try { @@ -219,25 +230,29 @@ public class PackageHelper { if ("AndroidManifest.xml".equals(zipEntryName) || "resources.arsc".equals(zipEntryName) || zipEntryName.startsWith("res/")) { - copyZipEntry(zipEntry, privateZip, publicZipOutStream); + size += zipEntry.getSize(); + if (publicZipFile != null) { + copyZipEntry(zipEntry, privateZip, publicZipOutStream); + } } } } finally { - try { - privateZip.close(); - } catch (IOException e) { - } + try { privateZip.close(); } catch (IOException e) {} } - publicZipOutStream.finish(); - publicZipOutStream.flush(); - FileUtils.sync(fstr); - publicZipOutStream.close(); - FileUtils.setPermissions(publicZipFile.getAbsolutePath(), FileUtils.S_IRUSR - | FileUtils.S_IWUSR | FileUtils.S_IRGRP | FileUtils.S_IROTH, -1, -1); + if (publicZipFile != null) { + publicZipOutStream.finish(); + publicZipOutStream.flush(); + FileUtils.sync(fstr); + publicZipOutStream.close(); + FileUtils.setPermissions(publicZipFile.getAbsolutePath(), FileUtils.S_IRUSR + | FileUtils.S_IWUSR | FileUtils.S_IRGRP | FileUtils.S_IROTH, -1, -1); + } } finally { IoUtils.closeQuietly(publicZipOutStream); } + + return size; } private static void copyZipEntry(ZipEntry zipEntry, ZipFile inZipFile, @@ -265,4 +280,18 @@ public class PackageHelper { IoUtils.closeQuietly(data); } } + + public static boolean fixSdPermissions(String cid, int gid, String filename) { + try { + int rc = getMountService().fixPermissionsSecureContainer(cid, gid, filename); + if (rc != StorageResultCode.OperationSucceeded) { + Log.i(TAG, "Failed to fixperms container " + cid); + return false; + } + return true; + } catch (RemoteException e) { + Log.e(TAG, "Failed to fixperms container " + cid + " with exception " + e); + } + return false; + } } diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp index dd59444fdabd..5507047ddf4c 100644 --- a/core/jni/android/graphics/BitmapFactory.cpp +++ b/core/jni/android/graphics/BitmapFactory.cpp @@ -322,6 +322,7 @@ static jobject doDecode(JNIEnv* env, SkStream* stream, jobject padding, const float sy = scaledHeight / float(decoded->height()); bitmap->setConfig(decoded->getConfig(), scaledWidth, scaledHeight); + bitmap->setIsOpaque(decoded->isOpaque()); bitmap->allocPixels(&javaAllocator, NULL); bitmap->eraseColor(0); diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index e1b9d559a501..3ae2b4ec8283 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -112,6 +112,13 @@ <protected-broadcast android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" /> <protected-broadcast android:name="android.hardware.usb.action.USB_DEVICE_DETACHED" /> + <protected-broadcast android:name="android.intent.action.HEADSET_PLUG" /> + <protected-broadcast android:name="android.intent.action.ANALOG_AUDIO_DOCK_PLUG" /> + <protected-broadcast android:name="android.intent.action.DIGITAL_AUDIO_DOCK_PLUG" /> + <protected-broadcast android:name="android.intent.action.HDMI_AUDIO_PLUG" /> + <protected-broadcast android:name="android.intent.action.USB_AUDIO_ACCESSORY_PLUG" /> + <protected-broadcast android:name="android.intent.action.USB_AUDIO_DEVICE_PLUG" /> + <protected-broadcast android:name="android.net.conn.CONNECTIVITY_CHANGE" /> <protected-broadcast android:name="android.net.conn.CONNECTIVITY_CHANGE_IMMEDIATE" /> @@ -1658,16 +1665,6 @@ android:excludeFromRecents="true" android:process=":ui"> </activity> - <activity android:name="com.android.internal.app.RingtonePickerActivity" - android:theme="@style/Theme.Holo.Dialog.Alert" - android:excludeFromRecents="true" - android:multiprocess="true" - android:process=":ui"> - <intent-filter> - <action android:name="android.intent.action.RINGTONE_PICKER" /> - <category android:name="android.intent.category.DEFAULT" /> - </intent-filter> - </activity> <activity android:name="android.accounts.ChooseAccountActivity" android:excludeFromRecents="true" diff --git a/core/res/res/values-sw600dp/config.xml b/core/res/res/values-sw600dp/config.xml index 49c88931f105..7fa76589957d 100644 --- a/core/res/res/values-sw600dp/config.xml +++ b/core/res/res/values-sw600dp/config.xml @@ -21,7 +21,7 @@ for different hardware and product builds. --> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <!-- see comment in values/config.xml --> - <integer name="config_longPressOnPowerBehavior">1</integer> + <integer name="config_longPressOnPowerBehavior">2</integer> <!-- Enable lockscreen rotation --> <bool name="config_enableLockScreenRotation">true</bool> diff --git a/core/tests/coretests/src/android/content/pm/PackageHelperTests.java b/core/tests/coretests/src/android/content/pm/PackageHelperTests.java index 27112a6a168d..7ad35d082f59 100644 --- a/core/tests/coretests/src/android/content/pm/PackageHelperTests.java +++ b/core/tests/coretests/src/android/content/pm/PackageHelperTests.java @@ -81,7 +81,8 @@ public class PackageHelperTests extends AndroidTestCase { public void testMountAndPullSdCard() { try { fullId = PREFIX; - fullId2 = PackageHelper.createSdDir(1024, fullId, "none", android.os.Process.myUid()); + fullId2 = PackageHelper.createSdDir(1024, fullId, "none", android.os.Process.myUid(), + true); Log.d(TAG,PackageHelper.getSdDir(fullId)); PackageHelper.unMountSdDir(fullId); diff --git a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java index 580b4da073e0..8a5f8bb5f783 100755 --- a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java +++ b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java @@ -309,9 +309,7 @@ public class PackageManagerTests extends AndroidTestCase { private static final int INSTALL_LOC_ERR = -1; private int getInstallLoc(int flags, int expInstallLocation, long pkgLen) { // Flags explicitly over ride everything else. - if ((flags & PackageManager.INSTALL_FORWARD_LOCK) != 0 ) { - return INSTALL_LOC_INT; - } else if ((flags & PackageManager.INSTALL_EXTERNAL) != 0 ) { + if ((flags & PackageManager.INSTALL_EXTERNAL) != 0 ) { return INSTALL_LOC_SD; } else if ((flags & PackageManager.INSTALL_INTERNAL) != 0) { return INSTALL_LOC_INT; @@ -380,61 +378,76 @@ public class PackageManagerTests extends AndroidTestCase { String publicSrcPath = publicSrcDir.getParent(); long pkgLen = new File(info.sourceDir).length(); - if ((flags & PackageManager.INSTALL_FORWARD_LOCK) != 0) { - assertTrue((info.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0); - assertEquals(srcPath, drmInstallPath); - assertEquals(publicSrcPath, appInstallPath); - assertTrue(info.nativeLibraryDir.startsWith(dataDir.getPath())); - } else { - assertFalse((info.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0); - int rLoc = getInstallLoc(flags, expInstallLocation, pkgLen); - if (rLoc == INSTALL_LOC_INT) { - assertEquals(srcPath, appInstallPath); - assertEquals(publicSrcPath, appInstallPath); - assertFalse((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0); - assertTrue(info.nativeLibraryDir.startsWith(dataDir.getPath())); - - // Make sure the native library dir is not a symlink - final File nativeLibDir = new File(info.nativeLibraryDir); - assertTrue("Native library dir should exist at " + info.nativeLibraryDir, - nativeLibDir.exists()); - try { - assertEquals("Native library dir should not be a symlink", - info.nativeLibraryDir, - nativeLibDir.getCanonicalPath()); - } catch (IOException e) { - fail("Can't read " + nativeLibDir.getPath()); - } - } else if (rLoc == INSTALL_LOC_SD){ - assertTrue("Application flags (" + info.flags - + ") should contain FLAG_EXTERNAL_STORAGE", - (info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0); + int rLoc = getInstallLoc(flags, expInstallLocation, pkgLen); + if (rLoc == INSTALL_LOC_INT) { + if ((flags & PackageManager.INSTALL_FORWARD_LOCK) != 0) { + assertTrue("The application should be installed forward locked", + (info.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0); assertTrue("The APK path (" + srcPath + ") should start with " - + SECURE_CONTAINERS_PREFIX, srcPath - .startsWith(SECURE_CONTAINERS_PREFIX)); + + SECURE_CONTAINERS_PREFIX, + srcPath.startsWith(SECURE_CONTAINERS_PREFIX)); assertTrue("The public APK path (" + publicSrcPath + ") should start with " - + SECURE_CONTAINERS_PREFIX, publicSrcPath - .startsWith(SECURE_CONTAINERS_PREFIX)); + + SECURE_CONTAINERS_PREFIX, + publicSrcPath.startsWith(SECURE_CONTAINERS_PREFIX)); assertTrue("The native library path (" + info.nativeLibraryDir + ") should start with " + SECURE_CONTAINERS_PREFIX, info.nativeLibraryDir.startsWith(SECURE_CONTAINERS_PREFIX)); + } else { + assertFalse((info.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0); + assertEquals(srcPath, appInstallPath); + assertEquals(publicSrcPath, appInstallPath); + assertTrue(info.nativeLibraryDir.startsWith(dataDir.getPath())); + } + assertFalse((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0); - // Make sure the native library in /data/data/<app>/lib is a - // symlink to the ASEC - final File nativeLibSymLink = new File(info.dataDir, "lib"); - assertTrue("Native library symlink should exist at " + nativeLibSymLink.getPath(), - nativeLibSymLink.exists()); - try { - assertEquals(nativeLibSymLink.getPath() + " should be a symlink to " - + info.nativeLibraryDir, info.nativeLibraryDir, nativeLibSymLink - .getCanonicalPath()); - } catch (IOException e) { - fail("Can't read " + nativeLibSymLink.getPath()); - } + // Make sure the native library dir is not a symlink + final File nativeLibDir = new File(info.nativeLibraryDir); + assertTrue("Native library dir should exist at " + info.nativeLibraryDir, + nativeLibDir.exists()); + try { + assertEquals("Native library dir should not be a symlink", + info.nativeLibraryDir, + nativeLibDir.getCanonicalPath()); + } catch (IOException e) { + fail("Can't read " + nativeLibDir.getPath()); + } + } else if (rLoc == INSTALL_LOC_SD){ + if ((flags & PackageManager.INSTALL_FORWARD_LOCK) != 0) { + assertTrue("The application should be installed forward locked", + (info.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0); } else { - // TODO handle error. Install should have failed. - fail("Install should have failed"); + assertFalse("The application should not be installed forward locked", + (info.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0); + } + assertTrue("Application flags (" + info.flags + + ") should contain FLAG_EXTERNAL_STORAGE", + (info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0); + // Might need to check: + // ((info.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0) + assertTrue("The APK path (" + srcPath + ") should start with " + + SECURE_CONTAINERS_PREFIX, srcPath.startsWith(SECURE_CONTAINERS_PREFIX)); + assertTrue("The public APK path (" + publicSrcPath + ") should start with " + + SECURE_CONTAINERS_PREFIX, + publicSrcPath.startsWith(SECURE_CONTAINERS_PREFIX)); + assertTrue("The native library path (" + info.nativeLibraryDir + + ") should start with " + SECURE_CONTAINERS_PREFIX, + info.nativeLibraryDir.startsWith(SECURE_CONTAINERS_PREFIX)); + + // Make sure the native library in /data/data/<app>/lib is a + // symlink to the ASEC + final File nativeLibSymLink = new File(info.dataDir, "lib"); + assertTrue("Native library symlink should exist at " + nativeLibSymLink.getPath(), + nativeLibSymLink.exists()); + try { + assertEquals(nativeLibSymLink.getPath() + " should be a symlink to " + + info.nativeLibraryDir, info.nativeLibraryDir, nativeLibSymLink + .getCanonicalPath()); + } catch (IOException e) { + fail("Can't read " + nativeLibSymLink.getPath()); } + } else { + // TODO handle error. Install should have failed. + fail("Install should have failed"); } } catch (NameNotFoundException e) { failStr("failed with exception : " + e); @@ -1774,15 +1787,17 @@ public class PackageManagerTests extends AndroidTestCase { } /* - * Install an app with both external and forward-lock flags set. should fail + * Install an app with both external and forward-lock flags set. */ @LargeTest public void testFlagEF() { - installFromRawResource("install.apk", R.raw.install, - PackageManager.INSTALL_FORWARD_LOCK | PackageManager.INSTALL_EXTERNAL, - false, - true, PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION, - PackageInfo.INSTALL_LOCATION_AUTO); + // Do not run on devices with emulated external storage. + if (Environment.isExternalStorageEmulated()) { + return; + } + + sampleInstallFromRawResource(PackageManager.INSTALL_FORWARD_LOCK + | PackageManager.INSTALL_EXTERNAL, true); } /* @@ -1899,15 +1914,20 @@ public class PackageManagerTests extends AndroidTestCase { PackageManager.INSTALL_FORWARD_LOCK, true, false, -1, - PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL); + PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY); } /* * Install an app with fwd locked flag set and install location set to - * preferExternal. should install internally. + * preferExternal. Should install externally. */ @LargeTest public void testFlagFManifestE() { + // Do not run on devices with emulated external storage. + if (Environment.isExternalStorageEmulated()) { + return; + } + installFromRawResource("install.apk", R.raw.install_loc_sdcard, PackageManager.INSTALL_FORWARD_LOCK, true, @@ -1916,11 +1936,16 @@ public class PackageManagerTests extends AndroidTestCase { } /* - * Install an app with fwd locked flag set and install location set to - * auto. should install internally. + * Install an app with fwd locked flag set and install location set to auto. + * should install externally. */ @LargeTest public void testFlagFManifestA() { + // Do not run on devices with emulated external storage. + if (Environment.isExternalStorageEmulated()) { + return; + } + installFromRawResource("install.apk", R.raw.install_loc_auto, PackageManager.INSTALL_FORWARD_LOCK, true, diff --git a/core/tests/coretests/src/android/os/storage/AsecTests.java b/core/tests/coretests/src/android/os/storage/AsecTests.java index 5efbd8853060..abb8eaeb8f27 100755 --- a/core/tests/coretests/src/android/os/storage/AsecTests.java +++ b/core/tests/coretests/src/android/os/storage/AsecTests.java @@ -27,20 +27,13 @@ import android.util.Log; import java.io.File; import java.io.FileOutputStream; -import junit.framework.Assert; - public class AsecTests extends AndroidTestCase { + private static final String SECURE_CONTAINER_PREFIX = "com.android.unittests.AsecTests."; private static final boolean localLOGV = true; public static final String TAG="AsecTests"; - void failStr(String errMsg) { - Log.w(TAG, "errMsg="+errMsg); - } - - void failStr(Exception e) { - Log.w(TAG, "e.getMessage="+e.getMessage()); - Log.w(TAG, "e="+e); - } + private static final String FS_FAT = "fat"; + private static final String FS_EXT4 = "ext4"; @Override protected void setUp() throws Exception { @@ -61,7 +54,9 @@ public class AsecTests extends AndroidTestCase { String[] containers = ms.getSecureContainerList(); for (int i = 0; i < containers.length; i++) { - if (containers[i].startsWith("com.android.unittests.AsecTests.")) { + if (containers[i].startsWith(SECURE_CONTAINER_PREFIX)) { + if (localLOGV) + Log.i(TAG, "Cleaning: " + containers[i]); ms.destroySecureContainer(containers[i], true); } } @@ -70,7 +65,7 @@ public class AsecTests extends AndroidTestCase { private boolean containerExists(String localId) throws RemoteException { IMountService ms = getMs(); String[] containers = ms.getSecureContainerList(); - String fullId = "com.android.unittests.AsecTests." + localId; + String fullId = SECURE_CONTAINER_PREFIX + localId; for (int i = 0; i < containers.length; i++) { if (containers[i].equals(fullId)) { @@ -80,50 +75,52 @@ public class AsecTests extends AndroidTestCase { return false; } - private int createContainer(String localId, int size, String key) throws RemoteException { - Assert.assertTrue(isMediaMounted()); - String fullId = "com.android.unittests.AsecTests." + localId; + private int createContainer(String localId, int size, String key, String filesystem, + boolean isExternal) throws Exception { + assertTrue("Media should be mounted", isMediaMounted()); + String fullId = SECURE_CONTAINER_PREFIX + localId; IMountService ms = getMs(); - return ms.createSecureContainer(fullId, size, "fat", key, android.os.Process.myUid()); + return ms.createSecureContainer(fullId, size, filesystem, key, android.os.Process.myUid(), + isExternal); } - private int mountContainer(String localId, String key) throws RemoteException { - Assert.assertTrue(isMediaMounted()); - String fullId = "com.android.unittests.AsecTests." + localId; + private int mountContainer(String localId, String key) throws Exception { + assertTrue("Media should be mounted", isMediaMounted()); + String fullId = SECURE_CONTAINER_PREFIX + localId; IMountService ms = getMs(); return ms.mountSecureContainer(fullId, key, android.os.Process.myUid()); } - private int renameContainer(String localId1, String localId2) throws RemoteException { - Assert.assertTrue(isMediaMounted()); - String fullId1 = "com.android.unittests.AsecTests." + localId1; - String fullId2 = "com.android.unittests.AsecTests." + localId2; + private int renameContainer(String localId1, String localId2) throws Exception { + assertTrue("Media should be mounted", isMediaMounted()); + String fullId1 = SECURE_CONTAINER_PREFIX + localId1; + String fullId2 = SECURE_CONTAINER_PREFIX + localId2; IMountService ms = getMs(); return ms.renameSecureContainer(fullId1, fullId2); } - private int unmountContainer(String localId, boolean force) throws RemoteException { - Assert.assertTrue(isMediaMounted()); - String fullId = "com.android.unittests.AsecTests." + localId; + private int unmountContainer(String localId, boolean force) throws Exception { + assertTrue("Media should be mounted", isMediaMounted()); + String fullId = SECURE_CONTAINER_PREFIX + localId; IMountService ms = getMs(); return ms.unmountSecureContainer(fullId, force); } - private int destroyContainer(String localId, boolean force) throws RemoteException { - Assert.assertTrue(isMediaMounted()); - String fullId = "com.android.unittests.AsecTests." + localId; + private int destroyContainer(String localId, boolean force) throws Exception { + assertTrue("Media should be mounted", isMediaMounted()); + String fullId = SECURE_CONTAINER_PREFIX + localId; IMountService ms = getMs(); return ms.destroySecureContainer(fullId, force); } - private boolean isContainerMounted(String localId) throws RemoteException { - Assert.assertTrue(isMediaMounted()); - String fullId = "com.android.unittests.AsecTests." + localId; + private boolean isContainerMounted(String localId) throws Exception { + assertTrue("Media should be mounted", isMediaMounted()); + String fullId = SECURE_CONTAINER_PREFIX + localId; IMountService ms = getMs(); return ms.isSecureContainerMounted(fullId); @@ -139,248 +136,392 @@ public class AsecTests extends AndroidTestCase { return null; } - private boolean isMediaMounted() { - try { + private boolean isMediaMounted() throws Exception { String mPath = Environment.getExternalStorageDirectory().toString(); String state = getMs().getVolumeState(mPath); return Environment.MEDIA_MOUNTED.equals(state); - } catch (RemoteException e) { - failStr(e); - return false; - } } - public void testCreateContainer() { - try { - Assert.assertEquals(StorageResultCode.OperationSucceeded, - createContainer("testCreateContainer", 4, "none")); - Assert.assertEquals(true, containerExists("testCreateContainer")); - } catch (Exception e) { - failStr(e); + + /* + * CREATE + */ + + public void test_Fat_External_Create_Success() throws Exception { + if (Environment.isExternalStorageEmulated()) { + return; } + + assertEquals(StorageResultCode.OperationSucceeded, + createContainer("testCreateContainer", 4, "none", FS_FAT, true)); + assertTrue(containerExists("testCreateContainer")); } - public void testCreateMinSizeContainer() { - try { - Assert.assertEquals(StorageResultCode.OperationSucceeded, - createContainer("testCreateContainer", 1, "none")); - Assert.assertEquals(true, containerExists("testCreateContainer")); - } catch (Exception e) { - failStr(e); + public void test_Ext4_External_Create_Success() throws Exception { + if (Environment.isExternalStorageEmulated()) { + return; } + + assertEquals(StorageResultCode.OperationSucceeded, + createContainer("testCreateContainer", 4, "none", FS_EXT4, true)); + assertTrue(containerExists("testCreateContainer")); } - public void testCreateZeroSizeContainer() { - try { - Assert.assertEquals(StorageResultCode.OperationFailedInternalError, - createContainer("testCreateZeroContainer", 0, "none")); - } catch (Exception e) { - failStr(e); - } + public void test_Fat_Internal_Create_Success() throws Exception { + assertEquals(StorageResultCode.OperationSucceeded, + createContainer("testCreateContainer", 4, "none", FS_FAT, false)); + assertTrue(containerExists("testCreateContainer")); } - public void testCreateDuplicateContainer() { - try { - Assert.assertEquals(StorageResultCode.OperationSucceeded, - createContainer("testCreateDupContainer", 4, "none")); + public void test_Ext4_Internal_Create_Success() throws Exception { + assertEquals(StorageResultCode.OperationSucceeded, + createContainer("testCreateContainer", 4, "none", FS_EXT4, false)); + assertTrue(containerExists("testCreateContainer")); + } - Assert.assertEquals(StorageResultCode.OperationFailedInternalError, - createContainer("testCreateDupContainer", 4, "none")); - } catch (Exception e) { - failStr(e); + + /* + * CREATE MIN SIZE + */ + + public void test_Fat_External_CreateMinSize_Success() throws Exception { + if (Environment.isExternalStorageEmulated()) { + return; } + + assertEquals(StorageResultCode.OperationSucceeded, + createContainer("testCreateContainer", 1, "none", FS_FAT, true)); + assertTrue(containerExists("testCreateContainer")); } - public void testDestroyContainer() { - try { - Assert.assertEquals(StorageResultCode.OperationSucceeded, - createContainer("testDestroyContainer", 4, "none")); - Assert.assertEquals(StorageResultCode.OperationSucceeded, - destroyContainer("testDestroyContainer", false)); - } catch (Exception e) { - failStr(e); + public void test_Ext4_External_CreateMinSize_Success() throws Exception { + if (Environment.isExternalStorageEmulated()) { + return; } + + assertEquals(StorageResultCode.OperationSucceeded, + createContainer("testCreateContainer", 1, "none", FS_EXT4, true)); + assertTrue(containerExists("testCreateContainer")); } - public void testMountContainer() { - try { - Assert.assertEquals(StorageResultCode.OperationSucceeded, - createContainer("testMountContainer", 4, "none")); + public void test_Fat_Internal_CreateMinSize_Success() throws Exception { + assertEquals(StorageResultCode.OperationSucceeded, + createContainer("testCreateContainer", 1, "none", FS_FAT, false)); + assertTrue(containerExists("testCreateContainer")); + } - Assert.assertEquals(StorageResultCode.OperationSucceeded, - unmountContainer("testMountContainer", false)); + public void test_Ext4_Internal_CreateMinSize_Success() throws Exception { + assertEquals(StorageResultCode.OperationSucceeded, + createContainer("testCreateContainer", 1, "none", FS_EXT4, false)); + assertTrue(containerExists("testCreateContainer")); + } + + + /* + * CREATE ZERO SIZE - FAIL CASE + */ - Assert.assertEquals(StorageResultCode.OperationSucceeded, - mountContainer("testMountContainer", "none")); - } catch (Exception e) { - failStr(e); + public void test_Fat_External_CreateZeroSize_Failure() throws Exception { + if (Environment.isExternalStorageEmulated()) { + return; } + + assertEquals(StorageResultCode.OperationFailedInternalError, + createContainer("testCreateZeroContainer", 0, "none", FS_FAT, true)); } - public void testMountBadKey() { - try { - Assert.assertEquals(StorageResultCode.OperationSucceeded, - createContainer("testMountBadKey", 4, "00000000000000000000000000000000")); + public void test_Ext4_External_CreateZeroSize_Failure() throws Exception { + if (Environment.isExternalStorageEmulated()) { + return; + } + + assertEquals(StorageResultCode.OperationFailedInternalError, + createContainer("testCreateZeroContainer", 0, "none", FS_EXT4, true)); + } - Assert.assertEquals(StorageResultCode.OperationSucceeded, - unmountContainer("testMountBadKey", false)); + public void test_Fat_Internal_CreateZeroSize_Failure() throws Exception { + assertEquals(StorageResultCode.OperationFailedInternalError, + createContainer("testCreateZeroContainer", 0, "none", FS_FAT, false)); + } - Assert.assertEquals(StorageResultCode.OperationFailedInternalError, - mountContainer("testMountContainer", "000000000000000000000000000000001")); + public void test_Ext4_Internal_CreateZeroSize_Failure() throws Exception { + assertEquals(StorageResultCode.OperationFailedInternalError, + createContainer("testCreateZeroContainer", 0, "none", FS_EXT4, false)); + } - Assert.assertEquals(StorageResultCode.OperationFailedInternalError, - mountContainer("testMountContainer", "none")); - } catch (Exception e) { - failStr(e); + + /* + * CREATE DUPLICATE - FAIL CASE + */ + + public void test_Fat_External_CreateDuplicate_Failure() throws Exception { + if (Environment.isExternalStorageEmulated()) { + return; } + + assertEquals(StorageResultCode.OperationSucceeded, + createContainer("testCreateDupContainer", 4, "none", FS_FAT, true)); + + assertEquals(StorageResultCode.OperationFailedInternalError, + createContainer("testCreateDupContainer", 4, "none", FS_FAT, true)); } - public void testNonExistPath() { - IMountService ms = getMs(); - try { - String path = ms.getSecureContainerPath("jparks.broke.it"); - failStr(path); - } catch (IllegalArgumentException e) { - } catch (Exception e) { - failStr(e); + public void test_Ext4_External_CreateDuplicate_Failure() throws Exception { + if (Environment.isExternalStorageEmulated()) { + return; } + + assertEquals(StorageResultCode.OperationSucceeded, + createContainer("testCreateDupContainer", 4, "none", FS_EXT4, true)); + + assertEquals(StorageResultCode.OperationFailedInternalError, + createContainer("testCreateDupContainer", 4, "none", FS_EXT4, true)); } - public void testUnmountBusyContainer() { - IMountService ms = getMs(); - try { - Assert.assertEquals(StorageResultCode.OperationSucceeded, - createContainer("testUnmountBusyContainer", 4, "none")); + public void test_Fat_Internal_CreateDuplicate_Failure() throws Exception { + assertEquals(StorageResultCode.OperationSucceeded, + createContainer("testCreateDupContainer", 4, "none", FS_FAT, false)); + + assertEquals(StorageResultCode.OperationFailedInternalError, + createContainer("testCreateDupContainer", 4, "none", FS_FAT, false)); + } + + public void test_Ext4_Internal_CreateDuplicate_Failure() throws Exception { + assertEquals(StorageResultCode.OperationSucceeded, + createContainer("testCreateDupContainer", 4, "none", FS_EXT4, false)); - String path = ms.getSecureContainerPath("com.android.unittests.AsecTests.testUnmountBusyContainer"); + assertEquals(StorageResultCode.OperationFailedInternalError, + createContainer("testCreateDupContainer", 4, "none", FS_EXT4, false)); + } - File f = new File(path, "reference"); - FileOutputStream fos = new FileOutputStream(f); - Assert.assertEquals(StorageResultCode.OperationFailedStorageBusy, - unmountContainer("testUnmountBusyContainer", false)); + /* + * DESTROY + */ - fos.close(); - Assert.assertEquals(StorageResultCode.OperationSucceeded, - unmountContainer("testUnmountBusyContainer", false)); - } catch (Exception e) { - failStr(e); + public void test_Fat_External_Destroy_Success() throws Exception { + if (Environment.isExternalStorageEmulated()) { + return; } + + assertEquals(StorageResultCode.OperationSucceeded, + createContainer("testDestroyContainer", 4, "none", FS_FAT, true)); + assertEquals(StorageResultCode.OperationSucceeded, + destroyContainer("testDestroyContainer", false)); } - public void testDestroyBusyContainer() { - IMountService ms = getMs(); - try { - Assert.assertEquals(StorageResultCode.OperationSucceeded, - createContainer("testDestroyBusyContainer", 4, "none")); + public void test_Ext4_External_Destroy_Success() throws Exception { + if (Environment.isExternalStorageEmulated()) { + return; + } + + assertEquals(StorageResultCode.OperationSucceeded, + createContainer("testDestroyContainer", 4, "none", FS_EXT4, true)); + assertEquals(StorageResultCode.OperationSucceeded, + destroyContainer("testDestroyContainer", false)); + } - String path = ms.getSecureContainerPath("com.android.unittests.AsecTests.testDestroyBusyContainer"); + public void test_Fat_Internal_Destroy_Success() throws Exception { + assertEquals(StorageResultCode.OperationSucceeded, + createContainer("testDestroyContainer", 4, "none", FS_FAT, false)); + assertEquals(StorageResultCode.OperationSucceeded, + destroyContainer("testDestroyContainer", false)); + } + + public void test_Ext4_Internal_Destroy_Success() throws Exception { + assertEquals(StorageResultCode.OperationSucceeded, + createContainer("testDestroyContainer", 4, "none", FS_EXT4, false)); + assertEquals(StorageResultCode.OperationSucceeded, + destroyContainer("testDestroyContainer", false)); + } - File f = new File(path, "reference"); - FileOutputStream fos = new FileOutputStream(f); - Assert.assertEquals(StorageResultCode.OperationFailedStorageBusy, - destroyContainer("testDestroyBusyContainer", false)); + /* + * MOUNT + */ - fos.close(); - Assert.assertEquals(StorageResultCode.OperationSucceeded, - destroyContainer("testDestroyBusyContainer", false)); - } catch (Exception e) { - failStr(e); + public void test_Fat_External_Mount() throws Exception { + if (Environment.isExternalStorageEmulated()) { + return; } + + assertEquals(StorageResultCode.OperationSucceeded, + createContainer("testMountContainer", 4, "none", FS_FAT, true)); + + assertEquals(StorageResultCode.OperationSucceeded, + unmountContainer("testMountContainer", false)); + + assertEquals(StorageResultCode.OperationSucceeded, + mountContainer("testMountContainer", "none")); } - public void testRenameContainer() { - try { - Assert.assertEquals(StorageResultCode.OperationSucceeded, - createContainer("testRenameContainer.1", 4, "none")); - Assert.assertEquals(StorageResultCode.OperationSucceeded, - unmountContainer("testRenameContainer.1", false)); + /* + * MOUNT BAD KEY - FAIL CASE + */ + + public void test_Fat_External_MountBadKey_Failure() throws Exception { + if (Environment.isExternalStorageEmulated()) { + return; + } + + assertEquals(StorageResultCode.OperationSucceeded, + createContainer("testMountBadKey", 4, "00000000000000000000000000000000", FS_FAT, + true)); + + assertEquals(StorageResultCode.OperationSucceeded, + unmountContainer("testMountBadKey", false)); + + assertEquals(StorageResultCode.OperationFailedInternalError, + mountContainer("testMountContainer", "000000000000000000000000000000001")); + + assertEquals(StorageResultCode.OperationFailedInternalError, + mountContainer("testMountContainer", "none")); + } - Assert.assertEquals(StorageResultCode.OperationSucceeded, - renameContainer("testRenameContainer.1", "testRenameContainer.2")); - Assert.assertEquals(false, containerExists("testRenameContainer.1")); - Assert.assertEquals(true, containerExists("testRenameContainer.2")); - } catch (Exception e) { - failStr(e); + public void test_Fat_External_UnmountBusy_Success() throws Exception { + if (Environment.isExternalStorageEmulated()) { + return; } + + IMountService ms = getMs(); + assertEquals(StorageResultCode.OperationSucceeded, + createContainer("testUnmountBusyContainer", 4, "none", FS_FAT, true)); + + String path = ms.getSecureContainerPath(SECURE_CONTAINER_PREFIX + + "testUnmountBusyContainer"); + + File f = new File(path, "reference"); + FileOutputStream fos = new FileOutputStream(f); + + assertEquals(StorageResultCode.OperationFailedStorageBusy, + unmountContainer("testUnmountBusyContainer", false)); + + fos.close(); + assertEquals(StorageResultCode.OperationSucceeded, + unmountContainer("testUnmountBusyContainer", false)); } - public void testRenameSrcMountedContainer() { - try { - Assert.assertEquals(StorageResultCode.OperationSucceeded, - createContainer("testRenameContainer.1", 4, "none")); + public void test_Fat_External_DestroyBusy() throws Exception { + if (Environment.isExternalStorageEmulated()) { + return; + } + + IMountService ms = getMs(); + + assertEquals(StorageResultCode.OperationSucceeded, + createContainer("testDestroyBusyContainer", 4, "none", FS_FAT, true)); + + String path = ms.getSecureContainerPath(SECURE_CONTAINER_PREFIX + + "testDestroyBusyContainer"); + + File f = new File(path, "reference"); + FileOutputStream fos = new FileOutputStream(f); + + assertEquals(StorageResultCode.OperationFailedStorageBusy, + destroyContainer("testDestroyBusyContainer", false)); - Assert.assertEquals(StorageResultCode.OperationFailedStorageMounted, - renameContainer("testRenameContainer.1", "testRenameContainer.2")); - } catch (Exception e) { - failStr(e); + fos.close(); + assertEquals(StorageResultCode.OperationSucceeded, + destroyContainer("testDestroyBusyContainer", false)); + } + + public void test_Fat_External_Rename_Success() throws Exception { + if (Environment.isExternalStorageEmulated()) { + return; } + + assertEquals(StorageResultCode.OperationSucceeded, + createContainer("testRenameContainer.1", 4, "none", FS_FAT, true)); + + assertEquals(StorageResultCode.OperationSucceeded, + unmountContainer("testRenameContainer.1", false)); + + assertEquals(StorageResultCode.OperationSucceeded, + renameContainer("testRenameContainer.1", "testRenameContainer.2")); + + assertFalse(containerExists("testRenameContainer.1")); + assertTrue(containerExists("testRenameContainer.2")); } - public void testRenameDstMountedContainer() { - try { - Assert.assertEquals(StorageResultCode.OperationSucceeded, - createContainer("testRenameContainer.1", 4, "none")); + public void test_Fat_External_RenameSrcMounted_Failure() throws Exception { + if (Environment.isExternalStorageEmulated()) { + return; + } - Assert.assertEquals(StorageResultCode.OperationSucceeded, - unmountContainer("testRenameContainer.1", false)); + assertEquals(StorageResultCode.OperationSucceeded, + createContainer("testRenameContainer.1", 4, "none", FS_FAT, true)); - Assert.assertEquals(StorageResultCode.OperationSucceeded, - createContainer("testRenameContainer.2", 4, "none")); + assertEquals(StorageResultCode.OperationFailedStorageMounted, + renameContainer("testRenameContainer.1", "testRenameContainer.2")); + } - Assert.assertEquals(StorageResultCode.OperationFailedStorageMounted, - renameContainer("testRenameContainer.1", "testRenameContainer.2")); - } catch (Exception e) { - failStr(e); + public void test_Fat_External_RenameDstMounted_Failure() throws Exception { + if (Environment.isExternalStorageEmulated()) { + return; } + + assertEquals(StorageResultCode.OperationSucceeded, + createContainer("testRenameContainer.1", 4, "none", FS_FAT, true)); + + assertEquals(StorageResultCode.OperationSucceeded, + unmountContainer("testRenameContainer.1", false)); + + assertEquals(StorageResultCode.OperationSucceeded, + createContainer("testRenameContainer.2", 4, "none", FS_FAT, true)); + + assertEquals(StorageResultCode.OperationFailedStorageMounted, + renameContainer("testRenameContainer.1", "testRenameContainer.2")); } - public void testContainerSize() { + public void test_Fat_External_Size_Success() throws Exception { + if (Environment.isExternalStorageEmulated()) { + return; + } + IMountService ms = getMs(); - try { - Assert.assertEquals(StorageResultCode.OperationSucceeded, - createContainer("testContainerSize", 1, "none")); - String path = ms.getSecureContainerPath("com.android.unittests.AsecTests.testUnmountBusyContainer"); - - byte[] buf = new byte[4096]; - File f = new File(path, "reference"); - FileOutputStream fos = new FileOutputStream(f); - for (int i = 0; i < (1024 * 1024); i+= buf.length) { - fos.write(buf); - } - fos.close(); - } catch (Exception e) { - failStr(e); + assertEquals(StorageResultCode.OperationSucceeded, + createContainer("testContainerSize", 1, "none", FS_FAT, true)); + String path = ms.getSecureContainerPath(SECURE_CONTAINER_PREFIX + "testContainerSize"); + + byte[] buf = new byte[4096]; + File f = new File(path, "reference"); + FileOutputStream fos = new FileOutputStream(f); + for (int i = 0; i < (1024 * 1024); i += buf.length) { + fos.write(buf); } + fos.close(); + } + + public void testGetSecureContainerPath_NonExistPath_Failure() throws Exception { + IMountService ms = getMs(); + assertNull("Getting the path for an invalid container should return null", + ms.getSecureContainerPath("jparks.broke.it")); } /*------------ Tests for unmounting volume ---*/ public final long MAX_WAIT_TIME=120*1000; public final long WAIT_TIME_INCR=20*1000; - boolean getMediaState() { - try { + + boolean getMediaState() throws Exception { String mPath = Environment.getExternalStorageDirectory().toString(); String state = getMs().getVolumeState(mPath); return Environment.MEDIA_MOUNTED.equals(state); - } catch (RemoteException e) { - return false; - } } - boolean mountMedia() { + boolean mountMedia() throws Exception { + if (Environment.isExternalStorageEmulated()) { + return true; + } + if (getMediaState()) { return true; } - try { + String mPath = Environment.getExternalStorageDirectory().toString(); int ret = getMs().mountVolume(mPath); return ret == StorageResultCode.OperationSucceeded; - } catch (RemoteException e) { - return false; - } } class StorageListener extends StorageEventListener { @@ -410,10 +551,15 @@ public class AsecTests extends AndroidTestCase { } } - private boolean unmountMedia() { + private void unmountMedia() throws Exception { + if (Environment.isExternalStorageEmulated()) { + return; + } + if (!getMediaState()) { - return true; + return; } + String path = Environment.getExternalStorageDirectory().toString(); StorageListener observer = new StorageListener(); StorageManager sm = (StorageManager) mContext.getSystemService(Context.STORAGE_SERVICE); @@ -428,17 +574,15 @@ public class AsecTests extends AndroidTestCase { waitTime += WAIT_TIME_INCR; } if(!observer.isDone()) { - throw new Exception("Timed out waiting for packageInstalled callback"); + fail("Timed out waiting for packageInstalled callback"); } - return true; } - } catch (Exception e) { - return false; } finally { sm.unregisterListener(observer); } } - public void testUnmount() { + + public void testUnmount() throws Exception { boolean oldStatus = getMediaState(); Log.i(TAG, "oldStatus="+oldStatus); try { @@ -446,7 +590,7 @@ public class AsecTests extends AndroidTestCase { if (!getMediaState()) { mountMedia(); } - assertTrue(unmountMedia()); + unmountMedia(); } finally { // Restore old status boolean currStatus = getMediaState(); @@ -472,7 +616,11 @@ public class AsecTests extends AndroidTestCase { * This test invokes unmount multiple time and expects the call back * to be invoked just once. */ - public void testUnmountMultiple() { + public void testUnmountMultiple() throws Exception { + if (Environment.isExternalStorageEmulated()) { + return; + } + boolean oldStatus = getMediaState(); StorageManager sm = (StorageManager) mContext.getSystemService(Context.STORAGE_SERVICE); MultipleStorageLis observer = new MultipleStorageLis(); @@ -494,12 +642,10 @@ public class AsecTests extends AndroidTestCase { waitTime += WAIT_TIME_INCR; } if(!observer.isDone()) { - failStr("Timed out waiting for packageInstalled callback"); + fail("Timed out waiting for packageInstalled callback"); } } assertEquals(observer.count, 1); - } catch (Exception e) { - failStr(e); } finally { sm.unregisterListener(observer); // Restore old status @@ -514,7 +660,7 @@ public class AsecTests extends AndroidTestCase { } } } - + class ShutdownObserver extends IMountShutdownObserver.Stub{ private boolean doneFlag = false; int statusCode; @@ -536,28 +682,26 @@ public class AsecTests extends AndroidTestCase { } - boolean invokeShutdown() { + void invokeShutdown() throws Exception { IMountService ms = getMs(); ShutdownObserver observer = new ShutdownObserver(); synchronized (observer) { - try { - ms.shutdown(observer); - return true; - } catch (RemoteException e) { - failStr(e); - } + ms.shutdown(observer); } - return false; } - public void testShutdown() { + public void testShutdown() throws Exception { + if (Environment.isExternalStorageEmulated()) { + return; + } + boolean oldStatus = getMediaState(); try { // Mount media firsts if (!getMediaState()) { mountMedia(); } - assertTrue(invokeShutdown()); + invokeShutdown(); } finally { // Restore old status boolean currStatus = getMediaState(); @@ -576,7 +720,11 @@ public class AsecTests extends AndroidTestCase { * This test invokes unmount multiple time and expects the call back * to be invoked just once. */ - public void testShutdownMultiple() { + public void testShutdownMultiple() throws Exception { + if (Environment.isExternalStorageEmulated()) { + return; + } + boolean oldStatus = getMediaState(); try { // Mount media firsts @@ -586,13 +734,9 @@ public class AsecTests extends AndroidTestCase { IMountService ms = getMs(); ShutdownObserver observer = new ShutdownObserver(); synchronized (observer) { - try { - ms.shutdown(observer); - for (int i = 0; i < 4; i++) { - ms.shutdown(null); - } - } catch (RemoteException e) { - failStr(e); + ms.shutdown(observer); + for (int i = 0; i < 4; i++) { + ms.shutdown(null); } } } finally { diff --git a/data/fonts/DroidNaskh-Regular-Shift.ttf b/data/fonts/DroidNaskh-Regular-Shift.ttf Binary files differindex bb9c70c2e232..de475ca6afb7 100644 --- a/data/fonts/DroidNaskh-Regular-Shift.ttf +++ b/data/fonts/DroidNaskh-Regular-Shift.ttf diff --git a/data/keyboards/Generic.kl b/data/keyboards/Generic.kl index 768ee5e99ff6..225c11a4b048 100644 --- a/data/keyboards/Generic.kl +++ b/data/keyboards/Generic.kl @@ -300,7 +300,7 @@ key 318 BUTTON_THUMBR # key 352 "KEY_OK" -# key 353 "KEY_SELECT" +key 353 DPAD_CENTER # key 354 "KEY_GOTO" # key 355 "KEY_CLEAR" # key 356 "KEY_POWER2" diff --git a/docs/html/guide/topics/fundamentals/processes-and-threads.jd b/docs/html/guide/topics/fundamentals/processes-and-threads.jd index 3d7710c78e4f..814d34edac4c 100644 --- a/docs/html/guide/topics/fundamentals/processes-and-threads.jd +++ b/docs/html/guide/topics/fundamentals/processes-and-threads.jd @@ -30,11 +30,12 @@ down the user interface</li> </div> </div> -<p>When an application component starts and the application does not have any other components +<p>When an application component starts and the process that should host that thread is not already running, the Android system starts a new Linux process for the application with a single thread of execution. By default, all components of the same application run in the same process and thread (called the "main" thread). If an application component starts and there already exists a process -for that application (because another component from the application exists), then the component is +for that application (because another component from the application exists or Android has been +able to retain its previous process cached in the background), then the component is started within that process and uses the same thread of execution. However, you can arrange for different components in your application to run in separate processes, and you can create additional threads for any process.</p> @@ -86,7 +87,10 @@ components running in the process and the state of those components. Processes importance are eliminated first, then those with the next lowest importance, and so on, as necessary to recover system resources.</p> -<p>There are five levels in the importance hierarchy. The following list presents the different +<p>The exact mapping of processes to importance and the management of these processes is +an implementation detail of the platform that changes over time. Broadly speaking, there +are five levels in the current implementation that are of most relevance to application +developers. The following list presents these different types of processes in order of importance (the first process is <em>most important</em> and is <em>killed last</em>):</p> @@ -100,18 +104,15 @@ types of processes in order of importance (the first process is <em>most importa android.app.Activity}'s {@link android.app.Activity#onResume onResume()} method has been called).</li> - <li>It hosts a {@link android.app.Service} that's bound to the activity that the user is -interacting with.</li> - - <li>It hosts a {@link android.app.Service} that's running "in the foreground"—the -service has called {@link android.app.Service#startForeground startForeground()}. - <li>It hosts a {@link android.app.Service} that's executing one of its lifecycle callbacks ({@link android.app.Service#onCreate onCreate()}, {@link android.app.Service#onStart onStart()}, or {@link android.app.Service#onDestroy onDestroy()}).</li> <li>It hosts a {@link android.content.BroadcastReceiver} that's executing its {@link android.content.BroadcastReceiver#onReceive onReceive()} method.</li> + + <li>Another foreground process has a dependency on this one: either bound + to a Service in this process, or using a Content Provider of the process.</li> </ul> <p>Generally, only a few foreground processes exist at any given time. They are killed only as @@ -130,43 +131,79 @@ visible to the user (its {@link android.app.Activity#onPause onPause()} method h This might occur, for example, if the foreground activity started a dialog, which allows the previous activity to be seen behind it.</li> - <li>It hosts a {@link android.app.Service} that's bound to a visible (or foreground) -activity.</li> + <li>Another visible process has a dependency on this one: either bound + to a Service in this process, or using a Content Provider of the process.</li> </ul> <p>A visible process is considered extremely important and will not be killed unless doing so is required to keep all foreground processes running. </p> </li> + <li><b>Perceptible process</b> + <p>A process that doesn't have any foreground or visible components, but is still + doing something that is directly perceptible by the user. A classic example of such + a process would be one doing background music playback. The main way applications + get into this state is through {@link android.app.Service#startForeground} or because + another perceptible process has a dependency on one of its services or content + providers. In addition, as of {@link android.os.Build.VERSION_CODES#HONEYCOMB}, + processes can go into this state when {@link android.app.Activity#onStop + Activity.onStop()} is executing, allowing the process to continue executing + critical code after no longer being visible to the user but before going + fully into the background.</p> + + <p>Like visible processes, a perceptible process is considered extremely important + and will not be killed unless doing so is required to keep all foreground and + visible processes running. </p> + </li> + <li><b>Service process</b> <p>A process that is running a service that has been started with the {@link -android.content.Context#startService startService()} method and does not fall into either of the two +android.content.Context#startService startService()} method and does not fall into any of the higher categories. Although service processes are not directly tied to anything the user sees, they -are generally doing things that the user cares about (such as playing music in the background or -downloading data on the network), so the system keeps them running unless there's not enough memory -to retain them along with all foreground and visible processes. </p> +are generally doing things that the user cares about (such as downloading a file the user has requested), +so the system keeps them running unless there's not enough memory to retain them along with all +foreground and visible processes. </p> + + <p>Even though Android tries to keep these processes running, it is considered normal + operation for them to temporarily be killed to support the needs of more important + processes. For example, if the user opens a very heavy-weight web page that needs + most of the device's RAM, background services may be temporarily killed to satisfy + those needs. Services in these processes thus must be prepared to deal gracefully + with being killed while doing their work and later restarted.</p> + + <p>In recent implementations of Android, there are actually a number of sub-divisions + in this area for processes that Android considers more important to the user and so + would like to try harder to keep around. For example, the process hosting the current + home app is generally kept in this area so that the user will not see long delays in + returning home because that process has been killed.</p> </li> - <li><b>Background process</b> - <p>A process holding an activity that's not currently visible to the user (the activity's -{@link android.app.Activity#onStop onStop()} method has been called). These processes have no direct -impact on the user experience, and the system can kill them at any time to reclaim memory for a -foreground, -visible, or service process. Usually there are many background processes running, so they are kept -in an LRU (least recently used) list to ensure that the process with the activity that was most -recently seen by the user is the last to be killed. If an activity implements its lifecycle methods + <li><b>Background (cached) process</b> + <p>The final importance level is for processes that are not of current significance. + This is basically any process that does not fall into one of the previous levels. + These processes have no direct impact on the user experience, and the system can kill + them at any time to reclaim memory for the other more important processes. + This includes everything from processes holding running activity objects that are not currently + visible to the user (the activity's {@link android.app.Activity#onStop onStop()} + method has been called) to processes that have no active code at all but may be + useful to keep around in case they are needed in the near future.</p> + + <p>Usually there are many background processes being maintained, so they are kept + in an LRU list to allow older processes to be killed before more recent ones. This + helps reduce the frequency that new processes need to be creating, facilitating things + like more rapid switching between the applications the user has recently visited. + However, processes in this state must deal correctly with being killed and later + restarted when needed. For example, if an activity implements its lifecycle methods correctly, and saves its current state, killing its process will not have a visible effect on the user experience, because when the user navigates back to the activity, the activity restores all of its visible state. See the <a href="{@docRoot}guide/topics/fundamentals/activities.html#SavingActivityState">Activities</a> document for information about saving and restoring state.</p> - </li> - <li><b>Empty process</b> - <p>A process that doesn't hold any active application components. The only reason to keep this -kind of process alive is for caching purposes, to improve startup time the next time a component -needs to run in it. The system often kills these processes in order to balance overall system -resources between process caches and the underlying kernel caches.</p> + <p>Android may also employ other additional policies for killing background processes. For + example, there are typically restrictions on a maximum number of such processes to + keep around, and limits on the amount of time they can spend holding wake locks + or consuming CPU power until they will be removed.</p> </li> </ol> @@ -176,23 +213,48 @@ components currently active in the process. For example, if a process hosts a s activity, the process is ranked as a visible process, not a service process.</p> <p>In addition, a process's ranking might be increased because other processes are dependent on -it—a process that is serving another process can never be ranked lower than the process it is +it—a process that is serving another process can not generally be ranked lower than the process it is serving. For example, if a content provider in process A is serving a client in process B, or if a -service in process A is bound to a component in process B, process A is always considered at least +service in process A has been bound to by a client in process B, process A is always considered at least as important as process B.</p> <p>Because a process running a service is ranked higher than a process with background activities, -an activity that initiates a long-running operation might do well to start a <a +an activity that initiates a long-running operation may sometimes start a <a href="{@docRoot}guide/topics/fundamentals/services.html">service</a> for that operation, rather than -simply create a worker thread—particularly if the operation will likely outlast the activity. +simply create a worker thread—but only when the operation is a specific task that needs +to be accomplished regardless of whether the user returns to the application. For example, an activity that's uploading a picture to a web site should start a service to perform the upload so that the upload can continue in the background even if the user leaves the activity. Using a service guarantees that the operation will have at least "service process" priority, -regardless of what happens to the activity. This is the same reason that broadcast receivers should -employ services rather than simply put time-consuming operations in a thread.</p> - +regardless of what happens to the activity. This is not however an approach that should always +be used. It would not be appropriate when simply downloading the data for a web page, since +that can easily be restarted later if the user returns to the web browser. Allowing +such a process to be in the background (instead of running a service) gives Android better +information about how to manage that process in relation to others. + + <p>For a similar reason, broadcast receivers will often employ services rather than + simply put time-consuming operations in a thread.</p> + + <p>Some command line tools are available to help you understand how Android is managing + its processes. The most common command is <code>adb shell dumpsys activity</code> + which provides a summary of various key state, including at the end a list of the + process states, one per line (plus an optional second line for any key dependency + on that process), ordered from higher importance to lowest. The exact + contents of these lines has changed across different versions of Android, but the + typical state for one process in the list would be:</p> + <pre> +Proc # 2: adj=prcp /F trm= 0 848:com.google.android.inputmethod.latin/u0a32 (service) + com.google.android.inputmethod.latin/com.android.inputmethod.latin.LatinIME<=Proc{417:system/1000} +</pre> + <p>This is a perceptible process (adj=prcp) that is running with the foreground + scheduling class (/F), and has not recently been told to trim any memory + (trm= 0). Its process id is 848; its name is com.google.android.inputmethod.latin; + its Linux uid is u0a32 (10032), and the key state contributing to its current + importance level is a service.</p> + <p>The second line provides the name of the service that is important, because another + process has a dependency on it (here the system process).</p> <h2 id="Threads">Threads</h2> diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index f8bb70a6c0a9..da2192f21cb2 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -190,8 +190,17 @@ void OpenGLRenderer::finish() { while ((status = glGetError()) != GL_NO_ERROR) { ALOGD("GL error from OpenGLRenderer: 0x%x", status); switch (status) { + case GL_INVALID_ENUM: + ALOGE(" GL_INVALID_ENUM"); + break; + case GL_INVALID_VALUE: + ALOGE(" GL_INVALID_VALUE"); + break; + case GL_INVALID_OPERATION: + ALOGE(" GL_INVALID_OPERATION"); + break; case GL_OUT_OF_MEMORY: - ALOGE(" OpenGLRenderer is out of memory!"); + ALOGE(" Out of memory!"); break; } } @@ -267,17 +276,24 @@ status_t OpenGLRenderer::invokeFunctors(Rect& dirty) { Functor* f = functors.itemAt(i); result |= (*f)(DrawGlInfo::kModeProcess, &info); - if (result != DrawGlInfo::kStatusDone) { + if (result & DrawGlInfo::kStatusDraw) { Rect localDirty(info.dirtyLeft, info.dirtyTop, info.dirtyRight, info.dirtyBottom); dirty.unionWith(localDirty); + } - if (result & DrawGlInfo::kStatusInvoke) { - mFunctors.add(f); - } + if (result & DrawGlInfo::kStatusInvoke) { + mFunctors.add(f); } } } + // Restore state possibly changed by the functors in process mode + GLboolean value; + glGetBooleanv(GL_BLEND, &value); + mCaches.blend = value; + + mCaches.activeTexture(0); + return result; } @@ -2787,6 +2803,7 @@ void OpenGLRenderer::drawTextureMesh(float left, float top, float right, float b void OpenGLRenderer::chooseBlending(bool blend, SkXfermode::Mode mode, ProgramDescription& description, bool swapSrcDst) { blend = blend || mode != SkXfermode::kSrcOver_Mode; + if (blend) { // These blend modes are not supported by OpenGL directly and have // to be implemented using shaders. Since the shader will perform diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index 41d5c324da9c..012e09570179 100644 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -47,7 +47,6 @@ public class AudioManager { private final Context mContext; private long mVolumeKeyUpTime; - private int mVolumeControlStream = -1; private final boolean mUseMasterVolume; private static String TAG = "AudioManager"; @@ -304,13 +303,6 @@ public class AudioManager { public static final int FLAG_VIBRATE = 1 << 4; /** - * forces use of specified stream - * @hide - */ - public static final int FLAG_FORCE_STREAM = 1 << 5; - - - /** * Ringer mode that will be silent and will not vibrate. (This overrides the * vibrate setting.) * @@ -458,10 +450,6 @@ public class AudioManager { : ADJUST_LOWER, flags); } else { - if (mVolumeControlStream != -1) { - stream = mVolumeControlStream; - flags |= FLAG_FORCE_STREAM; - } adjustSuggestedStreamVolume( keyCode == KeyEvent.KEYCODE_VOLUME_UP ? ADJUST_RAISE @@ -500,10 +488,6 @@ public class AudioManager { } } else { int flags = FLAG_PLAY_SOUND; - if (mVolumeControlStream != -1) { - stream = mVolumeControlStream; - flags |= FLAG_FORCE_STREAM; - } adjustSuggestedStreamVolume( ADJUST_SAME, stream, @@ -943,7 +927,12 @@ public class AudioManager { * @hide */ public void forceVolumeControlStream(int streamType) { - mVolumeControlStream = streamType; + IAudioService service = getService(); + try { + service.forceVolumeControlStream(streamType, mICallBack); + } catch (RemoteException e) { + Log.e(TAG, "Dead object in forceVolumeControlStream", e); + } } /** diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java index 48d37127f326..dcf72ccdeba0 100644 --- a/media/java/android/media/AudioService.java +++ b/media/java/android/media/AudioService.java @@ -149,6 +149,7 @@ public class AudioService extends IAudioService.Stub { private int mMode; // protects mRingerMode private final Object mSettingsLock = new Object(); + private boolean mMediaServerOk; private SoundPool mSoundPool; @@ -343,6 +344,14 @@ public class AudioService extends IAudioService.Stub { // Keyguard manager proxy private KeyguardManager mKeyguardManager; + // mVolumeControlStream is set by VolumePanel to temporarily force the stream type which volume + // is controlled by Vol keys. + private int mVolumeControlStream = -1; + private final Object mForceControlStreamLock = new Object(); + // VolumePanel is currently the only client of forceVolumeControlStream() and runs in system + // server process so in theory it is not necessary to monitor the client death. + // However it is good to be ready for future evolutions. + private ForceControlStreamClient mForceControlStreamClient = null; /////////////////////////////////////////////////////////////////////////// // Construction @@ -538,8 +547,8 @@ public class AudioService extends IAudioService.Stub { public void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags) { int streamType; - if ((flags & AudioManager.FLAG_FORCE_STREAM) != 0) { - streamType = suggestedStreamType; + if (mVolumeControlStream != -1) { + streamType = mVolumeControlStream; } else { streamType = getActiveStreamType(suggestedStreamType); } @@ -682,6 +691,57 @@ public class AudioService extends IAudioService.Stub { sendVolumeUpdate(streamType, oldIndex, index, flags); } + /** @see AudioManager#forceVolumeControlStream(int) */ + public void forceVolumeControlStream(int streamType, IBinder cb) { + synchronized(mForceControlStreamLock) { + mVolumeControlStream = streamType; + if (mVolumeControlStream == -1) { + if (mForceControlStreamClient != null) { + mForceControlStreamClient.release(); + mForceControlStreamClient = null; + } + } else { + mForceControlStreamClient = new ForceControlStreamClient(cb); + } + } + } + + private class ForceControlStreamClient implements IBinder.DeathRecipient { + private IBinder mCb; // To be notified of client's death + + ForceControlStreamClient(IBinder cb) { + if (cb != null) { + try { + cb.linkToDeath(this, 0); + } catch (RemoteException e) { + // Client has died! + Log.w(TAG, "ForceControlStreamClient() could not link to "+cb+" binder death"); + cb = null; + } + } + mCb = cb; + } + + public void binderDied() { + synchronized(mForceControlStreamLock) { + Log.w(TAG, "SCO client died"); + if (mForceControlStreamClient != this) { + Log.w(TAG, "unregistered control stream client died"); + } else { + mForceControlStreamClient = null; + mVolumeControlStream = -1; + } + } + } + + public void release() { + if (mCb != null) { + mCb.unlinkToDeath(this, 0); + mCb = null; + } + } + } + private int findVolumeDelta(int direction, int volume) { int delta = 0; if (direction == AudioManager.ADJUST_RAISE) { diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java index 7d4c28285851..f51a24a4662f 100644 --- a/media/java/android/media/AudioTrack.java +++ b/media/java/android/media/AudioTrack.java @@ -340,6 +340,15 @@ public class AudioTrack } } + // mask of all the channels supported by this implementation + private static final int SUPPORTED_OUT_CHANNELS = + AudioFormat.CHANNEL_OUT_FRONT_LEFT | + AudioFormat.CHANNEL_OUT_FRONT_RIGHT | + AudioFormat.CHANNEL_OUT_FRONT_CENTER | + AudioFormat.CHANNEL_OUT_LOW_FREQUENCY | + AudioFormat.CHANNEL_OUT_BACK_LEFT | + AudioFormat.CHANNEL_OUT_BACK_RIGHT | + AudioFormat.CHANNEL_OUT_BACK_CENTER; // Convenience method for the constructor's parameter checks. // This is where constructor IllegalArgumentException-s are thrown @@ -392,10 +401,16 @@ public class AudioTrack mChannels = AudioFormat.CHANNEL_OUT_STEREO; break; default: - mChannelCount = 0; - mChannels = AudioFormat.CHANNEL_INVALID; - mChannelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_INVALID; - throw(new IllegalArgumentException("Unsupported channel configuration.")); + if ((channelConfig & SUPPORTED_OUT_CHANNELS) != channelConfig) { + // input channel configuration features unsupported channels + mChannelCount = 0; + mChannels = AudioFormat.CHANNEL_INVALID; + mChannelConfiguration = AudioFormat.CHANNEL_INVALID; + throw(new IllegalArgumentException("Unsupported channel configuration.")); + } else { + mChannels = channelConfig; + mChannelCount = Integer.bitCount(channelConfig); + } } //-------------- @@ -623,8 +638,13 @@ public class AudioTrack channelCount = 2; break; default: - loge("getMinBufferSize(): Invalid channel configuration."); - return AudioTrack.ERROR_BAD_VALUE; + if ((channelConfig & SUPPORTED_OUT_CHANNELS) != channelConfig) { + // input channel configuration features unsupported channels + loge("getMinBufferSize(): Invalid channel configuration."); + return AudioTrack.ERROR_BAD_VALUE; + } else { + channelCount = Integer.bitCount(channelConfig); + } } if ((audioFormat != AudioFormat.ENCODING_PCM_16BIT) diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl index b77509548d9b..0311c59e2ff6 100644 --- a/media/java/android/media/IAudioService.aidl +++ b/media/java/android/media/IAudioService.aidl @@ -115,4 +115,6 @@ interface IAudioService { void startBluetoothSco(IBinder cb); void stopBluetoothSco(IBinder cb); + + void forceVolumeControlStream(int streamType, IBinder cb); } diff --git a/media/java/android/media/MediaExtractor.java b/media/java/android/media/MediaExtractor.java index 9fdb81fc240f..5fe58a8cc15c 100644 --- a/media/java/android/media/MediaExtractor.java +++ b/media/java/android/media/MediaExtractor.java @@ -191,17 +191,33 @@ final public class MediaExtractor { /** Subsequent calls to {@link #readSampleData}, {@link #getSampleTrackIndex} and * {@link #getSampleTime} only retrieve information for the subset of tracks - * selected by the call below. - * Selecting the same track multiple times has no effect, the track + * selected. + * Selecting the same track multiple times has no effect, the track is * only selected once. - * Media data will be returned in the order of their timestamps. */ public native void selectTrack(int index); - /** All selected tracks seek near the requested time. The next sample - * returned for each selected track will be a sync sample. + /** Subsequent calls to {@link #readSampleData}, {@link #getSampleTrackIndex} and + * {@link #getSampleTime} only retrieve information for the subset of tracks + * selected. */ - public native void seekTo(long timeUs); + public native void unselectTrack(int index); + + /** If possible, seek to a sync sample at or before the specified time */ + public static final int SEEK_TO_PREVIOUS_SYNC = 0; + /** If possible, seek to a sync sample at or after the specified time */ + public static final int SEEK_TO_NEXT_SYNC = 1; + /** If possible, seek to the sync sample closest to the specified time */ + public static final int SEEK_TO_CLOSEST_SYNC = 2; + /** If possible, seek to a sample closest to the specified time, which may + * NOT be a sync sample! + */ + public static final int SEEK_TO_CLOSEST = 3; + + /** All selected tracks seek near the requested time according to the + * specified mode. + */ + public native void seekTo(long timeUs, int mode); /** Advance to the next sample. Returns false if no more sample data * is available (end of stream). diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java index 2175131d5e28..e0b33cd90a81 100644 --- a/media/java/android/media/MediaRecorder.java +++ b/media/java/android/media/MediaRecorder.java @@ -257,6 +257,8 @@ public class MediaRecorder public static final int AAC_PLUS = 4; /** @hide enhanced AAC plus audio codec */ public static final int EAAC_PLUS = 5; + /** AAC-ELD audio codec */ + public static final int AAC_ELD = 6; } /** diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java index c41901b54d73..821a251b2753 100644 --- a/media/java/android/media/MediaScanner.java +++ b/media/java/android/media/MediaScanner.java @@ -31,17 +31,16 @@ import android.graphics.BitmapFactory; import android.mtp.MtpConstants; import android.net.Uri; import android.os.Environment; -import android.os.Process; import android.os.RemoteException; import android.os.SystemProperties; import android.provider.MediaStore; -import android.provider.MediaStore.Files.FileColumns; -import android.provider.Settings; import android.provider.MediaStore.Audio; +import android.provider.MediaStore.Audio.Playlists; import android.provider.MediaStore.Files; +import android.provider.MediaStore.Files.FileColumns; import android.provider.MediaStore.Images; import android.provider.MediaStore.Video; -import android.provider.MediaStore.Audio.Playlists; +import android.provider.Settings; import android.sax.Element; import android.sax.ElementListener; import android.sax.RootElement; @@ -56,10 +55,8 @@ import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; -import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; -import java.util.LinkedHashMap; import java.util.Locale; import libcore.io.ErrnoException; @@ -372,6 +369,14 @@ public class MediaScanner } } + private static class PlaylistEntry { + String path; + long bestmatchid; + int bestmatchlevel; + } + + private ArrayList<PlaylistEntry> mPlaylistEntries = new ArrayList<PlaylistEntry>(); + private MediaInserter mMediaInserter; private ArrayList<FileEntry> mPlayLists; @@ -1492,93 +1497,83 @@ public class MediaScanner return result; } - private boolean addPlayListEntry(String entry, String playListDirectory, - Uri uri, ContentValues values, int index, Cursor fileList) { + private boolean matchEntries(long rowId, String data) { + + int len = mPlaylistEntries.size(); + boolean done = true; + for (int i = 0; i < len; i++) { + PlaylistEntry entry = mPlaylistEntries.get(i); + if (entry.bestmatchlevel == Integer.MAX_VALUE) { + continue; // this entry has been matched already + } + done = false; + if (data.equalsIgnoreCase(entry.path)) { + entry.bestmatchid = rowId; + entry.bestmatchlevel = Integer.MAX_VALUE; + continue; // no need for path matching + } + + int matchLength = matchPaths(data, entry.path); + if (matchLength > entry.bestmatchlevel) { + entry.bestmatchid = rowId; + entry.bestmatchlevel = matchLength; + } + } + return done; + } + private void cachePlaylistEntry(String line, String playListDirectory) { + PlaylistEntry entry = new PlaylistEntry(); // watch for trailing whitespace - int entryLength = entry.length(); - while (entryLength > 0 && Character.isWhitespace(entry.charAt(entryLength - 1))) entryLength--; + int entryLength = line.length(); + while (entryLength > 0 && Character.isWhitespace(line.charAt(entryLength - 1))) entryLength--; // path should be longer than 3 characters. // avoid index out of bounds errors below by returning here. - if (entryLength < 3) return false; - if (entryLength < entry.length()) entry = entry.substring(0, entryLength); + if (entryLength < 3) return; + if (entryLength < line.length()) line = line.substring(0, entryLength); // does entry appear to be an absolute path? // look for Unix or DOS absolute paths - char ch1 = entry.charAt(0); + char ch1 = line.charAt(0); boolean fullPath = (ch1 == '/' || - (Character.isLetter(ch1) && entry.charAt(1) == ':' && entry.charAt(2) == '\\')); + (Character.isLetter(ch1) && line.charAt(1) == ':' && line.charAt(2) == '\\')); // if we have a relative path, combine entry with playListDirectory if (!fullPath) - entry = playListDirectory + entry; - + line = playListDirectory + line; + entry.path = line; //FIXME - should we look for "../" within the path? - // best matching MediaFile for the play list entry - FileEntry bestMatch = null; - - // number of rightmost file/directory names for bestMatch - int bestMatchLength = 0; - - if (fileList != null) { - int count = fileList.getCount(); - // Backing up a little in the cursor helps when the files in the - // playlist are not in the same order as they are in the database - // but are still close. - fileList.move(-1000); - while(--count >= 0) { - if (!fileList.moveToNext()) { - fileList.moveToFirst(); - } - long rowId = fileList.getLong(FILES_PRESCAN_ID_COLUMN_INDEX); - String path = fileList.getString(FILES_PRESCAN_PATH_COLUMN_INDEX); - int format = fileList.getInt(FILES_PRESCAN_FORMAT_COLUMN_INDEX); - long lastModified = fileList.getLong(FILES_PRESCAN_DATE_MODIFIED_COLUMN_INDEX); - - if (path.equalsIgnoreCase(entry)) { - bestMatch = new FileEntry(rowId, path, lastModified, format); - break; // don't bother continuing search - } + mPlaylistEntries.add(entry); + } - int matchLength = matchPaths(path, entry); - if (matchLength > bestMatchLength) { - bestMatch = new FileEntry(rowId, path, lastModified, format); - bestMatchLength = matchLength; - } + private void processCachedPlaylist(Cursor fileList, ContentValues values, Uri playlistUri) { + fileList.moveToPosition(-1); + while (fileList.moveToNext()) { + long rowId = fileList.getLong(FILES_PRESCAN_ID_COLUMN_INDEX); + String data = fileList.getString(FILES_PRESCAN_PATH_COLUMN_INDEX); + if (matchEntries(rowId, data)) { + break; } } - if (bestMatch == null) { - return false; - } - - try { - // check rowid is set. Rowid may be missing if it is inserted by bulkInsert(). - if (bestMatch.mRowId == 0) { - Cursor c = mMediaProvider.query(mAudioUri, ID_PROJECTION, - MediaStore.Files.FileColumns.DATA + "=?", - new String[] { bestMatch.mPath }, null, null); - if (c != null) { - if (c.moveToNext()) { - bestMatch.mRowId = c.getLong(0); - } - c.close(); - } - if (bestMatch.mRowId == 0) { - return false; + int len = mPlaylistEntries.size(); + int index = 0; + for (int i = 0; i < len; i++) { + PlaylistEntry entry = mPlaylistEntries.get(i); + if (entry.bestmatchlevel > 0) { + try { + values.clear(); + values.put(MediaStore.Audio.Playlists.Members.PLAY_ORDER, Integer.valueOf(index)); + values.put(MediaStore.Audio.Playlists.Members.AUDIO_ID, Long.valueOf(entry.bestmatchid)); + mMediaProvider.insert(playlistUri, values); + index++; + } catch (RemoteException e) { + Log.e(TAG, "RemoteException in MediaScanner.processCachedPlaylist()", e); + return; } } - // OK, now we are ready to add this to the database - values.clear(); - values.put(MediaStore.Audio.Playlists.Members.PLAY_ORDER, Integer.valueOf(index)); - values.put(MediaStore.Audio.Playlists.Members.AUDIO_ID, Long.valueOf(bestMatch.mRowId)); - mMediaProvider.insert(uri, values); - } catch (RemoteException e) { - Log.e(TAG, "RemoteException in MediaScanner.addPlayListEntry()", e); - return false; } - - return true; + mPlaylistEntries.clear(); } private void processM3uPlayList(String path, String playListDirectory, Uri uri, @@ -1590,16 +1585,16 @@ public class MediaScanner reader = new BufferedReader( new InputStreamReader(new FileInputStream(f)), 8192); String line = reader.readLine(); - int index = 0; + mPlaylistEntries.clear(); while (line != null) { // ignore comment lines, which begin with '#' if (line.length() > 0 && line.charAt(0) != '#') { - values.clear(); - if (addPlayListEntry(line, playListDirectory, uri, values, index, fileList)) - index++; + cachePlaylistEntry(line, playListDirectory); } line = reader.readLine(); } + + processCachedPlaylist(fileList, values, uri); } } catch (IOException e) { Log.e(TAG, "IOException in MediaScanner.processM3uPlayList()", e); @@ -1622,20 +1617,19 @@ public class MediaScanner reader = new BufferedReader( new InputStreamReader(new FileInputStream(f)), 8192); String line = reader.readLine(); - int index = 0; + mPlaylistEntries.clear(); while (line != null) { // ignore comment lines, which begin with '#' if (line.startsWith("File")) { int equals = line.indexOf('='); if (equals > 0) { - values.clear(); - if (addPlayListEntry(line.substring(equals + 1), playListDirectory, - uri, values, index, fileList)) - index++; + cachePlaylistEntry(line, playListDirectory); } } line = reader.readLine(); } + + processCachedPlaylist(fileList, values, uri); } } catch (IOException e) { Log.e(TAG, "IOException in MediaScanner.processPlsPlayList()", e); @@ -1653,15 +1647,9 @@ public class MediaScanner final ContentHandler handler; String playListDirectory; - Uri uri; - Cursor fileList; - ContentValues values = new ContentValues(); - int index = 0; public WplHandler(String playListDirectory, Uri uri, Cursor fileList) { this.playListDirectory = playListDirectory; - this.uri = uri; - this.fileList = fileList; RootElement root = new RootElement("smil"); Element body = root.getChild("body"); @@ -1676,13 +1664,11 @@ public class MediaScanner public void start(Attributes attributes) { String path = attributes.getValue("", "src"); if (path != null) { - values.clear(); - if (addPlayListEntry(path, playListDirectory, uri, values, index, fileList)) { - index++; - } + cachePlaylistEntry(path, playListDirectory); } } + @Override public void end() { } @@ -1692,15 +1678,18 @@ public class MediaScanner } private void processWplPlayList(String path, String playListDirectory, Uri uri, - Cursor fileList) { + ContentValues values, Cursor fileList) { FileInputStream fis = null; try { File f = new File(path); if (f.exists()) { fis = new FileInputStream(f); + mPlaylistEntries.clear(); Xml.parse(fis, Xml.findEncodingByName("UTF-8"), new WplHandler(playListDirectory, uri, fileList).getContentHandler()); + + processCachedPlaylist(fileList, values, uri); } } catch (SAXException e) { e.printStackTrace(); @@ -1762,7 +1751,7 @@ public class MediaScanner } else if (fileType == MediaFile.FILE_TYPE_PLS) { processPlsPlayList(path, playListDirectory, membersUri, values, fileList); } else if (fileType == MediaFile.FILE_TYPE_WPL) { - processWplPlayList(path, playListDirectory, membersUri, fileList); + processWplPlayList(path, playListDirectory, membersUri, values, fileList); } } @@ -1800,7 +1789,7 @@ public class MediaScanner private native final void native_finalize(); /** - * Releases resouces associated with this MediaScanner object. + * Releases resources associated with this MediaScanner object. * It is considered good practice to call this method when * one is done using the MediaScanner object. After this method * is called, the MediaScanner object can no longer be used. diff --git a/media/java/android/media/RingtoneManager.java b/media/java/android/media/RingtoneManager.java index 7aaf4aac10de..a5b1f45cf978 100644 --- a/media/java/android/media/RingtoneManager.java +++ b/media/java/android/media/RingtoneManager.java @@ -393,13 +393,13 @@ public class RingtoneManager { * @return A {@link Uri} pointing to the ringtone. */ public Uri getRingtoneUri(int position) { - final Cursor cursor = getCursor(); - - if (!cursor.moveToPosition(position)) { + // use cursor directly instead of requerying it, which could easily + // cause position to shuffle. + if (mCursor == null || !mCursor.moveToPosition(position)) { return null; } - return getUriFromCursor(cursor); + return getUriFromCursor(mCursor); } private static Uri getUriFromCursor(Cursor cursor) { diff --git a/media/jni/android_media_MediaExtractor.cpp b/media/jni/android_media_MediaExtractor.cpp index 051833161c23..9e1920ca8dfc 100644 --- a/media/jni/android_media_MediaExtractor.cpp +++ b/media/jni/android_media_MediaExtractor.cpp @@ -96,8 +96,13 @@ status_t JMediaExtractor::selectTrack(size_t index) { return mImpl->selectTrack(index); } -status_t JMediaExtractor::seekTo(int64_t timeUs) { - return mImpl->seekTo(timeUs); +status_t JMediaExtractor::unselectTrack(size_t index) { + return mImpl->unselectTrack(index); +} + +status_t JMediaExtractor::seekTo( + int64_t timeUs, MediaSource::ReadOptions::SeekMode mode) { + return mImpl->seekTo(timeUs, mode); } status_t JMediaExtractor::advance() { @@ -281,8 +286,25 @@ static void android_media_MediaExtractor_selectTrack( } } +static void android_media_MediaExtractor_unselectTrack( + JNIEnv *env, jobject thiz, jint index) { + sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz); + + if (extractor == NULL) { + jniThrowException(env, "java/lang/IllegalStateException", NULL); + return; + } + + status_t err = extractor->unselectTrack(index); + + if (err != OK) { + jniThrowException(env, "java/lang/IllegalArgumentException", NULL); + return; + } +} + static void android_media_MediaExtractor_seekTo( - JNIEnv *env, jobject thiz, jlong timeUs) { + JNIEnv *env, jobject thiz, jlong timeUs, jint mode) { sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz); if (extractor == NULL) { @@ -290,7 +312,13 @@ static void android_media_MediaExtractor_seekTo( return; } - extractor->seekTo(timeUs); + if (mode < MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC + || mode > MediaSource::ReadOptions::SEEK_CLOSEST) { + jniThrowException(env, "java/lang/IllegalArgumentException", NULL); + return; + } + + extractor->seekTo(timeUs, (MediaSource::ReadOptions::SeekMode)mode); } static jboolean android_media_MediaExtractor_advance( @@ -648,7 +676,10 @@ static JNINativeMethod gMethods[] = { { "selectTrack", "(I)V", (void *)android_media_MediaExtractor_selectTrack }, - { "seekTo", "(J)V", (void *)android_media_MediaExtractor_seekTo }, + { "unselectTrack", "(I)V", + (void *)android_media_MediaExtractor_unselectTrack }, + + { "seekTo", "(JI)V", (void *)android_media_MediaExtractor_seekTo }, { "advance", "()Z", (void *)android_media_MediaExtractor_advance }, diff --git a/media/jni/android_media_MediaExtractor.h b/media/jni/android_media_MediaExtractor.h index ef0c48b3a3c4..2d4627ef4cec 100644 --- a/media/jni/android_media_MediaExtractor.h +++ b/media/jni/android_media_MediaExtractor.h @@ -18,6 +18,7 @@ #define _ANDROID_MEDIA_MEDIAEXTRACTOR_H_ #include <media/stagefright/foundation/ABase.h> +#include <media/stagefright/MediaSource.h> #include <utils/Errors.h> #include <utils/KeyedVector.h> #include <utils/RefBase.h> @@ -43,8 +44,9 @@ struct JMediaExtractor : public RefBase { status_t getTrackFormat(size_t index, jobject *format) const; status_t selectTrack(size_t index); + status_t unselectTrack(size_t index); - status_t seekTo(int64_t timeUs); + status_t seekTo(int64_t timeUs, MediaSource::ReadOptions::SeekMode mode); status_t advance(); status_t readSampleData(jobject byteBuf, size_t offset, size_t *sampleSize); diff --git a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java index 8e3a3c52ee45..3eec18c1b58e 100644 --- a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java +++ b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java @@ -81,13 +81,15 @@ public class DefaultContainerService extends IntentService { * @return Returns the new cache path where the resource has been copied into * */ - public String copyResourceToContainer(final Uri packageURI, - final String cid, - final String key, final String resFileName) { + public String copyResourceToContainer(final Uri packageURI, final String cid, + final String key, final String resFileName, final String publicResFileName, + boolean isExternal, boolean isForwardLocked) { if (packageURI == null || cid == null) { return null; } - return copyResourceInner(packageURI, cid, key, resFileName); + + return copyResourceInner(packageURI, cid, key, resFileName, publicResFileName, + isExternal, isForwardLocked); } /* @@ -169,22 +171,23 @@ public class DefaultContainerService extends IntentService { } @Override - public boolean checkInternalFreeStorage(Uri packageUri, long threshold) - throws RemoteException { + public boolean checkInternalFreeStorage(Uri packageUri, boolean isForwardLocked, + long threshold) throws RemoteException { final File apkFile = new File(packageUri.getPath()); try { - return isUnderInternalThreshold(apkFile, threshold); - } catch (FileNotFoundException e) { + return isUnderInternalThreshold(apkFile, isForwardLocked, threshold); + } catch (IOException e) { return true; } } @Override - public boolean checkExternalFreeStorage(Uri packageUri) throws RemoteException { + public boolean checkExternalFreeStorage(Uri packageUri, boolean isForwardLocked) + throws RemoteException { final File apkFile = new File(packageUri.getPath()); try { - return isUnderExternalThreshold(apkFile); - } catch (FileNotFoundException e) { + return isUnderExternalThreshold(apkFile, isForwardLocked); + } catch (IOException e) { return true; } } @@ -259,12 +262,16 @@ public class DefaultContainerService extends IntentService { return mBinder; } - private String copyResourceInner(Uri packageURI, String newCid, String key, String resFileName) { - // Make sure the sdcard is mounted. - String status = Environment.getExternalStorageState(); - if (!status.equals(Environment.MEDIA_MOUNTED)) { - Slog.w(TAG, "Make sure sdcard is mounted."); - return null; + private String copyResourceInner(Uri packageURI, String newCid, String key, String resFileName, + String publicResFileName, boolean isExternal, boolean isForwardLocked) { + + if (isExternal) { + // Make sure the sdcard is mounted. + String status = Environment.getExternalStorageState(); + if (!status.equals(Environment.MEDIA_MOUNTED)) { + Slog.w(TAG, "Make sure sdcard is mounted."); + return null; + } } // The .apk file @@ -272,17 +279,18 @@ public class DefaultContainerService extends IntentService { File codeFile = new File(codePath); // Calculate size of container needed to hold base APK. - int sizeMb; + final int sizeMb; try { - sizeMb = calculateContainerSize(codeFile); - } catch (FileNotFoundException e) { - Slog.w(TAG, "File does not exist when trying to copy " + codeFile.getPath()); + sizeMb = calculateContainerSize(codeFile, isForwardLocked); + } catch (IOException e) { + Slog.w(TAG, "Problem when trying to copy " + codeFile.getPath()); return null; } // Create new container - final String newCachePath; - if ((newCachePath = PackageHelper.createSdDir(sizeMb, newCid, key, Process.myUid())) == null) { + final String newCachePath = PackageHelper.createSdDir(sizeMb, newCid, key, Process.myUid(), + isExternal); + if (newCachePath == null) { Slog.e(TAG, "Failed to create container " + newCid); return null; } @@ -303,6 +311,30 @@ public class DefaultContainerService extends IntentService { return null; } + if (isForwardLocked) { + File publicZipFile = new File(newCachePath, publicResFileName); + try { + PackageHelper.extractPublicFiles(resFile.getAbsolutePath(), publicZipFile); + if (localLOGV) { + Slog.i(TAG, "Copied resources to " + publicZipFile); + } + } catch (IOException e) { + Slog.e(TAG, "Could not chown public APK " + publicZipFile.getAbsolutePath() + ": " + + e.getMessage()); + PackageHelper.destroySdDir(newCid); + return null; + } + + try { + Libcore.os.chmod(resFile.getAbsolutePath(), 0640); + Libcore.os.chmod(publicZipFile.getAbsolutePath(), 0644); + } catch (ErrnoException e) { + Slog.e(TAG, "Could not chown APK or resource file: " + e.getMessage()); + PackageHelper.destroySdDir(newCid); + return null; + } + } + final File sharedLibraryDir = new File(newCachePath, LIB_DIR_NAME); if (sharedLibraryDir.mkdir()) { int ret = NativeLibraryHelper.copyNativeBinariesIfNeededLI(codeFile, sharedLibraryDir); @@ -412,18 +444,13 @@ public class DefaultContainerService extends IntentService { int prefer; boolean checkBoth = false; + final boolean isForwardLocked = (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0; + check_inner : { /* * Explicit install flags should override the manifest settings. */ - if ((flags & PackageManager.INSTALL_FORWARD_LOCK) != 0) { - /* - * Forward-locked applications cannot be installed on SD card, - * so only allow checking internal storage. - */ - prefer = PREFER_INTERNAL; - break check_inner; - } else if ((flags & PackageManager.INSTALL_INTERNAL) != 0) { + if ((flags & PackageManager.INSTALL_INTERNAL) != 0) { prefer = PREFER_INTERNAL; break check_inner; } else if ((flags & PackageManager.INSTALL_EXTERNAL) != 0) { @@ -473,8 +500,8 @@ public class DefaultContainerService extends IntentService { boolean fitsOnInternal = false; if (checkBoth || prefer == PREFER_INTERNAL) { try { - fitsOnInternal = isUnderInternalThreshold(apkFile, threshold); - } catch (FileNotFoundException e) { + fitsOnInternal = isUnderInternalThreshold(apkFile, isForwardLocked, threshold); + } catch (IOException e) { return PackageHelper.RECOMMEND_FAILED_INVALID_URI; } } @@ -482,8 +509,8 @@ public class DefaultContainerService extends IntentService { boolean fitsOnSd = false; if (!emulated && (checkBoth || prefer == PREFER_EXTERNAL)) { try { - fitsOnSd = isUnderExternalThreshold(apkFile); - } catch (FileNotFoundException e) { + fitsOnSd = isUnderExternalThreshold(apkFile, isForwardLocked); + } catch (IOException e) { return PackageHelper.RECOMMEND_FAILED_INVALID_URI; } } @@ -527,13 +554,17 @@ public class DefaultContainerService extends IntentService { * @return true if file fits under threshold * @throws FileNotFoundException when APK does not exist */ - private boolean isUnderInternalThreshold(File apkFile, long threshold) - throws FileNotFoundException { - final long size = apkFile.length(); + private boolean isUnderInternalThreshold(File apkFile, boolean isForwardLocked, long threshold) + throws IOException { + long size = apkFile.length(); if (size == 0 && !apkFile.exists()) { throw new FileNotFoundException(); } + if (isForwardLocked) { + size += PackageHelper.extractPublicFiles(apkFile.getAbsolutePath(), null); + } + final StatFs internalStats = new StatFs(Environment.getDataDirectory().getPath()); final long availInternalSize = (long) internalStats.getAvailableBlocks() * (long) internalStats.getBlockSize(); @@ -549,12 +580,13 @@ public class DefaultContainerService extends IntentService { * @return true if file fits * @throws IOException when file does not exist */ - private boolean isUnderExternalThreshold(File apkFile) throws FileNotFoundException { + private boolean isUnderExternalThreshold(File apkFile, boolean isForwardLocked) + throws IOException { if (Environment.isExternalStorageEmulated()) { return false; } - final int sizeMb = calculateContainerSize(apkFile); + final int sizeMb = calculateContainerSize(apkFile, isForwardLocked); final int availSdMb; if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) { @@ -573,9 +605,9 @@ public class DefaultContainerService extends IntentService { * * @param apkFile file from which to calculate size * @return size in megabytes (2^20 bytes) - * @throws FileNotFoundException when file does not exist + * @throws IOException when there is a problem reading the file */ - private int calculateContainerSize(File apkFile) throws FileNotFoundException { + private int calculateContainerSize(File apkFile, boolean forwardLocked) throws IOException { // Calculate size of container needed to hold base APK. long sizeBytes = apkFile.length(); if (sizeBytes == 0 && !apkFile.exists()) { @@ -586,6 +618,10 @@ public class DefaultContainerService extends IntentService { // container size. sizeBytes += NativeLibraryHelper.sumNativeBinariesLI(apkFile); + if (forwardLocked) { + sizeBytes += PackageHelper.extractPublicFiles(apkFile.getPath(), null); + } + int sizeMb = (int) (sizeBytes >> 20); if ((sizeBytes - (sizeMb * 1024 * 1024)) > 0) { sizeMb++; diff --git a/packages/InputDevices/res/raw/keyboard_layout_croatian_and_slovenian.kcm b/packages/InputDevices/res/raw/keyboard_layout_croatian_and_slovenian.kcm new file mode 100644 index 000000000000..eec9d27cf524 --- /dev/null +++ b/packages/InputDevices/res/raw/keyboard_layout_croatian_and_slovenian.kcm @@ -0,0 +1,352 @@ +# Copyright (C) 2012 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. + +# +# Croatian and Slovenian keyboard layout, QWERTZ style. +# + +type OVERLAY + +map key 12 SLASH +map key 21 Z +map key 44 Y +map key 53 MINUS +map key 86 PLUS + +### ROW 1 + +key GRAVE { + label: '\u00b8' + base: '\u0327' + shift: '\u0308' +} + +key 1 { + label: '1' + base: '1' + shift: '!' + ralt: '\u0303' +} + +key 2 { + label: '2' + base: '2' + shift: '"' + ralt: '\u030c' +} + +key 3 { + label: '3' + base: '3' + shift: '#' + ralt: '\u0302' +} + +key 4 { + label: '4' + base: '4' + shift: '$' + ralt: '\u0306' +} + +key 5 { + label: '5' + base: '5' + shift: '%' + ralt: '\u030a' +} + +key 6 { + label: '6' + base: '6' + shift: '&' + ralt: '\u0328' +} + +key 7 { + label: '7' + base: '7' + shift: '/' + ralt: '\u0300' +} + +key 8 { + label: '8' + base: '8' + shift: '(' + ralt: '\u0307' +} + +key 9 { + label: '9' + base: '9' + shift: ')' + ralt: '\u0301' +} + +key 0 { + label: '0' + base: '0' + shift: '=' + ralt: '\u030b' +} + +key SLASH { + label: '\'' + base: '\'' + shift: '?' + ralt: '\u0308' +} + +key EQUALS { + label: '+' + base: '+' + shift: '*' + ralt: '\u0327' +} + +### ROW 2 + +key Q { + label: 'Q' + base: 'q' + shift, capslock: 'Q' + ralt: '\\' +} + +key W { + label: 'W' + base: 'w' + shift, capslock: 'W' + ralt: '|' +} + +key E { + label: 'E' + base: 'e' + shift, capslock: 'E' + ralt: '\u20ac' +} + +key R { + label: 'R' + base: 'r' + shift, capslock: 'R' +} + +key T { + label: 'T' + base: 't' + shift, capslock: 'T' +} + +key Z { + label: 'Z' + base: 'z' + shift, capslock: 'Z' +} + +key U { + label: 'U' + base: 'u' + shift, capslock: 'U' +} + +key I { + label: 'I' + base: 'i' + shift, capslock: 'I' +} + +key O { + label: 'O' + base: 'o' + shift, capslock: 'O' +} + +key P { + label: 'P' + base: 'p' + shift, capslock: 'P' +} + +key LEFT_BRACKET { + label: '\u0160' + base: '\u0161' + shift, capslock: '\u0160' + ralt: '\u00f7' +} + +key RIGHT_BRACKET { + label: '\u0110' + base: '\u0111' + shift, capslock: '\u0110' + ralt: '\u00d7' +} + +### ROW 3 + +key A { + label: 'A' + base: 'a' + shift, capslock: 'A' +} + +key S { + label: 'S' + base: 's' + shift, capslock: 'S' +} + +key D { + label: 'D' + base: 'd' + shift, capslock: 'D' +} + +key F { + label: 'F' + base: 'f' + shift, capslock: 'F' + ralt: '[' +} + +key G { + label: 'G' + base: 'g' + shift, capslock: 'G' + ralt: ']' +} + +key H { + label: 'H' + base: 'h' + shift, capslock: 'H' +} + +key J { + label: 'J' + base: 'j' + shift, capslock: 'J' +} + +key K { + label: 'K' + base: 'k' + shift, capslock: 'K' + ralt: '\u0268' + ralt+shift, ralt+capslock: '\u0197' +} + +key L { + label: 'L' + base: 'l' + shift, capslock: 'L' + ralt: '\u0142' + ralt+shift, ralt+capslock: '\u0141' +} + +key SEMICOLON { + label: '\u010d' + base: '\u010c' + shift, capslock: '\u010d' +} + +key APOSTROPHE { + label: '\u0106' + base: '\u0107' + shift, capslock: '\u0106' + ralt: '\u00df' +} + +key BACKSLASH { + label: '\u017d' + base: '\u017e' + shift, capslock: '\u017d' + ralt: '\u00a4' +} + +### ROW 4 + +key PLUS { + label: '<' + base: '<' + shift: '>' +} + +key Y { + label: 'Y' + base: 'y' + shift, capslock: 'Y' +} + +key X { + label: 'X' + base: 'x' + shift, capslock: 'X' +} + +key C { + label: 'C' + base: 'c' + shift, capslock: 'C' +} + +key V { + label: 'V' + base: 'v' + shift, capslock: 'V' + ralt: '@' +} + +key B { + label: 'B' + base: 'b' + shift, capslock: 'B' + ralt: '{' +} + +key N { + label: 'N' + base: 'n' + shift, capslock: 'N' + ralt: '}' +} + +key M { + label: 'M' + base: 'm' + shift, capslock: 'M' + ralt: '\u00a7' +} + +key COMMA { + label: ',' + base: ',' + shift: ';' + ralt: '<' +} + +key PERIOD { + label: '.' + base: '.' + shift: ':' + ralt: '>' +} + +key MINUS { + label: '-' + base: '-' + shift: '_' +} diff --git a/packages/InputDevices/res/raw/keyboard_layout_czech.kcm b/packages/InputDevices/res/raw/keyboard_layout_czech.kcm new file mode 100644 index 000000000000..f710a8ef3372 --- /dev/null +++ b/packages/InputDevices/res/raw/keyboard_layout_czech.kcm @@ -0,0 +1,348 @@ +# Copyright (C) 2012 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. + +# +# Czech keyboard layout. +# + +type OVERLAY + +map key 86 PLUS + +### ROW 1 + +key GRAVE { + label: ';' + base: ';' + shift: '\u00b0' +} + +key 1 { + label: '1' + base: '+' + shift: '1' + ralt: '!' +} + +key 2 { + label: '2' + base: '\u011b' + shift: '2' + ralt: '@' +} + +key 3 { + label: '3' + base: '\u0161' + shift: '3' + ralt: '#' +} + +key 4 { + label: '4' + base: '\u010d' + shift: '4' + ralt: '$' +} + +key 5 { + label: '5' + base: '\u0159' + shift: '5' + ralt: '%' +} + +key 6 { + label: '6' + base: '\u017e' + shift: '6' + ralt: '^' +} + +key 7 { + label: '7' + base: '\u00fd' + shift: '7' + ralt: '&' +} + +key 8 { + label: '8' + base: '\u00e1' + shift: '8' + ralt: '*' +} + +key 9 { + label: '9' + base: '\u00ed' + shift: '9' + ralt: '(' +} + +key 0 { + label: '0' + base: '\u00e9' + shift: '0' + ralt: ')' +} + +key MINUS { + label: '=' + base: '=' + shift: '%' + ralt: '-' + ralt+shift: '_' +} + +key EQUALS { + label: '\u00b4' + base: '\u0301' + shift: '\u030c' + ralt: '=' + ralt+shift: '+' +} + +### ROW 2 + +key Q { + label: 'Q' + base: 'q' + shift, capslock: 'Q' +} + +key W { + label: 'W' + base: 'w' + shift, capslock: 'W' +} + +key E { + label: 'E' + base: 'e' + shift, capslock: 'E' + ralt: '\u20ac' +} + +key R { + label: 'R' + base: 'r' + shift, capslock: 'R' +} + +key T { + label: 'T' + base: 't' + shift, capslock: 'T' +} + +key Y { + label: 'Y' + base: 'y' + shift, capslock: 'Y' +} + +key U { + label: 'U' + base: 'u' + shift, capslock: 'U' +} + +key I { + label: 'I' + base: 'i' + shift, capslock: 'I' +} + +key O { + label: 'O' + base: 'o' + shift, capslock: 'O' +} + +key P { + label: 'P' + base: 'p' + shift, capslock: 'P' +} + +key LEFT_BRACKET { + label: '\u00fa' + base: '\u00fa' + shift: '/' + ralt: '[' + ralt+shift: '{' +} + +key RIGHT_BRACKET { + label: ')' + base: ')' + shift: '(' + ralt: ']' + ralt+shift: '}' +} + +### ROW 3 + +key A { + label: 'A' + base: 'a' + shift, capslock: 'A' +} + +key S { + label: 'S' + base: 's' + shift, capslock: 'S' +} + +key D { + label: 'D' + base: 'd' + shift, capslock: 'D' +} + +key F { + label: 'F' + base: 'f' + shift, capslock: 'F' +} + +key G { + label: 'G' + base: 'g' + shift, capslock: 'G' +} + +key H { + label: 'H' + base: 'h' + shift, capslock: 'H' +} + +key J { + label: 'J' + base: 'j' + shift, capslock: 'J' +} + +key K { + label: 'K' + base: 'k' + shift, capslock: 'K' +} + +key L { + label: 'L' + base: 'l' + shift, capslock: 'L' +} + +key SEMICOLON { + label: '\u016f' + base: '\u016f' + shift: '"' + ralt: ';' + ralt+shift: ':' +} + +key APOSTROPHE { + label: '\u00a7' + base: '\u00a7' + shift: '!' + ralt: '\'' + ralt+shift: '"' +} + +key BACKSLASH { + label: '\u0308' + base: '\u0308' + shift: '\'' + ralt: '\\' + ralt+shift: '|' +} + +### ROW 4 + +key PLUS { + label: '\\' + base: '\\' + shift: '|' +} + +key Z { + label: 'Z' + base: 'z' + shift, capslock: 'Z' +} + +key X { + label: 'X' + base: 'x' + shift, capslock: 'X' +} + +key C { + label: 'C' + base: 'c' + shift, capslock: 'C' +} + +key V { + label: 'V' + base: 'v' + shift, capslock: 'V' + ralt: '@' +} + +key B { + label: 'B' + base: 'b' + shift, capslock: 'B' +} + +key N { + label: 'N' + base: 'n' + shift, capslock: 'N' +} + +key M { + label: 'M' + base: 'm' + shift, capslock: 'M' + ralt: '\u00b5' +} + +key COMMA { + label: ',' + base: ',' + shift: '?' + ralt: '<' +} + +key PERIOD { + label: '.' + base: '.' + shift: ':' + ralt: '>' +} + +key SLASH { + label: '-' + base: '-' + shift: '_' + ralt: '/' + ralt+shift: '?' +} diff --git a/packages/InputDevices/res/raw/keyboard_layout_danish.kcm b/packages/InputDevices/res/raw/keyboard_layout_danish.kcm new file mode 100644 index 000000000000..9386a454b6cd --- /dev/null +++ b/packages/InputDevices/res/raw/keyboard_layout_danish.kcm @@ -0,0 +1,331 @@ +# Copyright (C) 2012 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. + +# +# Danish keyboard layout. +# + +type OVERLAY + +map key 12 SLASH +map key 53 MINUS +map key 86 PLUS + +### ROW 1 + +key GRAVE { + label: '\u00bd' + base: '\u00bd' + shift: '\u00a7' +} + +key 1 { + label: '1' + base: '1' + shift: '!' +} + +key 2 { + label: '2' + base: '2' + shift: '"' + ralt: '@' +} + +key 3 { + label: '3' + base: '3' + shift: '#' + ralt: '\u00a3' +} + +key 4 { + label: '4' + base: '4' + shift: '\u00a4' + ralt: '$' +} + +key 5 { + label: '5' + base: '5' + shift: '%' +} + +key 6 { + label: '6' + base: '6' + shift: '&' +} + +key 7 { + label: '7' + base: '7' + shift: '/' + ralt: '{' +} + +key 8 { + label: '8' + base: '8' + shift: '(' + ralt: '[' +} + +key 9 { + label: '9' + base: '9' + shift: ')' + ralt: ']' +} + +key 0 { + label: '0' + base: '0' + shift: '=' + ralt: '}' +} + +key SLASH { + label: '+' + base: '+' + shift: '?' +} + +key EQUALS { + label: '\u00b4' + base: '\u0301' + shift: '\u0300' + ralt: '|' +} + +### ROW 2 + +key Q { + label: 'Q' + base: 'q' + shift, capslock: 'Q' +} + +key W { + label: 'W' + base: 'w' + shift, capslock: 'W' +} + +key E { + label: 'E' + base: 'e' + shift, capslock: 'E' + ralt: '\u20ac' +} + +key R { + label: 'R' + base: 'r' + shift, capslock: 'R' +} + +key T { + label: 'T' + base: 't' + shift, capslock: 'T' +} + +key Y { + label: 'Y' + base: 'y' + shift, capslock: 'Y' +} + +key U { + label: 'U' + base: 'u' + shift, capslock: 'U' +} + +key I { + label: 'I' + base: 'i' + shift, capslock: 'I' +} + +key O { + label: 'O' + base: 'o' + shift, capslock: 'O' +} + +key P { + label: 'P' + base: 'p' + shift, capslock: 'P' +} + +key LEFT_BRACKET { + label: '\u00c5' + base: '\u00e5' + shift, capslock: '\u00c5' +} + +key RIGHT_BRACKET { + label: '\u00a8' + base: '\u0308' + shift: '\u0302' + ralt: '\u0303' +} + +### ROW 3 + +key A { + label: 'A' + base: 'a' + shift, capslock: 'A' +} + +key S { + label: 'S' + base: 's' + shift, capslock: 'S' +} + +key D { + label: 'D' + base: 'd' + shift, capslock: 'D' +} + +key F { + label: 'F' + base: 'f' + shift, capslock: 'F' +} + +key G { + label: 'G' + base: 'g' + shift, capslock: 'G' +} + +key H { + label: 'H' + base: 'h' + shift, capslock: 'H' +} + +key J { + label: 'J' + base: 'j' + shift, capslock: 'J' +} + +key K { + label: 'K' + base: 'k' + shift, capslock: 'K' +} + +key L { + label: 'L' + base: 'l' + shift, capslock: 'L' +} + +key SEMICOLON { + label: '\u00c6' + base: '\u00e6' + shift, capslock: '\u00c6' +} + +key APOSTROPHE { + label: '\u00d8' + base: '\u00f8' + shift, capslock: '\u00d8' +} + +key BACKSLASH { + label: '\'' + base: '\'' + shift: '*' +} + +### ROW 4 + +key PLUS { + label: '<' + base: '<' + shift: '>' + ralt: '\\' +} + +key Z { + label: 'Z' + base: 'z' + shift, capslock: 'Z' +} + +key X { + label: 'X' + base: 'x' + shift, capslock: 'X' +} + +key C { + label: 'C' + base: 'c' + shift, capslock: 'C' +} + +key V { + label: 'V' + base: 'v' + shift, capslock: 'V' +} + +key B { + label: 'B' + base: 'b' + shift, capslock: 'B' +} + +key N { + label: 'N' + base: 'n' + shift, capslock: 'N' +} + +key M { + label: 'M' + base: 'm' + shift, capslock: 'M' + ralt: '\u00b5' +} + +key COMMA { + label: ',' + base: ',' + shift: ';' +} + +key PERIOD { + label: '.' + base: '.' + shift: ':' +} + +key MINUS { + label: '-' + base: '-' + shift: '_' +} diff --git a/packages/InputDevices/res/raw/keyboard_layout_estonian.kcm b/packages/InputDevices/res/raw/keyboard_layout_estonian.kcm new file mode 100644 index 000000000000..ef545b86bd1c --- /dev/null +++ b/packages/InputDevices/res/raw/keyboard_layout_estonian.kcm @@ -0,0 +1,336 @@ +# Copyright (C) 2012 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. + +# +# Estonian keyboard layout. +# + +type OVERLAY + +map key 12 SLASH +map key 53 MINUS +map key 86 PLUS + +### ROW 1 + +key GRAVE { + label: '\u02c7' + base: '\u030c' + shift: '\u0303' +} + +key 1 { + label: '1' + base: '1' + shift: '!' +} + +key 2 { + label: '2' + base: '2' + shift: '"' + ralt: '@' +} + +key 3 { + label: '3' + base: '3' + shift: '#' + ralt: '\u00a3' +} + +key 4 { + label: '4' + base: '4' + shift: '\u00a4' + ralt: '$' +} + +key 5 { + label: '5' + base: '5' + shift: '%' +} + +key 6 { + label: '6' + base: '6' + shift: '&' +} + +key 7 { + label: '7' + base: '7' + shift: '/' + ralt: '{' +} + +key 8 { + label: '8' + base: '8' + shift: '(' + ralt: '[' +} + +key 9 { + label: '9' + base: '9' + shift: ')' + ralt: ']' +} + +key 0 { + label: '0' + base: '0' + shift: '=' + ralt: '}' +} + +key SLASH { + label: '+' + base: '+' + shift: '?' + ralt: '\\' +} + +key EQUALS { + label: '\u00b4' + base: '\u0301' + shift: '\u0300' +} + +### ROW 2 + +key Q { + label: 'Q' + base: 'q' + shift, capslock: 'Q' +} + +key W { + label: 'W' + base: 'w' + shift, capslock: 'W' +} + +key E { + label: 'E' + base: 'e' + shift, capslock: 'E' + ralt: '\u20ac' +} + +key R { + label: 'R' + base: 'r' + shift, capslock: 'R' +} + +key T { + label: 'T' + base: 't' + shift, capslock: 'T' +} + +key Y { + label: 'Y' + base: 'y' + shift, capslock: 'Y' +} + +key U { + label: 'U' + base: 'u' + shift, capslock: 'U' +} + +key I { + label: 'I' + base: 'i' + shift, capslock: 'I' +} + +key O { + label: 'O' + base: 'o' + shift, capslock: 'O' +} + +key P { + label: 'P' + base: 'p' + shift, capslock: 'P' +} + +key LEFT_BRACKET { + label: '\u00dc' + base: '\u00fc' + shift, capslock: '\u00dc' +} + +key RIGHT_BRACKET { + label: '\u00d5' + base: '\u00f5' + shift, capslock: '\u00d5' + ralt: '\u00a7' +} + +### ROW 3 + +key A { + label: 'A' + base: 'a' + shift, capslock: 'A' +} + +key S { + label: 'S' + base: 's' + shift, capslock: 'S' + ralt: '\u0161' + ralt+shift, ralt+capslock: '\u0160' +} + +key D { + label: 'D' + base: 'd' + shift, capslock: 'D' +} + +key F { + label: 'F' + base: 'f' + shift, capslock: 'F' +} + +key G { + label: 'G' + base: 'g' + shift, capslock: 'G' +} + +key H { + label: 'H' + base: 'h' + shift, capslock: 'H' +} + +key J { + label: 'J' + base: 'j' + shift, capslock: 'J' +} + +key K { + label: 'K' + base: 'k' + shift, capslock: 'K' +} + +key L { + label: 'L' + base: 'l' + shift, capslock: 'L' +} + +key SEMICOLON { + label: '\u00d6' + base: '\u00f6' + shift, capslock: '\u00d6' +} + +key APOSTROPHE { + label: '\u00c4' + base: '\u00e4' + shift, capslock: '\u00c4' + ralt: '\u0302' +} + +key BACKSLASH { + label: '\'' + base: '\'' + shift: '*' + ralt: '\u00bd' +} + +### ROW 4 + +key PLUS { + label: '<' + base: '<' + shift: '>' + ralt: '|' +} + +key Z { + label: 'Z' + base: 'z' + shift, capslock: 'Z' + ralt: '\u017e' + ralt+shift, ralt+capslock: '\u017d' +} + +key X { + label: 'X' + base: 'x' + shift, capslock: 'X' +} + +key C { + label: 'C' + base: 'c' + shift, capslock: 'C' +} + +key V { + label: 'V' + base: 'v' + shift, capslock: 'V' +} + +key B { + label: 'B' + base: 'b' + shift, capslock: 'B' +} + +key N { + label: 'N' + base: 'n' + shift, capslock: 'N' +} + +key M { + label: 'M' + base: 'm' + shift, capslock: 'M' +} + +key COMMA { + label: ',' + base: ',' + shift: ';' +} + +key PERIOD { + label: '.' + base: '.' + shift: ':' +} + +key MINUS { + label: '-' + base: '-' + shift: '_' +} diff --git a/packages/InputDevices/res/raw/keyboard_layout_finnish.kcm b/packages/InputDevices/res/raw/keyboard_layout_finnish.kcm new file mode 100644 index 000000000000..c6e5ac407650 --- /dev/null +++ b/packages/InputDevices/res/raw/keyboard_layout_finnish.kcm @@ -0,0 +1,380 @@ +# Copyright (C) 2012 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. + +# +# Finnish multilingual keyboard layout. +# + +type OVERLAY + +map key 12 SLASH +map key 53 MINUS +map key 86 PLUS + +### ROW 1 + +key GRAVE { + label: '\u00a7' + base: '\u00a7' + shift: '\u00bd' + ralt: '\u0335' +} + +key 1 { + label: '1' + base: '1' + shift: '!' + ralt+shift: '\u00a1' +} + +key 2 { + label: '2' + base: '2' + shift: '"' + ralt: '@' + ralt+shift: '\u201d' +} + +key 3 { + label: '3' + base: '3' + shift: '#' + ralt: '\u00a3' + ralt+shift: '\u00bb' +} + +key 4 { + label: '4' + base: '4' + shift: '\u00a4' + ralt: '$' + ralt+shift: '\u00ab' +} + +key 5 { + label: '5' + base: '5' + shift: '%' + ralt: '\u2030' + ralt+shift: '\u201c' +} + +key 6 { + label: '6' + base: '6' + shift: '&' + ralt: '\u201a' + ralt+shift: '\u201e' +} + +key 7 { + label: '7' + base: '7' + shift: '/' + ralt: '{' +} + +key 8 { + label: '8' + base: '8' + shift: '(' + ralt: '[' +} + +key 9 { + label: '9' + base: '9' + shift: ')' + ralt: ']' +} + +key 0 { + label: '0' + base: '0' + shift: '=' + ralt: '}' + ralt+shift: '\u00b0' +} + +key SLASH { + label: '+' + base: '+' + shift: '?' + ralt: '\\' + ralt+shift: '\u00bf' +} + +key EQUALS { + label: '\u00b4' + base: '\u0301' + shift: '\u0300' + ralt: '\u0327' + ralt+shift: '\u0328' +} + +### ROW 2 + +key Q { + label: 'Q' + base: 'q' + shift, capslock: 'Q' +} + +key W { + label: 'W' + base: 'w' + shift, capslock: 'W' +} + +key E { + label: 'E' + base: 'e' + shift, capslock: 'E' + ralt: '\u20ac' +} + +key R { + label: 'R' + base: 'r' + shift, capslock: 'R' +} + +key T { + label: 'T' + base: 't' + shift, capslock: 'T' + ralt: '\u00fe' + ralt+shift, ralt+capslock: '\u00de' +} + +key Y { + label: 'Y' + base: 'y' + shift, capslock: 'Y' +} + +key U { + label: 'U' + base: 'u' + shift, capslock: 'U' +} + +key I { + label: 'I' + base: 'i' + shift, capslock: 'I' + ralt: '\u0131' +} + +key O { + label: 'O' + base: 'o' + shift, capslock: 'O' + ralt: '\u0153' + ralt+shift, ralt+capslock: '\u0152' +} + +key P { + label: 'P' + base: 'p' + shift, capslock: 'P' + ralt: '\u031b' + ralt+shift: '\u0309' +} + +key LEFT_BRACKET { + label: '\u00c5' + base: '\u00e5' + shift, capslock: '\u00c5' + ralt: '\u030b' + ralt+shift: '\u030a' +} + +key RIGHT_BRACKET { + label: '\u00a8' + base: '\u0308' + shift: '\u0302' + ralt: '\u0303' + ralt+shift: '\u0304' +} + +### ROW 3 + +key A { + label: 'A' + base: 'a' + shift, capslock: 'A' + ralt: '\u0259' + ralt+shift, ralt+capslock: '\u018f' +} + +key S { + label: 'S' + base: 's' + shift, capslock: 'S' + ralt: '\u00df' +} + +key D { + label: 'D' + base: 'd' + shift, capslock: 'D' + ralt: '\u00f0' + ralt+shift, ralt+capslock: '\u00d0' +} + +key F { + label: 'F' + base: 'f' + shift, capslock: 'F' +} + +key G { + label: 'G' + base: 'g' + shift, capslock: 'G' +} + +key H { + label: 'H' + base: 'h' + shift, capslock: 'H' +} + +key J { + label: 'J' + base: 'j' + shift, capslock: 'J' +} + +key K { + label: 'K' + base: 'k' + shift, capslock: 'K' + ralt: '\u0138' +} + +key L { + label: 'L' + base: 'l' + shift, capslock: 'L' + ralt: '\u0335' +} + +key SEMICOLON { + label: '\u00d6' + base: '\u00f6' + shift, capslock: '\u00d6' + ralt: '\u00f8' + ralt+shift, ralt+capslock: '\u00d8' +} + +key APOSTROPHE { + label: '\u00c4' + base: '\u00e4' + shift, capslock: '\u00c4' + ralt: '\u00e6' + ralt+shift, ralt+capslock: '\u00c6' +} + +key BACKSLASH { + label: '\'' + base: '\'' + shift: '*' + ralt: '\u030c' + ralt+shift: '\u0306' +} + +### ROW 4 + +key PLUS { + label: '<' + base: '<' + shift: '>' + ralt: '|' +} + +key Z { + label: 'Z' + base: 'z' + shift, capslock: 'Z' + ralt: '\u0292' + ralt+shift, ralt+capslock: '\u01b7' +} + +key X { + label: 'X' + base: 'x' + shift, capslock: 'X' + ralt: '\u00d7' + ralt+shift: '\u00b7' +} + +key C { + label: 'C' + base: 'c' + shift, capslock: 'C' +} + +key V { + label: 'V' + base: 'v' + shift, capslock: 'V' +} + +key B { + label: 'B' + base: 'b' + shift, capslock: 'B' +} + +key N { + label: 'N' + base: 'n' + shift, capslock: 'N' + ralt: '\u014b' + ralt+shift, ralt+capslock: '\u014a' +} + +key M { + label: 'M' + base: 'm' + shift, capslock: 'M' + ralt: '\u00b5' + ralt+shift: '\u2014' +} + +key COMMA { + label: ',' + base: ',' + shift: ';' + ralt: '\u2019' + ralt+shift: '\u2018' +} + +key PERIOD { + label: '.' + base: '.' + shift: ':' + ralt: '\u0323' + ralt+shift: '\u0307' +} + +key MINUS { + label: '-' + base: '-' + shift: '_' + ralt: '\u2013' + ralt+shift: '\u0307' +} diff --git a/packages/InputDevices/res/raw/keyboard_layout_hungarian.kcm b/packages/InputDevices/res/raw/keyboard_layout_hungarian.kcm new file mode 100644 index 000000000000..dafb50ba0f8f --- /dev/null +++ b/packages/InputDevices/res/raw/keyboard_layout_hungarian.kcm @@ -0,0 +1,362 @@ +# Copyright (C) 2012 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. + +# +# Hungarian keyboard layout, QWERTZ style. +# + +type OVERLAY + +map key 41 0 +map key 11 GRAVE +map key 12 SLASH +map key 21 Z +map key 44 Y +map key 53 MINUS +map key 86 PLUS + +### ROW 1 + +key 0 { + label: '0' + base: '0' + shift: '\u00a7' +} + +key 1 { + label: '1' + base: '1' + shift: '!' + ralt: '\u0303' +} + +key 2 { + label: '2' + base: '2' + shift: '"' + ralt: '\u030c' +} + +key 3 { + label: '3' + base: '3' + shift: '+' + ralt: '\u0302' +} + +key 4 { + label: '4' + base: '4' + shift: '!' + ralt: '\u0306' +} + +key 5 { + label: '5' + base: '5' + shift: '%' + ralt: '\u030a' +} + +key 6 { + label: '6' + base: '6' + shift: '/' + ralt: '\u0328' +} + +key 7 { + label: '7' + base: '7' + shift: '=' + ralt: '\u0300' +} + +key 8 { + label: '8' + base: '8' + shift: '(' + ralt: '\u0307' +} + +key 9 { + label: '9' + base: '9' + shift: ')' + ralt: '\u0301' +} + +key GRAVE { + label: '\u00d6' + base: '\u00f6' + shift, capslock: '\u00d6' + ralt: '\u030b' +} + +key SLASH { + label: '\u00dc' + base: '\u00fc' + shift, capslock: '\u00dc' + ralt: '\u0308' +} + +key EQUALS { + label: '\u00d3' + base: '\u00f3' + shift, capslock: '\u00d3' + ralt: '\u0327' +} + +### ROW 2 + +key Q { + label: 'Q' + base: 'q' + shift, capslock: 'Q' + ralt: '\\' +} + +key W { + label: 'W' + base: 'w' + shift, capslock: 'W' + ralt: '|' +} + +key E { + label: 'E' + base: 'e' + shift, capslock: 'E' + ralt: '\u00c4' +} + +key R { + label: 'R' + base: 'r' + shift, capslock: 'R' +} + +key T { + label: 'T' + base: 't' + shift, capslock: 'T' +} + +key Z { + label: 'Z' + base: 'z' + shift, capslock: 'Z' +} + +key U { + label: 'U' + base: 'u' + shift, capslock: 'U' + ralt: '\u20ac' +} + +key I { + label: 'I' + base: 'i' + shift, capslock: 'I' + ralt: '\u00cd' +} + +key O { + label: 'O' + base: 'o' + shift, capslock: 'O' +} + +key P { + label: 'P' + base: 'p' + shift, capslock: 'P' +} + +key LEFT_BRACKET { + label: '\u0150' + base: '\u0151' + shift, capslock: '\u0150' + ralt: '\u00f7' +} + +key RIGHT_BRACKET { + label: '\u00da' + base: '\u00fa' + shift, capslock: '\u00da' + ralt: '\u00d7' +} + +### ROW 3 + +key A { + label: 'A' + base: 'a' + shift, capslock: 'A' + ralt: '\u00e4' +} + +key S { + label: 'S' + base: 's' + shift, capslock: 'S' + ralt: '\u0111' +} + +key D { + label: 'D' + base: 'd' + shift, capslock: 'D' + ralt: '\u0110' +} + +key F { + label: 'F' + base: 'f' + shift, capslock: 'F' + ralt: '[' +} + +key G { + label: 'G' + base: 'g' + shift, capslock: 'G' + ralt: ']' +} + +key H { + label: 'H' + base: 'h' + shift, capslock: 'H' +} + +key J { + label: 'J' + base: 'j' + shift, capslock: 'J' + ralt: '\u00ed' +} + +key K { + label: 'K' + base: 'k' + shift, capslock: 'K' + ralt: '\u0197' +} + +key L { + label: 'L' + base: 'l' + shift, capslock: 'L' + ralt: '\u0141' +} + +key SEMICOLON { + label: '\u00c9' + base: '\u00e9' + shift, capslock: '\u00c9' + ralt: '$' +} + +key APOSTROPHE { + label: '\u00c1' + base: '\u00e1' + shift, capslock: '\u00c1' + ralt: '\u00df' +} + +key BACKSLASH { + label: '\u0170' + base: '\u0171' + shift, capslock: '\u0170' + ralt: '\u00a4' +} + +### ROW 4 + +key PLUS { + label: '\u00cd' + base: '\u00ed' + shift, capslock: '\u00cd' + ralt: '<' +} + +key Y { + label: 'Y' + base: 'y' + shift, capslock: 'Y' + ralt: '>' +} + +key X { + label: 'X' + base: 'x' + shift, capslock: 'X' + ralt: '#' +} + +key C { + label: 'C' + base: 'c' + shift, capslock: 'C' + ralt: '&' +} + +key V { + label: 'V' + base: 'v' + shift, capslock: 'V' + ralt: '@' +} + +key B { + label: 'B' + base: 'b' + shift, capslock: 'B' + ralt: '{' +} + +key N { + label: 'N' + base: 'n' + shift, capslock: 'N' + ralt: '}' +} + +key M { + label: 'M' + base: 'm' + shift, capslock: 'M' +} + +key COMMA { + label: ',' + base: ',' + shift: '?' + ralt: ';' +} + +key PERIOD { + label: '.' + base: '.' + shift: ':' +} + +key MINUS { + label: '-' + base: '-' + shift: '_' + ralt: '*' +} diff --git a/packages/InputDevices/res/raw/keyboard_layout_icelandic.kcm b/packages/InputDevices/res/raw/keyboard_layout_icelandic.kcm new file mode 100644 index 000000000000..117f58bf6f5a --- /dev/null +++ b/packages/InputDevices/res/raw/keyboard_layout_icelandic.kcm @@ -0,0 +1,332 @@ +# Copyright (C) 2012 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. + +# +# Icelandic keyboard layout. +# + +type OVERLAY + +map key 12 EQUALS +map key 13 MINUS +map key 86 PLUS + +### ROW 1 + +key GRAVE { + label: '\u02da' + base: '\u030a' + shift: '\u0308' +} + +key 1 { + label: '1' + base: '1' + shift: '!' +} + +key 2 { + label: '2' + base: '2' + shift: '"' +} + +key 3 { + label: '3' + base: '3' + shift: '#' +} + +key 4 { + label: '4' + base: '4' + shift: '$' +} + +key 5 { + label: '5' + base: '5' + shift: '%' + ralt: '\u20ac' +} + +key 6 { + label: '6' + base: '6' + shift: '&' +} + +key 7 { + label: '7' + base: '7' + shift: '/' + ralt: '{' +} + +key 8 { + label: '8' + base: '8' + shift: '(' + ralt: '[' +} + +key 9 { + label: '9' + base: '9' + shift: ')' + ralt: ']' +} + +key 0 { + label: '0' + base: '0' + shift: '=' + ralt: '}' +} + +key EQUALS { + label: '\u00d6' + base: '\u00f6' + shift, capslock: '\u00d6' + ralt: '\\' +} + +key MINUS { + label: '-' + base: '-' + shift: '_' +} + +### ROW 2 + +key Q { + label: 'Q' + base: 'q' + shift, capslock: 'Q' + ralt: '@' +} + +key W { + label: 'W' + base: 'w' + shift, capslock: 'W' +} + +key E { + label: 'E' + base: 'e' + shift, capslock: 'E' + ralt: '\u20ac' +} + +key R { + label: 'R' + base: 'r' + shift, capslock: 'R' +} + +key T { + label: 'T' + base: 't' + shift, capslock: 'T' +} + +key Y { + label: 'Y' + base: 'y' + shift, capslock: 'Y' +} + +key U { + label: 'U' + base: 'u' + shift, capslock: 'U' +} + +key I { + label: 'I' + base: 'i' + shift, capslock: 'I' +} + +key O { + label: 'O' + base: 'o' + shift, capslock: 'O' +} + +key P { + label: 'P' + base: 'p' + shift, capslock: 'P' +} + +key LEFT_BRACKET { + label: '\u0110' + base: '\u0111' + shift, capslock: '\u0110' +} + +key RIGHT_BRACKET { + label: '\'' + base: '\'' + shift: '?' + ralt: '~' +} + +### ROW 3 + +key A { + label: 'A' + base: 'a' + shift, capslock: 'A' +} + +key S { + label: 'S' + base: 's' + shift, capslock: 'S' +} + +key D { + label: 'D' + base: 'd' + shift, capslock: 'D' +} + +key F { + label: 'F' + base: 'f' + shift, capslock: 'F' +} + +key G { + label: 'G' + base: 'g' + shift, capslock: 'G' +} + +key H { + label: 'H' + base: 'h' + shift, capslock: 'H' +} + +key J { + label: 'J' + base: 'j' + shift, capslock: 'J' +} + +key K { + label: 'K' + base: 'k' + shift, capslock: 'K' +} + +key L { + label: 'L' + base: 'l' + shift, capslock: 'L' +} + +key SEMICOLON { + label: '\u00c6' + base: '\u00e6' + shift, capslock: '\u00c6' +} + +key APOSTROPHE { + label: '\u00b4' + base: '\u0301' + shift: '\'' + ralt: '^' +} + +key BACKSLASH { + label: '+' + base: '+' + shift: '*' + ralt: '`' +} + +### ROW 4 + +key PLUS { + label: '<' + base: '<' + shift: '>' + ralt: '|' +} + +key Z { + label: 'Z' + base: 'z' + shift, capslock: 'Z' +} + +key X { + label: 'X' + base: 'x' + shift, capslock: 'X' +} + +key C { + label: 'C' + base: 'c' + shift, capslock: 'C' +} + +key V { + label: 'V' + base: 'v' + shift, capslock: 'V' +} + +key B { + label: 'B' + base: 'b' + shift, capslock: 'B' +} + +key N { + label: 'N' + base: 'n' + shift, capslock: 'N' +} + +key M { + label: 'M' + base: 'm' + shift, capslock: 'M' + ralt: '\u00b5' +} + +key COMMA { + label: ',' + base: ',' + shift: ';' +} + +key PERIOD { + label: '.' + base: '.' + shift: ':' +} + +key SLASH { + label: '\u00de' + base: '\u00fe' + shift, capslock: '\u00de' +} diff --git a/packages/InputDevices/res/raw/keyboard_layout_italian.kcm b/packages/InputDevices/res/raw/keyboard_layout_italian.kcm new file mode 100644 index 000000000000..bd2d25a41a30 --- /dev/null +++ b/packages/InputDevices/res/raw/keyboard_layout_italian.kcm @@ -0,0 +1,327 @@ +# Copyright (C) 2012 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. + +# +# Italian keyboard layout. +# + +type OVERLAY + +map key 12 SLASH +map key 53 MINUS +map key 86 PLUS + +### ROW 1 + +key GRAVE { + label: '\\' + base: '\\' + shift: '|' +} + +key 1 { + label: '1' + base: '1' + shift: '!' +} + +key 2 { + label: '2' + base: '2' + shift: '"' +} + +key 3 { + label: '3' + base: '3' + shift: '\u00a3' +} + +key 4 { + label: '4' + base: '4' + shift: '$' +} + +key 5 { + label: '5' + base: '5' + shift: '%' + ralt: '\u20ac' +} + +key 6 { + label: '6' + base: '6' + shift: '&' +} + +key 7 { + label: '7' + base: '7' + shift: '/' +} + +key 8 { + label: '8' + base: '8' + shift: '(' +} + +key 9 { + label: '9' + base: '9' + shift: ')' +} + +key 0 { + label: '0' + base: '0' + shift: '=' +} + +key SLASH { + label: '\'' + base: '\'' + shift: '?' +} + +key EQUALS { + label: '\u00ec' + base: '\u00ec' + shift: '^' +} + +### ROW 2 + +key Q { + label: 'Q' + base: 'q' + shift, capslock: 'Q' +} + +key W { + label: 'W' + base: 'w' + shift, capslock: 'W' +} + +key E { + label: 'E' + base: 'e' + shift, capslock: 'E' + ralt: '\u20ac' +} + +key R { + label: 'R' + base: 'r' + shift, capslock: 'R' +} + +key T { + label: 'T' + base: 't' + shift, capslock: 'T' +} + +key Y { + label: 'Y' + base: 'y' + shift, capslock: 'Y' +} + +key U { + label: 'U' + base: 'u' + shift, capslock: 'U' +} + +key I { + label: 'I' + base: 'i' + shift, capslock: 'I' +} + +key O { + label: 'O' + base: 'o' + shift, capslock: 'O' +} + +key P { + label: 'P' + base: 'p' + shift, capslock: 'P' +} + +key LEFT_BRACKET { + label: '\u00e8' + base: '\u00e8' + shift: '\u00e9' + ralt: '[' + ralt+shift: '{' +} + +key RIGHT_BRACKET { + label: '+' + base: '+' + shift: '*' + ralt: ']' + ralt+shift: '}' +} + +### ROW 3 + +key A { + label: 'A' + base: 'a' + shift, capslock: 'A' +} + +key S { + label: 'S' + base: 's' + shift, capslock: 'S' +} + +key D { + label: 'D' + base: 'd' + shift, capslock: 'D' +} + +key F { + label: 'F' + base: 'f' + shift, capslock: 'F' +} + +key G { + label: 'G' + base: 'g' + shift, capslock: 'G' +} + +key H { + label: 'H' + base: 'h' + shift, capslock: 'H' +} + +key J { + label: 'J' + base: 'j' + shift, capslock: 'J' +} + +key K { + label: 'K' + base: 'k' + shift, capslock: 'K' +} + +key L { + label: 'L' + base: 'l' + shift, capslock: 'L' +} + +key SEMICOLON { + label: '\u00f2' + base: '\u00f2' + shift: '\u00e7' + ralt: '@' +} + +key APOSTROPHE { + label: '\u00e0' + base: '\u00e0' + shift: '\u00b0' + ralt: '#' +} + +key BACKSLASH { + label: '\u00f9' + base: '\u00f9' + shift: '\u00a7' +} + +### ROW 4 + +key PLUS { + label: '<' + base: '<' + shift: '>' +} + +key Z { + label: 'Z' + base: 'z' + shift, capslock: 'Z' +} + +key X { + label: 'X' + base: 'x' + shift, capslock: 'X' +} + +key C { + label: 'C' + base: 'c' + shift, capslock: 'C' +} + +key V { + label: 'V' + base: 'v' + shift, capslock: 'V' +} + +key B { + label: 'B' + base: 'b' + shift, capslock: 'B' +} + +key N { + label: 'N' + base: 'n' + shift, capslock: 'N' +} + +key M { + label: 'M' + base: 'm' + shift, capslock: 'M' +} + +key COMMA { + label: ',' + base: ',' + shift: ';' +} + +key PERIOD { + label: '.' + base: '.' + shift: ':' +} + +key MINUS { + label: '-' + base: '-' + shift: '_' +} diff --git a/packages/InputDevices/res/raw/keyboard_layout_norwegian.kcm b/packages/InputDevices/res/raw/keyboard_layout_norwegian.kcm new file mode 100644 index 000000000000..d1be485ed781 --- /dev/null +++ b/packages/InputDevices/res/raw/keyboard_layout_norwegian.kcm @@ -0,0 +1,330 @@ +# Copyright (C) 2012 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. + +# +# Norwegian keyboard layout. +# + +type OVERLAY + +map key 12 SLASH +map key 53 MINUS +map key 86 PLUS + +### ROW 1 + +key GRAVE { + label: '|' + base: '|' + shift: '\u00a7' +} + +key 1 { + label: '1' + base: '1' + shift: '!' +} + +key 2 { + label: '2' + base: '2' + shift: '"' + ralt: '@' +} + +key 3 { + label: '3' + base: '3' + shift: '#' + ralt: '\u00a3' +} + +key 4 { + label: '4' + base: '4' + shift: '\u00a4' + ralt: '$' +} + +key 5 { + label: '5' + base: '5' + shift: '%' +} + +key 6 { + label: '6' + base: '6' + shift: '&' +} + +key 7 { + label: '7' + base: '7' + shift: '/' + ralt: '{' +} + +key 8 { + label: '8' + base: '8' + shift: '(' + ralt: '[' +} + +key 9 { + label: '9' + base: '9' + shift: ')' + ralt: ']' +} + +key 0 { + label: '0' + base: '0' + shift: '=' + ralt: '}' +} + +key SLASH { + label: '+' + base: '+' + shift: '?' +} + +key EQUALS { + label: '\\' + base: '\\' + shift: '\u0300' + ralt: '\u0301' +} + +### ROW 2 + +key Q { + label: 'Q' + base: 'q' + shift, capslock: 'Q' +} + +key W { + label: 'W' + base: 'w' + shift, capslock: 'W' +} + +key E { + label: 'E' + base: 'e' + shift, capslock: 'E' + ralt: '\u20ac' +} + +key R { + label: 'R' + base: 'r' + shift, capslock: 'R' +} + +key T { + label: 'T' + base: 't' + shift, capslock: 'T' +} + +key Y { + label: 'Y' + base: 'y' + shift, capslock: 'Y' +} + +key U { + label: 'U' + base: 'u' + shift, capslock: 'U' +} + +key I { + label: 'I' + base: 'i' + shift, capslock: 'I' +} + +key O { + label: 'O' + base: 'o' + shift, capslock: 'O' +} + +key P { + label: 'P' + base: 'p' + shift, capslock: 'P' +} + +key LEFT_BRACKET { + label: '\u00c5' + base: '\u00e5' + shift, capslock: '\u00c5' +} + +key RIGHT_BRACKET { + label: '\u00a8' + base: '\u0308' + shift: '\u0302' + ralt: '\u0303' +} + +### ROW 3 + +key A { + label: 'A' + base: 'a' + shift, capslock: 'A' +} + +key S { + label: 'S' + base: 's' + shift, capslock: 'S' +} + +key D { + label: 'D' + base: 'd' + shift, capslock: 'D' +} + +key F { + label: 'F' + base: 'f' + shift, capslock: 'F' +} + +key G { + label: 'G' + base: 'g' + shift, capslock: 'G' +} + +key H { + label: 'H' + base: 'h' + shift, capslock: 'H' +} + +key J { + label: 'J' + base: 'j' + shift, capslock: 'J' +} + +key K { + label: 'K' + base: 'k' + shift, capslock: 'K' +} + +key L { + label: 'L' + base: 'l' + shift, capslock: 'L' +} + +key SEMICOLON { + label: '\u00d8' + base: '\u00f8' + shift, capslock: '\u00d8' +} + +key APOSTROPHE { + label: '\u00c6' + base: '\u00e6' + shift, capslock: '\u00c6' +} + +key BACKSLASH { + label: '\'' + base: '\'' + shift: '*' +} + +### ROW 4 + +key PLUS { + label: '<' + base: '<' + shift: '>' +} + +key Z { + label: 'Z' + base: 'z' + shift, capslock: 'Z' +} + +key X { + label: 'X' + base: 'x' + shift, capslock: 'X' +} + +key C { + label: 'C' + base: 'c' + shift, capslock: 'C' +} + +key V { + label: 'V' + base: 'v' + shift, capslock: 'V' +} + +key B { + label: 'B' + base: 'b' + shift, capslock: 'B' +} + +key N { + label: 'N' + base: 'n' + shift, capslock: 'N' +} + +key M { + label: 'M' + base: 'm' + shift, capslock: 'M' + ralt: '\u00b5' +} + +key COMMA { + label: ',' + base: ',' + shift: ';' +} + +key PERIOD { + label: '.' + base: '.' + shift: ':' +} + +key MINUS { + label: '-' + base: '-' + shift: '_' +} diff --git a/packages/InputDevices/res/raw/keyboard_layout_portuguese.kcm b/packages/InputDevices/res/raw/keyboard_layout_portuguese.kcm new file mode 100644 index 000000000000..47ee86708d18 --- /dev/null +++ b/packages/InputDevices/res/raw/keyboard_layout_portuguese.kcm @@ -0,0 +1,329 @@ +# Copyright (C) 2012 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. + +# +# Portuguese keyboard layout. +# + +type OVERLAY + +map key 12 SLASH +map key 53 MINUS +map key 86 PLUS + +### ROW 1 + +key GRAVE { + label: '\\' + base: '\\' + shift: '|' +} + +key 1 { + label: '1' + base: '1' + shift: '!' +} + +key 2 { + label: '2' + base: '2' + shift: '"' + ralt: '@' +} + +key 3 { + label: '3' + base: '3' + shift: '#' + ralt: '\u00a3' +} + +key 4 { + label: '4' + base: '4' + shift: '$' + ralt: '\u00a7' +} + +key 5 { + label: '5' + base: '5' + shift: '%' +} + +key 6 { + label: '6' + base: '6' + shift: '&' +} + +key 7 { + label: '7' + base: '7' + shift: '/' + ralt: '{' +} + +key 8 { + label: '8' + base: '8' + shift: '(' + ralt: '[' +} + +key 9 { + label: '9' + base: '9' + shift: ')' + ralt: ']' +} + +key 0 { + label: '0' + base: '0' + shift: '=' + ralt: '}' +} + +key SLASH { + label: '\'' + base: '\'' + shift: '?' +} + +key EQUALS { + label: '\u00ab' + base: '\u00ab' + shift: '\u00bb' +} + +### ROW 2 + +key Q { + label: 'Q' + base: 'q' + shift, capslock: 'Q' +} + +key W { + label: 'W' + base: 'w' + shift, capslock: 'W' +} + +key E { + label: 'E' + base: 'e' + shift, capslock: 'E' + ralt: '\u20ac' +} + +key R { + label: 'R' + base: 'r' + shift, capslock: 'R' +} + +key T { + label: 'T' + base: 't' + shift, capslock: 'T' +} + +key Y { + label: 'Y' + base: 'y' + shift, capslock: 'Y' +} + +key U { + label: 'U' + base: 'u' + shift, capslock: 'U' +} + +key I { + label: 'I' + base: 'i' + shift, capslock: 'I' +} + +key O { + label: 'O' + base: 'o' + shift, capslock: 'O' +} + +key P { + label: 'P' + base: 'p' + shift, capslock: 'P' +} + +key LEFT_BRACKET { + label: '+' + base: '+' + shift: '*' + ralt: '\u0308' +} + +key RIGHT_BRACKET { + label: '\u00b4' + base: '\u0301' + shift: '\u0300' +} + +### ROW 3 + +key A { + label: 'A' + base: 'a' + shift, capslock: 'A' +} + +key S { + label: 'S' + base: 's' + shift, capslock: 'S' +} + +key D { + label: 'D' + base: 'd' + shift, capslock: 'D' +} + +key F { + label: 'F' + base: 'f' + shift, capslock: 'F' +} + +key G { + label: 'G' + base: 'g' + shift, capslock: 'G' +} + +key H { + label: 'H' + base: 'h' + shift, capslock: 'H' +} + +key J { + label: 'J' + base: 'j' + shift, capslock: 'J' +} + +key K { + label: 'K' + base: 'k' + shift, capslock: 'K' +} + +key L { + label: 'L' + base: 'l' + shift, capslock: 'L' +} + +key SEMICOLON { + label: '\u00c7' + base: '\u00e7' + shift, capslock: '\u00c7' +} + +key APOSTROPHE { + label: '\u00ba' + base: '\u00ba' + shift: '\u00aa' +} + +key BACKSLASH { + label: '\u02dc' + base: '\u0303' + shift: '\u0302' +} + +### ROW 4 + +key PLUS { + label: '<' + base: '<' + shift: '>' + ralt: '\\' +} + +key Z { + label: 'Z' + base: 'z' + shift, capslock: 'Z' +} + +key X { + label: 'X' + base: 'x' + shift, capslock: 'X' +} + +key C { + label: 'C' + base: 'c' + shift, capslock: 'C' +} + +key V { + label: 'V' + base: 'v' + shift, capslock: 'V' +} + +key B { + label: 'B' + base: 'b' + shift, capslock: 'B' +} + +key N { + label: 'N' + base: 'n' + shift, capslock: 'N' +} + +key M { + label: 'M' + base: 'm' + shift, capslock: 'M' +} + +key COMMA { + label: ',' + base: ',' + shift: ';' +} + +key PERIOD { + label: '.' + base: '.' + shift: ':' +} + +key MINUS { + label: '-' + base: '-' + shift: '_' +} diff --git a/packages/InputDevices/res/raw/keyboard_layout_russian_apple.kcm b/packages/InputDevices/res/raw/keyboard_layout_russian_mac.kcm index 8c1d5967c413..11c2ad449bac 100644 --- a/packages/InputDevices/res/raw/keyboard_layout_russian_apple.kcm +++ b/packages/InputDevices/res/raw/keyboard_layout_russian_mac.kcm @@ -15,7 +15,7 @@ # # Russian keyboard layout. # This is a variant of the typical Russian PC keyboard layout that is presented -# on Apple keyboards. In contrast with the standard layout, some of the symbols and +# on Mac keyboards. In contrast with the standard layout, some of the symbols and # punctuation characters have been rearranged. # As an added convenience, English characters are accessible using ralt (Alt Gr). # diff --git a/packages/InputDevices/res/raw/keyboard_layout_slovak.kcm b/packages/InputDevices/res/raw/keyboard_layout_slovak.kcm new file mode 100644 index 000000000000..70c1fa43ca48 --- /dev/null +++ b/packages/InputDevices/res/raw/keyboard_layout_slovak.kcm @@ -0,0 +1,353 @@ +# Copyright (C) 2012 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. + +# +# Slovak keyboard layout. +# + +type OVERLAY + +map key 86 PLUS + +### ROW 1 + +key GRAVE { + label: ';' + base: ';' + shift: '\u00b0' + ralt: '`' + ralt+shift: '~' +} + +key 1 { + label: '1' + base: '+' + shift: '1' + ralt: '!' +} + +key 2 { + label: '2' + base: '\u013e' + shift: '2' + ralt: '@' +} + +key 3 { + label: '3' + base: '\u0161' + shift: '3' + ralt: '#' +} + +key 4 { + label: '4' + base: '\u010d' + shift: '4' + ralt: '$' +} + +key 5 { + label: '5' + base: '\u0165' + shift: '5' + ralt: '%' +} + +key 6 { + label: '6' + base: '\u017e' + shift: '6' + ralt: '^' +} + +key 7 { + label: '7' + base: '\u00fd' + shift: '7' + ralt: '&' +} + +key 8 { + label: '8' + base: '\u00e1' + shift: '8' + ralt: '*' +} + +key 9 { + label: '9' + base: '\u00ed' + shift: '9' + ralt: '(' +} + +key 0 { + label: '0' + base: '\u00e9' + shift: '0' + ralt: ')' +} + +key MINUS { + label: '=' + base: '=' + shift: '%' + ralt: '-' + ralt+shift: '_' +} + +key EQUALS { + label: '\u00b4' + base: '\u0301' + shift: '\u030c' + ralt: '=' + ralt+shift: '+' +} + +### ROW 2 + +key Q { + label: 'Q' + base: 'q' + shift, capslock: 'Q' + ralt: '\\' +} + +key W { + label: 'W' + base: 'w' + shift, capslock: 'W' + ralt: '|' +} + +key E { + label: 'E' + base: 'e' + shift, capslock: 'E' + ralt: '\u20ac' +} + +key R { + label: 'R' + base: 'r' + shift, capslock: 'R' +} + +key T { + label: 'T' + base: 't' + shift, capslock: 'T' +} + +key Y { + label: 'Y' + base: 'y' + shift, capslock: 'Y' +} + +key U { + label: 'U' + base: 'u' + shift, capslock: 'U' +} + +key I { + label: 'I' + base: 'i' + shift, capslock: 'I' +} + +key O { + label: 'O' + base: 'o' + shift, capslock: 'O' +} + +key P { + label: 'P' + base: 'p' + shift, capslock: 'P' +} + +key LEFT_BRACKET { + label: '\u00fa' + base: '\u00fa' + shift: '/' + ralt: '[' + ralt+shift: '{' +} + +key RIGHT_BRACKET { + label: '\u00e4' + base: '\u00e4' + shift: '(' + ralt: ']' + ralt+shift: '}' +} + +### ROW 3 + +key A { + label: 'A' + base: 'a' + shift, capslock: 'A' +} + +key S { + label: 'S' + base: 's' + shift, capslock: 'S' +} + +key D { + label: 'D' + base: 'd' + shift, capslock: 'D' +} + +key F { + label: 'F' + base: 'f' + shift, capslock: 'F' +} + +key G { + label: 'G' + base: 'g' + shift, capslock: 'G' +} + +key H { + label: 'H' + base: 'h' + shift, capslock: 'H' +} + +key J { + label: 'J' + base: 'j' + shift, capslock: 'J' +} + +key K { + label: 'K' + base: 'k' + shift, capslock: 'K' +} + +key L { + label: 'L' + base: 'l' + shift, capslock: 'L' +} + +key SEMICOLON { + label: '\u00f4' + base: '\u00f4' + shift: '"' + ralt: ';' + ralt+shift: ':' +} + +key APOSTROPHE { + label: '\u00a7' + base: '\u00a7' + shift: '!' + ralt: '\'' + ralt+shift: '"' +} + +key BACKSLASH { + label: '\u0148' + base: '\u0148' + shift: ')' + ralt: '\\' + ralt+shift: '|' +} + +### ROW 4 + +key PLUS { + label: '\\' + base: '\\' + shift: '|' + ralt: '&' + ralt+shift: '*' +} + +key Z { + label: 'Z' + base: 'z' + shift, capslock: 'Z' +} + +key X { + label: 'X' + base: 'x' + shift, capslock: 'X' +} + +key C { + label: 'C' + base: 'c' + shift, capslock: 'C' +} + +key V { + label: 'V' + base: 'v' + shift, capslock: 'V' + ralt: '@' +} + +key B { + label: 'B' + base: 'b' + shift, capslock: 'B' +} + +key N { + label: 'N' + base: 'n' + shift, capslock: 'N' +} + +key M { + label: 'M' + base: 'm' + shift, capslock: 'M' +} + +key COMMA { + label: ',' + base: ',' + shift: '?' + ralt: '<' +} + +key PERIOD { + label: '.' + base: '.' + shift: ':' + ralt: '>' +} + +key SLASH { + label: '-' + base: '-' + shift: '_' + ralt: '/' + ralt+shift: '?' +} diff --git a/packages/InputDevices/res/raw/keyboard_layout_swedish.kcm b/packages/InputDevices/res/raw/keyboard_layout_swedish.kcm new file mode 100644 index 000000000000..e42bd6c46795 --- /dev/null +++ b/packages/InputDevices/res/raw/keyboard_layout_swedish.kcm @@ -0,0 +1,331 @@ +# Copyright (C) 2012 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. + +# +# Swedish keyboard layout. +# + +type OVERLAY + +map key 12 SLASH +map key 53 MINUS +map key 86 PLUS + +### ROW 1 + +key GRAVE { + label: '\u00a7' + base: '\u00a7' + shift: '\u00bd' +} + +key 1 { + label: '1' + base: '1' + shift: '!' +} + +key 2 { + label: '2' + base: '2' + shift: '"' + ralt: '@' +} + +key 3 { + label: '3' + base: '3' + shift: '#' + ralt: '\u00a3' +} + +key 4 { + label: '4' + base: '4' + shift: '\u00a4' + ralt: '$' +} + +key 5 { + label: '5' + base: '5' + shift: '%' +} + +key 6 { + label: '6' + base: '6' + shift: '&' +} + +key 7 { + label: '7' + base: '7' + shift: '/' + ralt: '{' +} + +key 8 { + label: '8' + base: '8' + shift: '(' + ralt: '[' +} + +key 9 { + label: '9' + base: '9' + shift: ')' + ralt: ']' +} + +key 0 { + label: '0' + base: '0' + shift: '=' + ralt: '}' +} + +key SLASH { + label: '+' + base: '+' + shift: '?' + ralt: '\\' +} + +key EQUALS { + label: '\u00b4' + base: '\u0301' + shift: '\u0300' +} + +### ROW 2 + +key Q { + label: 'Q' + base: 'q' + shift, capslock: 'Q' +} + +key W { + label: 'W' + base: 'w' + shift, capslock: 'W' +} + +key E { + label: 'E' + base: 'e' + shift, capslock: 'E' + ralt: '\u20ac' +} + +key R { + label: 'R' + base: 'r' + shift, capslock: 'R' +} + +key T { + label: 'T' + base: 't' + shift, capslock: 'T' +} + +key Y { + label: 'Y' + base: 'y' + shift, capslock: 'Y' +} + +key U { + label: 'U' + base: 'u' + shift, capslock: 'U' +} + +key I { + label: 'I' + base: 'i' + shift, capslock: 'I' +} + +key O { + label: 'O' + base: 'o' + shift, capslock: 'O' +} + +key P { + label: 'P' + base: 'p' + shift, capslock: 'P' +} + +key LEFT_BRACKET { + label: '\u00c5' + base: '\u00e5' + shift, capslock: '\u00c5' +} + +key RIGHT_BRACKET { + label: '\u00a8' + base: '\u0308' + shift: '\u0302' + ralt: '\u0303' +} + +### ROW 3 + +key A { + label: 'A' + base: 'a' + shift, capslock: 'A' +} + +key S { + label: 'S' + base: 's' + shift, capslock: 'S' +} + +key D { + label: 'D' + base: 'd' + shift, capslock: 'D' +} + +key F { + label: 'F' + base: 'f' + shift, capslock: 'F' +} + +key G { + label: 'G' + base: 'g' + shift, capslock: 'G' +} + +key H { + label: 'H' + base: 'h' + shift, capslock: 'H' +} + +key J { + label: 'J' + base: 'j' + shift, capslock: 'J' +} + +key K { + label: 'K' + base: 'k' + shift, capslock: 'K' +} + +key L { + label: 'L' + base: 'l' + shift, capslock: 'L' +} + +key SEMICOLON { + label: '\u00d6' + base: '\u00f6' + shift, capslock: '\u00d6' +} + +key APOSTROPHE { + label: '\u00c4' + base: '\u00e4' + shift, capslock: '\u00c4' +} + +key BACKSLASH { + label: '\'' + base: '\'' + shift: '*' +} + +### ROW 4 + +key PLUS { + label: '<' + base: '<' + shift: '>' + ralt: '|' +} + +key Z { + label: 'Z' + base: 'z' + shift, capslock: 'Z' +} + +key X { + label: 'X' + base: 'x' + shift, capslock: 'X' +} + +key C { + label: 'C' + base: 'c' + shift, capslock: 'C' +} + +key V { + label: 'V' + base: 'v' + shift, capslock: 'V' +} + +key B { + label: 'B' + base: 'b' + shift, capslock: 'B' +} + +key N { + label: 'N' + base: 'n' + shift, capslock: 'N' +} + +key M { + label: 'M' + base: 'm' + shift, capslock: 'M' + ralt: '\u00b5' +} + +key COMMA { + label: ',' + base: ',' + shift: ';' +} + +key PERIOD { + label: '.' + base: '.' + shift: ':' +} + +key MINUS { + label: '-' + base: '-' + shift: '_' +} diff --git a/packages/InputDevices/res/raw/keyboard_layout_turkish.kcm b/packages/InputDevices/res/raw/keyboard_layout_turkish.kcm new file mode 100644 index 000000000000..e193d341caf5 --- /dev/null +++ b/packages/InputDevices/res/raw/keyboard_layout_turkish.kcm @@ -0,0 +1,347 @@ +# Copyright (C) 2012 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. + +# +# Turkish keyboard layout. +# + +type OVERLAY + +map key 12 SLASH +map key 13 MINUS +map key 43 COMMA +map key 51 EQUALS +map key 52 BACKSLASH +map key 53 PERIOD +map key 86 PLUS + +### ROW 1 + +key GRAVE { + label: '"' + base: '"' + shift: '\u00e9' + ralt: '<' +} + +key 1 { + label: '1' + base: '1' + shift: '!' + ralt: '>' +} + +key 2 { + label: '2' + base: '2' + shift: '\'' + ralt: '\u00a3' +} + +key 3 { + label: '3' + base: '3' + shift: '\u0302' + ralt: '#' +} + +key 4 { + label: '4' + base: '4' + shift: '+' + ralt: '$' +} + +key 5 { + label: '5' + base: '5' + shift: '%' + ralt: '\u00bd' +} + +key 6 { + label: '6' + base: '6' + shift: '&' +} + +key 7 { + label: '7' + base: '7' + shift: '/' + ralt: '{' +} + +key 8 { + label: '8' + base: '8' + shift: '(' + ralt: '[' +} + +key 9 { + label: '9' + base: '9' + shift: ')' + ralt: ']' +} + +key 0 { + label: '0' + base: '0' + shift: '=' + ralt: '}' +} + +key SLASH { + label: '*' + base: '*' + shift: '?' + ralt: '\\' +} + +key MINUS { + label: '-' + base: '-' + shift: '_' + ralt: '|' +} + +### ROW 2 + +key Q { + label: 'Q' + base: 'q' + shift, capslock: 'Q' + ralt: '@' +} + +key W { + label: 'W' + base: 'w' + shift, capslock: 'W' +} + +key E { + label: 'E' + base: 'e' + shift, capslock: 'E' + ralt: '\u20ac' +} + +key R { + label: 'R' + base: 'r' + shift, capslock: 'R' +} + +key T { + label: 'T' + base: 't' + shift, capslock: 'T' +} + +key Y { + label: 'Y' + base: 'y' + shift, capslock: 'Y' +} + +key U { + label: 'U' + base: 'u' + shift, capslock: 'U' +} + +key I { + label: 'I' + base: '\u0131' + shift, capslock: 'I' + ralt: 'i' + ralt+shift, ralt+capslock: '\u0130' +} + +key O { + label: 'O' + base: 'o' + shift, capslock: 'O' +} + +key P { + label: 'P' + base: 'p' + shift, capslock: 'P' +} + +key LEFT_BRACKET { + label: '\u011e' + base: '\u011f' + shift, capslock: '\u011e' + ralt: '\u0308' +} + +key RIGHT_BRACKET { + label: '\u00dc' + base: '\u00fc' + shift, capslock: '\u00dc' + ralt: '\u0303' +} + +### ROW 3 + +key A { + label: 'A' + base: 'a' + shift, capslock: 'A' + ralt: '\u00e6' + ralt+shift, ralt+capslock: '\u00c6' +} + +key S { + label: 'S' + base: 's' + shift, capslock: 'S' + ralt: '\u00df' +} + +key D { + label: 'D' + base: 'd' + shift, capslock: 'D' +} + +key F { + label: 'F' + base: 'f' + shift, capslock: 'F' +} + +key G { + label: 'G' + base: 'g' + shift, capslock: 'G' +} + +key H { + label: 'H' + base: 'h' + shift, capslock: 'H' +} + +key J { + label: 'J' + base: 'j' + shift, capslock: 'J' +} + +key K { + label: 'K' + base: 'k' + shift, capslock: 'K' +} + +key L { + label: 'L' + base: 'l' + shift, capslock: 'L' +} + +key SEMICOLON { + label: '\u015e' + base: '\u015f' + shift, capslock: '\u015e' + ralt: '\u0301' +} + +key APOSTROPHE { + label: '\u0130' + base: 'i' + shift, capslock: '\u0130' +} + +key COMMA { + label: ',' + base: ',' + shift: ';' + ralt: '\u0300' +} + +### ROW 4 + +key PLUS { + label: '<' + base: '<' + shift: '>' + ralt: '\\' +} + +key Z { + label: 'Z' + base: 'z' + shift, capslock: 'Z' +} + +key X { + label: 'X' + base: 'x' + shift, capslock: 'X' +} + +key C { + label: 'C' + base: 'c' + shift, capslock: 'C' +} + +key V { + label: 'V' + base: 'v' + shift, capslock: 'V' +} + +key B { + label: 'B' + base: 'b' + shift, capslock: 'B' +} + +key N { + label: 'N' + base: 'n' + shift, capslock: 'N' +} + +key M { + label: 'M' + base: 'm' + shift, capslock: 'M' +} + +key EQUALS { + label: '\u00d6' + base: '\u00f6' + shift, capslock: '\u00d6' +} + +key BACKSLASH { + label: '\u00c7' + base: '\u00e7' + shift, capslock: '\u00c7' +} + +key PERIOD { + label: '.' + base: '.' + shift: ':' +} diff --git a/packages/InputDevices/res/raw/keyboard_layout_ukrainian.kcm b/packages/InputDevices/res/raw/keyboard_layout_ukrainian.kcm new file mode 100644 index 000000000000..a8024603555e --- /dev/null +++ b/packages/InputDevices/res/raw/keyboard_layout_ukrainian.kcm @@ -0,0 +1,404 @@ +# Copyright (C) 2012 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. + +# +# Ukrainian keyboard layout. +# This is a typical Ukrainian PC keyboard layout. +# As an added convenience, English characters are accessible using ralt (Alt Gr). +# + +type OVERLAY + +map key 86 PLUS + +### ROW 1 + +key GRAVE { + label: '\u0401' + base: '\u0451' + shift, capslock: '\u0401' + ralt: '`' + ralt+shift: '~' +} + +key 1 { + label: '1' + base: '1' + shift: '!' + ralt: '!' +} + +key 2 { + label: '2' + base: '2' + shift: '"' + ralt: '@' +} + +key 3 { + label: '3' + base: '3' + shift: '\u2116' + ralt: '#' +} + +key 4 { + label: '4' + base: '4' + shift: ';' + ralt: '$' +} + +key 5 { + label: '5' + base: '5' + shift: '%' + ralt: '%' +} + +key 6 { + label: '6' + base: '6' + shift: ':' + ralt: '^' +} + +key 7 { + label: '7' + base: '7' + shift: '?' + ralt: '&' +} + +key 8 { + label: '8' + base: '8' + shift: '*' + ralt: '*' +} + +key 9 { + label: '9' + base: '9' + shift: '(' + ralt: '(' +} + +key 0 { + label: '0' + base: '0' + shift: ')' + ralt: ')' +} + +key MINUS { + label: '-' + base: '-' + shift: '_' + ralt: '-' + ralt+shift: '_' +} + +key EQUALS { + label: '=' + base: '=' + shift: '+' + ralt: '=' + ralt+shift: '+' +} + +### ROW 2 + +key Q { + label: '\u0419' + base: '\u0439' + shift, capslock: '\u0419' + ralt: 'q' + ralt+shift, ralt+capslock: 'Q' +} + +key W { + label: '\u0426' + base: '\u0446' + shift, capslock: '\u0426' + ralt: 'w' + ralt+shift, ralt+capslock: 'W' +} + +key E { + label: '\u0423' + base: '\u0443' + shift, capslock: '\u0423' + ralt: 'e' + ralt+shift, ralt+capslock: 'E' +} + +key R { + label: '\u041a' + base: '\u043a' + shift, capslock: '\u041a' + ralt: 'r' + ralt+shift, ralt+capslock: 'R' +} + +key T { + label: '\u0415' + base: '\u0435' + shift, capslock: '\u0415' + ralt: 't' + ralt+shift, ralt+capslock: 'T' +} + +key Y { + label: '\u041d' + base: '\u043d' + shift, capslock: '\u041d' + ralt: 'y' + ralt+shift, ralt+capslock: 'Y' +} + +key U { + label: '\u0413' + base: '\u0433' + shift, capslock: '\u0413' + ralt: 'u' + ralt+shift, ralt+capslock: 'U' +} + +key I { + label: '\u0428' + base: '\u0448' + shift, capslock: '\u0428' + ralt: 'i' + ralt+shift, ralt+capslock: 'I' +} + +key O { + label: '\u0429' + base: '\u0449' + shift, capslock: '\u0429' + ralt: 'o' + ralt+shift, ralt+capslock: 'O' +} + +key P { + label: '\u0417' + base: '\u0437' + shift, capslock: '\u0417' + ralt: 'p' + ralt+shift, ralt+capslock: 'P' +} + +key LEFT_BRACKET { + label: '\u0425' + base: '\u0445' + shift, capslock: '\u0425' + ralt: '[' + ralt+shift: '{' +} + +key RIGHT_BRACKET { + label: '\u0407' + base: '\u0457' + shift, capslock: '\u0407' + ralt: ']' + ralt+shift: '}' +} + +### ROW 3 + +key A { + label: '\u0424' + base: '\u0444' + shift, capslock: '\u0424' + ralt: 'a' + ralt+shift, ralt+capslock: 'A' +} + +key S { + label: '\u0406' + base: '\u0456' + shift, capslock: '\u0406' + ralt: 's' + ralt+shift, ralt+capslock: 'S' +} + +key D { + label: '\u0412' + base: '\u0432' + shift, capslock: '\u0412' + ralt: 'd' + ralt+shift, ralt+capslock: 'D' +} + +key F { + label: '\u0410' + base: '\u0430' + shift, capslock: '\u0410' + ralt: 'f' + ralt+shift, ralt+capslock: 'F' +} + +key G { + label: '\u041f' + base: '\u043f' + shift, capslock: '\u041f' + ralt: 'g' + ralt+shift, ralt+capslock: 'G' +} + +key H { + label: '\u0420' + base: '\u0440' + shift, capslock: '\u0420' + ralt: 'h' + ralt+shift, ralt+capslock: 'H' +} + +key J { + label: '\u041e' + base: '\u043e' + shift, capslock: '\u041e' + ralt: 'j' + ralt+shift, ralt+capslock: 'J' +} + +key K { + label: '\u041b' + base: '\u043b' + shift, capslock: '\u041b' + ralt: 'k' + ralt+shift, ralt+capslock: 'K' +} + +key L { + label: '\u0414' + base: '\u0434' + shift, capslock: '\u0414' + ralt: 'l' + ralt+shift, ralt+capslock: 'L' +} + +key SEMICOLON { + label: '\u0416' + base: '\u0436' + shift, capslock: '\u0416' + ralt: ';' + ralt+shift: ':' +} + +key APOSTROPHE { + label: '\u0404' + base: '\u0454' + shift, capslock: '\u0404' + ralt: '\'' + ralt+shift: '"' +} + +key BACKSLASH { + label: '\\' + base: '\\' + shift: '/' + ralt: '|' +} + +### ROW 4 + +key PLUS { + label: '\u0490' + base: '\u0491' + shift, capslock: '\u0490' + ralt: '\\' + ralt+shift: '|' +} + +key Z { + label: '\u042f' + base: '\u044f' + shift, capslock: '\u042f' + ralt: 'z' + ralt+shift, ralt+capslock: 'Z' +} + +key X { + label: '\u0427' + base: '\u0447' + shift, capslock: '\u0427' + ralt: 'x' + ralt+shift, ralt+capslock: 'X' +} + +key C { + label: '\u0421' + base: '\u0441' + shift, capslock: '\u0421' + ralt: 'c' + ralt+shift, ralt+capslock: 'C' +} + +key V { + label: '\u041c' + base: '\u043c' + shift, capslock: '\u041c' + ralt: 'v' + ralt+shift, ralt+capslock: 'V' +} + +key B { + label: '\u0418' + base: '\u0438' + shift, capslock: '\u0418' + ralt: 'b' + ralt+shift, ralt+capslock: 'B' +} + +key N { + label: '\u0422' + base: '\u0442' + shift, capslock: '\u0422' + ralt: 'n' + ralt+shift, ralt+capslock: 'N' +} + +key M { + label: '\u042c' + base: '\u044c' + shift, capslock: '\u042c' + ralt: 'm' + ralt+shift, ralt+capslock: 'M' +} + +key COMMA { + label: '\u0411' + base: '\u0431' + shift, capslock: '\u0411' + ralt: ',' + ralt+shift: '<' +} + +key PERIOD { + label: '\u042e' + base: '\u044e' + shift, capslock: '\u042e' + ralt: '.' + ralt+shift: '>' +} + +key SLASH { + label: '.' + base: '.' + shift: ',' + ralt: '/' + ralt+shift: '?' +} diff --git a/packages/InputDevices/res/values/strings.xml b/packages/InputDevices/res/values/strings.xml index 95e74012c68a..140c7d4243a2 100644 --- a/packages/InputDevices/res/values/strings.xml +++ b/packages/InputDevices/res/values/strings.xml @@ -7,7 +7,7 @@ <string name="keyboard_layout_english_us_label">English (US)</string> <!-- US English (Dvorak style) keyboard layout label. [CHAR LIMIT=35] --> - <string name="keyboard_layout_english_us_dvorak_label">English (US), Dvorak</string> + <string name="keyboard_layout_english_us_dvorak_label">English (US), Dvorak style</string> <!-- German keyboard layout label. [CHAR LIMIT=35] --> <string name="keyboard_layout_german_label">German</string> @@ -21,8 +21,8 @@ <!-- Russian keyboard layout label. [CHAR LIMIT=35] --> <string name="keyboard_layout_russian_label">Russian</string> - <!-- Russian (Apple style) keyboard layout label. [CHAR LIMIT=35] --> - <string name="keyboard_layout_russian_apple_label">Russian, Apple</string> + <!-- Russian (Mac style) keyboard layout label. [CHAR LIMIT=35] --> + <string name="keyboard_layout_russian_mac_label">Russian, Mac style</string> <!-- Spanish keyboard layout label. [CHAR LIMIT=35] --> <string name="keyboard_layout_spanish_label">Spanish</string> @@ -38,4 +38,49 @@ <!-- Bulgarian keyboard layout label. [CHAR LIMIT=35] --> <string name="keyboard_layout_bulgarian">Bulgarian</string> + + <!-- Italian keyboard layout label. [CHAR LIMIT=35] --> + <string name="keyboard_layout_italian">Italian</string> + + <!-- Danish keyboard layout label. [CHAR LIMIT=35] --> + <string name="keyboard_layout_danish">Danish</string> + + <!-- Norwegian keyboard layout label. [CHAR LIMIT=35] --> + <string name="keyboard_layout_norwegian">Norwegian</string> + + <!-- Swedish keyboard layout label. [CHAR LIMIT=35] --> + <string name="keyboard_layout_swedish">Swedish</string> + + <!-- Finnish keyboard layout label. [CHAR LIMIT=35] --> + <string name="keyboard_layout_finnish">Finnish</string> + + <!-- Croatian keyboard layout label. [CHAR LIMIT=35] --> + <string name="keyboard_layout_croatian">Croatian</string> + + <!-- Czech keyboard layout label. [CHAR LIMIT=35] --> + <string name="keyboard_layout_czech">Czech</string> + + <!-- Estonian keyboard layout label. [CHAR LIMIT=35] --> + <string name="keyboard_layout_estonian">Estonian</string> + + <!-- Hungarian keyboard layout label. [CHAR LIMIT=35] --> + <string name="keyboard_layout_hungarian">Hungarian</string> + + <!-- Icelandic keyboard layout label. [CHAR LIMIT=35] --> + <string name="keyboard_layout_icelandic">Icelandic</string> + + <!-- Portuguese keyboard layout label. [CHAR LIMIT=35] --> + <string name="keyboard_layout_portuguese">Portuguese</string> + + <!-- Slovak keyboard layout label. [CHAR LIMIT=35] --> + <string name="keyboard_layout_slovak">Slovak</string> + + <!-- Slovenian keyboard layout label. [CHAR LIMIT=35] --> + <string name="keyboard_layout_slovenian">Slovenian</string> + + <!-- Turkish keyboard layout label. [CHAR LIMIT=35] --> + <string name="keyboard_layout_turkish">Turkish</string> + + <!-- Ukrainian keyboard layout label. [CHAR LIMIT=35] --> + <string name="keyboard_layout_ukrainian">Ukrainian</string> </resources> diff --git a/packages/InputDevices/res/xml/keyboard_layouts.xml b/packages/InputDevices/res/xml/keyboard_layouts.xml index 50672a1353a2..23f6bcb8e6c2 100644 --- a/packages/InputDevices/res/xml/keyboard_layouts.xml +++ b/packages/InputDevices/res/xml/keyboard_layouts.xml @@ -24,9 +24,9 @@ android:label="@string/keyboard_layout_russian_label" android:kcm="@raw/keyboard_layout_russian" /> - <keyboard-layout android:name="keyboard_layout_russian_apple" - android:label="@string/keyboard_layout_russian_apple_label" - android:kcm="@raw/keyboard_layout_russian_apple" /> + <keyboard-layout android:name="keyboard_layout_russian_mac" + android:label="@string/keyboard_layout_russian_mac_label" + android:kcm="@raw/keyboard_layout_russian_mac" /> <keyboard-layout android:name="keyboard_layout_spanish" android:label="@string/keyboard_layout_spanish_label" @@ -47,4 +47,64 @@ <keyboard-layout android:name="keyboard_layout_bulgarian" android:label="@string/keyboard_layout_bulgarian" android:kcm="@raw/keyboard_layout_bulgarian" /> + + <keyboard-layout android:name="keyboard_layout_italian" + android:label="@string/keyboard_layout_italian" + android:kcm="@raw/keyboard_layout_italian" /> + + <keyboard-layout android:name="keyboard_layout_danish" + android:label="@string/keyboard_layout_danish" + android:kcm="@raw/keyboard_layout_danish" /> + + <keyboard-layout android:name="keyboard_layout_norwegian" + android:label="@string/keyboard_layout_norwegian" + android:kcm="@raw/keyboard_layout_norwegian" /> + + <keyboard-layout android:name="keyboard_layout_swedish" + android:label="@string/keyboard_layout_swedish" + android:kcm="@raw/keyboard_layout_swedish" /> + + <keyboard-layout android:name="keyboard_layout_finnish" + android:label="@string/keyboard_layout_finnish" + android:kcm="@raw/keyboard_layout_finnish" /> + + <keyboard-layout android:name="keyboard_layout_croatian" + android:label="@string/keyboard_layout_croatian" + android:kcm="@raw/keyboard_layout_croatian_and_slovenian" /> + + <keyboard-layout android:name="keyboard_layout_czech" + android:label="@string/keyboard_layout_czech" + android:kcm="@raw/keyboard_layout_czech" /> + + <keyboard-layout android:name="keyboard_layout_estonian" + android:label="@string/keyboard_layout_estonian" + android:kcm="@raw/keyboard_layout_estonian" /> + + <keyboard-layout android:name="keyboard_layout_hungarian" + android:label="@string/keyboard_layout_hungarian" + android:kcm="@raw/keyboard_layout_hungarian" /> + + <keyboard-layout android:name="keyboard_layout_icelandic" + android:label="@string/keyboard_layout_icelandic" + android:kcm="@raw/keyboard_layout_icelandic" /> + + <keyboard-layout android:name="keyboard_layout_portuguese" + android:label="@string/keyboard_layout_portuguese" + android:kcm="@raw/keyboard_layout_portuguese" /> + + <keyboard-layout android:name="keyboard_layout_slovak" + android:label="@string/keyboard_layout_slovak" + android:kcm="@raw/keyboard_layout_slovak" /> + + <keyboard-layout android:name="keyboard_layout_slovenian" + android:label="@string/keyboard_layout_slovenian" + android:kcm="@raw/keyboard_layout_croatian_and_slovenian" /> + + <keyboard-layout android:name="keyboard_layout_turkish" + android:label="@string/keyboard_layout_turkish" + android:kcm="@raw/keyboard_layout_turkish" /> + + <keyboard-layout android:name="keyboard_layout_ukrainian" + android:label="@string/keyboard_layout_ukrainian" + android:kcm="@raw/keyboard_layout_ukrainian" /> </keyboard-layouts> diff --git a/packages/SystemUI/res/values-hdpi/dimens.xml b/packages/SystemUI/res/values-hdpi/dimens.xml deleted file mode 100644 index 7cd318cc5cbe..000000000000 --- a/packages/SystemUI/res/values-hdpi/dimens.xml +++ /dev/null @@ -1,26 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - * Copyright (c) 2011, 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. -*/ ---> -<resources> - <!-- thickness (height) of each notification row, including any separators or padding --> - <!-- Note: this is 64dip + 1px divider = 97px. --> - <dimen name="notification_height">99px</dimen> - - <!-- thickness (height) of dividers between each notification row; see math for - notification_height above --> - <dimen name="notification_divider_height">4px</dimen> -</resources> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 531f154af19a..6c29c6e7c179 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -72,7 +72,7 @@ <dimen name="status_bar_icon_padding">0dp</dimen> <!-- thickness (height) of dividers between each notification row --> - <dimen name="notification_divider_height">4dp</dimen> + <dimen name="notification_divider_height">2dp</dimen> <!-- Notification drawer tuning parameters (phone UI) --> <!-- Initial velocity of the shade when expanding on its own --> diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java index 8ea08c738692..028fcbee7ac0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java @@ -436,6 +436,8 @@ public abstract class BaseStatusBar extends SystemUI implements } protected boolean inflateViews(NotificationData.Entry entry, ViewGroup parent) { + int rowHeight = + mContext.getResources().getDimensionPixelSize(R.dimen.notification_height); int minHeight = mContext.getResources().getDimensionPixelSize(R.dimen.notification_min_height); int maxHeight = @@ -462,7 +464,7 @@ public abstract class BaseStatusBar extends SystemUI implements lp.height = ViewGroup.LayoutParams.WRAP_CONTENT; expandable = Boolean.TRUE; } else { - lp.height = minHeight; + lp.height = rowHeight; } row.setLayoutParams(lp); row.setTag(R.id.expandable_tag, expandable); diff --git a/policy/src/com/android/internal/policy/impl/GlobalActions.java b/policy/src/com/android/internal/policy/impl/GlobalActions.java index cd6da853458c..3fa79b6eccd1 100644 --- a/policy/src/com/android/internal/policy/impl/GlobalActions.java +++ b/policy/src/com/android/internal/policy/impl/GlobalActions.java @@ -114,14 +114,21 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac mDeviceProvisioned = isDeviceProvisioned; if (mDialog != null) { mDialog.dismiss(); + mDialog = null; + // Show delayed, so that the dismiss of the previous dialog completes + mHandler.sendEmptyMessage(MESSAGE_SHOW); + } else { + handleShow(); } + } + + private void handleShow() { mDialog = createDialog(); prepareDialog(); mDialog.show(); mDialog.getWindow().getDecorView().setSystemUiVisibility(View.STATUS_BAR_DISABLE_EXPAND); } - /** * Create the global actions dialog. * @return A new dialog. @@ -280,7 +287,6 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac } } - /** {@inheritDoc} */ public void onDismiss(DialogInterface dialog) { if (SHOW_SILENT_TOGGLE) { @@ -694,16 +700,23 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac private static final int MESSAGE_DISMISS = 0; private static final int MESSAGE_REFRESH = 1; + private static final int MESSAGE_SHOW = 2; private static final int DIALOG_DISMISS_DELAY = 300; // ms private Handler mHandler = new Handler() { public void handleMessage(Message msg) { - if (msg.what == MESSAGE_DISMISS) { + switch (msg.what) { + case MESSAGE_DISMISS: if (mDialog != null) { mDialog.dismiss(); } - } else if (msg.what == MESSAGE_REFRESH) { + break; + case MESSAGE_REFRESH: mAdapter.notifyDataSetChanged(); + break; + case MESSAGE_SHOW: + handleShow(); + break; } } }; diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java index faa8d3ce1cd9..dd650bf229d3 100644 --- a/services/java/com/android/server/ConnectivityService.java +++ b/services/java/com/android/server/ConnectivityService.java @@ -2422,15 +2422,15 @@ private NetworkStateTracker makeWimaxStateTracker() { } // Connectivity state changed: - // [31-13] Reserved for future use - // [12-9] Network subtype (for mobile network, as defined + // [31-14] Reserved for future use + // [13-10] Network subtype (for mobile network, as defined // by TelephonyManager) - // [8-3] Detailed state ordinal (as defined by + // [9-4] Detailed state ordinal (as defined by // NetworkInfo.DetailedState) - // [2-0] Network type (as defined by ConnectivityManager) - int eventLogParam = (info.getType() & 0x7) | - ((info.getDetailedState().ordinal() & 0x3f) << 3) | - (info.getSubtype() << 9); + // [3-0] Network type (as defined by ConnectivityManager) + int eventLogParam = (info.getType() & 0xf) | + ((info.getDetailedState().ordinal() & 0x3f) << 4) | + (info.getSubtype() << 10); EventLog.writeEvent(EventLogTags.CONNECTIVITY_STATE_CHANGED, eventLogParam); diff --git a/services/java/com/android/server/EventLogTags.logtags b/services/java/com/android/server/EventLogTags.logtags index 249513f2f4ed..41f7335f9bc8 100644 --- a/services/java/com/android/server/EventLogTags.logtags +++ b/services/java/com/android/server/EventLogTags.logtags @@ -134,10 +134,10 @@ option java_package com.android.server # ConnectivityService.java # --------------------------- # Connectivity state changed: -# [31-13] Reserved for future use -# [12- 9] Network subtype (for mobile network, as defined by TelephonyManager) -# [ 8- 3] Detailed state ordinal (as defined by NetworkInfo.DetailedState) -# [ 2- 0] Network type (as defined by ConnectivityManager) +# [31-14] Reserved for future use +# [13-10] Network subtype (for mobile network, as defined by TelephonyManager) +# [ 9- 4] Detailed state ordinal (as defined by NetworkInfo.DetailedState) +# [ 3- 0] Network type (as defined by ConnectivityManager) 50020 connectivity_state_changed (custom|1|5) diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java index 510bdb2a12ed..d6606f63a686 100644 --- a/services/java/com/android/server/MountService.java +++ b/services/java/com/android/server/MountService.java @@ -668,6 +668,9 @@ class MountService extends IMountService.Stub updatePublicVolumeState(mExternalStoragePath, Environment.MEDIA_REMOVED); } + // Let package manager load internal ASECs. + mPms.updateExternalMediaStatus(true, false); + /* * Now that we've done our initialization, release * the hounds! @@ -1435,15 +1438,16 @@ class MountService extends IMountService.Stub } } - public int createSecureContainer(String id, int sizeMb, String fstype, - String key, int ownerUid) { + public int createSecureContainer(String id, int sizeMb, String fstype, String key, + int ownerUid, boolean external) { validatePermission(android.Manifest.permission.ASEC_CREATE); waitForReady(); warnOnNotMounted(); int rc = StorageResultCode.OperationSucceeded; try { - mConnector.execute("asec", "create", id, sizeMb, fstype, key, ownerUid); + mConnector.execute("asec", "create", id, sizeMb, fstype, key, ownerUid, + external ? "1" : "0"); } catch (NativeDaemonConnectorException e) { rc = StorageResultCode.OperationFailedInternalError; } @@ -1473,6 +1477,23 @@ class MountService extends IMountService.Stub return rc; } + public int fixPermissionsSecureContainer(String id, int gid, String filename) { + validatePermission(android.Manifest.permission.ASEC_CREATE); + warnOnNotMounted(); + + int rc = StorageResultCode.OperationSucceeded; + try { + mConnector.execute("asec", "fixperms", id, gid, filename); + /* + * Fix permissions does a remount, so no need to update + * mAsecMountSet + */ + } catch (NativeDaemonConnectorException e) { + rc = StorageResultCode.OperationFailedInternalError; + } + return rc; + } + public int destroySecureContainer(String id, boolean force) { validatePermission(android.Manifest.permission.ASEC_DESTROY); waitForReady(); diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java index 00d86e31e381..21ae62491605 100644 --- a/services/java/com/android/server/pm/PackageManagerService.java +++ b/services/java/com/android/server/pm/PackageManagerService.java @@ -723,7 +723,7 @@ public class PackageManagerService extends IPackageManager.Stub { } if (msg.obj != null) { @SuppressWarnings("unchecked") - Set<SdInstallArgs> args = (Set<SdInstallArgs>) msg.obj; + Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj; if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers"); // Unload containers unloadAllContainers(args); @@ -830,17 +830,6 @@ public class PackageManagerService extends IPackageManager.Stub { } } - static boolean installOnSd(int flags) { - if (((flags & PackageManager.INSTALL_FORWARD_LOCK) != 0) || - ((flags & PackageManager.INSTALL_INTERNAL) != 0)) { - return false; - } - if ((flags & PackageManager.INSTALL_EXTERNAL) != 0) { - return true; - } - return false; - } - public static final IPackageManager main(Context context, boolean factoryTest, boolean onlyCore) { PackageManagerService m = new PackageManagerService(context, factoryTest, onlyCore); @@ -5396,7 +5385,7 @@ public class PackageManagerService extends IPackageManager.Stub { synchronized (mInstallLock) { installPackageLI(args, true, res); } - args.doPostInstall(res.returnCode); + args.doPostInstall(res.returnCode, res.uid); } // A restore should be performed at this point if (a) the install @@ -5646,7 +5635,6 @@ public class PackageManagerService extends IPackageManager.Stub { */ public void handleStartCopy() throws RemoteException { int ret = PackageManager.INSTALL_SUCCEEDED; - final boolean fwdLocked = (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0; final boolean onSd = (flags & PackageManager.INSTALL_EXTERNAL) != 0; final boolean onInt = (flags & PackageManager.INSTALL_INTERNAL) != 0; PackageInfoLite pkgLite = null; @@ -5655,10 +5643,6 @@ public class PackageManagerService extends IPackageManager.Stub { // Check if both bits are set. Slog.w(TAG, "Conflicting flags specified for installing on both internal and external"); ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; - } else if (fwdLocked && onSd) { - // Check for forward locked apps - Slog.w(TAG, "Cannot install fwd locked apps on sdcard"); - ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; } else { final long lowThreshold; @@ -5835,6 +5819,10 @@ public class PackageManagerService extends IPackageManager.Stub { mArgs = createInstallArgs(this); mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; } + + public boolean isForwardLocked() { + return (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0; + } } /* @@ -5850,14 +5838,16 @@ public class PackageManagerService extends IPackageManager.Stub { final String packageName; final InstallArgs srcArgs; final InstallArgs targetArgs; + int uid; int mRet; MoveParams(InstallArgs srcArgs, IPackageMoveObserver observer, int flags, - String packageName, String dataDir) { + String packageName, String dataDir, int uid) { this.srcArgs = srcArgs; this.observer = observer; this.flags = flags; this.packageName = packageName; + this.uid = uid; if (srcArgs != null) { Uri packageUri = Uri.fromFile(new File(srcArgs.getCodePath())); targetArgs = createInstallArgs(packageUri, flags, packageName, dataDir); @@ -5892,7 +5882,7 @@ public class PackageManagerService extends IPackageManager.Stub { @Override void handleReturnCode() { - targetArgs.doPostInstall(mRet); + targetArgs.doPostInstall(mRet, uid); int currentStatus = PackageManager.MOVE_FAILED_INTERNAL_ERROR; if (mRet == PackageManager.INSTALL_SUCCEEDED) { currentStatus = PackageManager.MOVE_SUCCEEDED; @@ -5908,9 +5898,35 @@ public class PackageManagerService extends IPackageManager.Stub { } } + /** + * Used during creation of InstallArgs + * + * @param flags package installation flags + * @return true if should be installed on external storage + */ + private static boolean installOnSd(int flags) { + if ((flags & PackageManager.INSTALL_INTERNAL) != 0) { + return false; + } + if ((flags & PackageManager.INSTALL_EXTERNAL) != 0) { + return true; + } + return false; + } + + /** + * Used during creation of InstallArgs + * + * @param flags package installation flags + * @return true if should be installed as forward locked + */ + private static boolean installForwardLocked(int flags) { + return (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0; + } + private InstallArgs createInstallArgs(InstallParams params) { - if (installOnSd(params.flags)) { - return new SdInstallArgs(params); + if (installOnSd(params.flags) || params.isForwardLocked()) { + return new AsecInstallArgs(params); } else { return new FileInstallArgs(params); } @@ -5918,8 +5934,9 @@ public class PackageManagerService extends IPackageManager.Stub { private InstallArgs createInstallArgs(int flags, String fullCodePath, String fullResourcePath, String nativeLibraryPath) { - if (installOnSd(flags)) { - return new SdInstallArgs(fullCodePath, fullResourcePath, nativeLibraryPath); + if (installOnSd(flags) || installForwardLocked(flags)) { + return new AsecInstallArgs(fullCodePath, fullResourcePath, nativeLibraryPath, + (flags & PackageManager.INSTALL_EXTERNAL) != 0); } else { return new FileInstallArgs(fullCodePath, fullResourcePath, nativeLibraryPath); } @@ -5927,9 +5944,10 @@ public class PackageManagerService extends IPackageManager.Stub { // Used by package mover private InstallArgs createInstallArgs(Uri packageURI, int flags, String pkgName, String dataDir) { - if (installOnSd(flags)) { - String cid = getNextCodePath(null, pkgName, "/" + SdInstallArgs.RES_FILE_NAME); - return new SdInstallArgs(packageURI, cid); + if (installOnSd(flags) || installForwardLocked(flags)) { + String cid = getNextCodePath(null, pkgName, "/" + AsecInstallArgs.RES_FILE_NAME); + return new AsecInstallArgs(packageURI, cid, + (flags & PackageManager.INSTALL_EXTERNAL) != 0); } else { return new FileInstallArgs(packageURI, pkgName, dataDir); } @@ -5956,7 +5974,8 @@ public class PackageManagerService extends IPackageManager.Stub { abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException; abstract int doPreInstall(int status); abstract boolean doRename(int status, String pkgName, String oldCodePath); - abstract int doPostInstall(int status); + + abstract int doPostInstall(int status, int uid); abstract String getCodePath(); abstract String getResourcePath(); abstract String getNativeLibraryPath(); @@ -5964,6 +5983,10 @@ public class PackageManagerService extends IPackageManager.Stub { abstract void cleanUpResourcesLI(); abstract boolean doPostDeleteLI(boolean delete); abstract boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException; + + protected boolean isFwdLocked() { + return (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0; + } } class FileInstallArgs extends InstallArgs { @@ -6016,7 +6039,7 @@ public class PackageManagerService extends IPackageManager.Stub { try { mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION); - return imcs.checkInternalFreeStorage(packageURI, lowThreshold); + return imcs.checkInternalFreeStorage(packageURI, isFwdLocked(), lowThreshold); } finally { mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION); } @@ -6126,7 +6149,7 @@ public class PackageManagerService extends IPackageManager.Stub { } } - int doPostInstall(int status) { + int doPostInstall(int status, int uid) { if (status != PackageManager.INSTALL_SUCCEEDED) { cleanUp(); } @@ -6229,10 +6252,6 @@ public class PackageManagerService extends IPackageManager.Stub { cleanUpResourcesLI(); return true; } - - private boolean isFwdLocked() { - return (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0; - } } /** @@ -6246,20 +6265,23 @@ public class PackageManagerService extends IPackageManager.Stub { return subStr1.substring(sidx+1, eidx); } - class SdInstallArgs extends InstallArgs { + class AsecInstallArgs extends InstallArgs { static final String RES_FILE_NAME = "pkg.apk"; + static final String PUBLIC_RES_FILE_NAME = "res.zip"; String cid; String packagePath; + String resourcePath; String libraryPath; - SdInstallArgs(InstallParams params) { + AsecInstallArgs(InstallParams params) { super(params.packageURI, params.observer, params.flags, params.installerPackageName, params.manifestDigest); } - SdInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath) { - super(null, null, PackageManager.INSTALL_EXTERNAL, null, null); + AsecInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath, + boolean isExternal) { + super(null, null, isExternal ? PackageManager.INSTALL_EXTERNAL : 0, null, null); // Extract cid from fullCodePath int eidx = fullCodePath.lastIndexOf("/"); String subStr1 = fullCodePath.substring(0, eidx); @@ -6268,14 +6290,14 @@ public class PackageManagerService extends IPackageManager.Stub { setCachePath(subStr1); } - SdInstallArgs(String cid) { - super(null, null, PackageManager.INSTALL_EXTERNAL, null, null); + AsecInstallArgs(String cid) { + super(null, null, 0, null, null); this.cid = cid; setCachePath(PackageHelper.getSdDir(cid)); } - SdInstallArgs(Uri packageURI, String cid) { - super(packageURI, null, PackageManager.INSTALL_EXTERNAL, null, null); + AsecInstallArgs(Uri packageURI, String cid, boolean isExternal) { + super(packageURI, null, isExternal ? PackageManager.INSTALL_EXTERNAL : 0, null, null); this.cid = cid; } @@ -6287,12 +6309,16 @@ public class PackageManagerService extends IPackageManager.Stub { try { mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION); - return imcs.checkExternalFreeStorage(packageURI); + return imcs.checkExternalFreeStorage(packageURI, isFwdLocked()); } finally { mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION); } } + private final boolean isExternal() { + return (flags & PackageManager.INSTALL_EXTERNAL) != 0; + } + int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { if (temp) { createCopyFile(); @@ -6308,8 +6334,8 @@ public class PackageManagerService extends IPackageManager.Stub { try { mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION); - newCachePath = imcs.copyResourceToContainer(packageURI, cid, - getEncryptKey(), RES_FILE_NAME); + newCachePath = imcs.copyResourceToContainer(packageURI, cid, getEncryptKey(), + RES_FILE_NAME, PUBLIC_RES_FILE_NAME, isExternal(), isFwdLocked()); } finally { mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION); } @@ -6329,7 +6355,7 @@ public class PackageManagerService extends IPackageManager.Stub { @Override String getResourcePath() { - return packagePath; + return resourcePath; } @Override @@ -6405,22 +6431,36 @@ public class PackageManagerService extends IPackageManager.Stub { File cachePath = new File(newCachePath); libraryPath = new File(cachePath, LIB_DIR_NAME).getPath(); packagePath = new File(cachePath, RES_FILE_NAME).getPath(); + + if (isFwdLocked()) { + resourcePath = new File(cachePath, PUBLIC_RES_FILE_NAME).getPath(); + } else { + resourcePath = packagePath; + } } - int doPostInstall(int status) { + int doPostInstall(int status, int uid) { if (status != PackageManager.INSTALL_SUCCEEDED) { cleanUp(); } else { + if (uid < Process.FIRST_APPLICATION_UID + || !PackageHelper.fixSdPermissions(cid, uid, RES_FILE_NAME)) { + Slog.e(TAG, "Failed to finalize " + cid); + PackageHelper.destroySdDir(cid); + return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; + } + boolean mounted = PackageHelper.isContainerMounted(cid); if (!mounted) { - PackageHelper.mountSdDir(cid, - getEncryptKey(), Process.myUid()); + PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid()); } } return status; } private void cleanUp() { + if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp"); + // Destroy secure container PackageHelper.destroySdDir(cid); } @@ -6749,8 +6789,7 @@ public class PackageManagerService extends IPackageManager.Stub { // We didn't need to disable the .apk as a current system package, // which means we are replacing another update that is already // installed. We need to make sure to delete the older one's .apk. - res.removedInfo.args = createInstallArgs(isExternal(pkg) - ? PackageManager.INSTALL_EXTERNAL : PackageManager.INSTALL_INTERNAL, + res.removedInfo.args = createInstallArgs(0, deletedPackage.applicationInfo.sourceDir, deletedPackage.applicationInfo.publicSourceDir, deletedPackage.applicationInfo.nativeLibraryDir); @@ -6836,13 +6875,9 @@ public class PackageManagerService extends IPackageManager.Stub { // Discontinue if moving dex files failed. return; } - if((res.returnCode = setPermissionsLI(newPackage)) - != PackageManager.INSTALL_SUCCEEDED) { - mInstaller.rmdex(newPackage.mScanPath); - return; - } else { - Log.d(TAG, "New package installed in " + newPackage.mPath); - } + + Log.d(TAG, "New package installed in " + newPackage.mPath); + synchronized (mPackages) { updatePermissionsLPw(newPackage.packageName, newPackage, UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0 @@ -6872,10 +6907,9 @@ public class PackageManagerService extends IPackageManager.Stub { res.returnCode = PackageManager.INSTALL_SUCCEEDED; // Retrieve PackageSettings and parse package - int parseFlags = PackageParser.PARSE_CHATTY | - (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0) | - (onSd ? PackageParser.PARSE_ON_SDCARD : 0); - parseFlags |= mDefParseFlags; + int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY + | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0) + | (onSd ? PackageParser.PARSE_ON_SDCARD : 0); PackageParser pp = new PackageParser(tmpPackageFile.getPath()); pp.setSeparateProcesses(mSeparateProcesses); final PackageParser.Package pkg = pp.parsePackage(tmpPackageFile, @@ -6972,27 +7006,6 @@ public class PackageManagerService extends IPackageManager.Stub { } } - private int setPermissionsLI(PackageParser.Package newPackage) { - int retCode = 0; - // TODO Gross hack but fix later. Ideally move this to be a post installation - // check after alloting uid. - if (isForwardLocked(newPackage)) { - retCode = mInstaller.setForwardLockPerm(getApkName(newPackage.mPath), - newPackage.applicationInfo.uid); - } else { - // The permissions on the resource file was set when it was copied for - // non forward locked apps and apps on sdcard - } - - if (retCode != 0) { - Slog.e(TAG, "Couldn't set new package file permissions for " + newPackage.mPath - + ". The return code was: " + retCode); - // TODO Define new internal error - return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; - } - return PackageManager.INSTALL_SUCCEEDED; - } - private static boolean isForwardLocked(PackageParser.Package pkg) { return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0; } @@ -7001,6 +7014,10 @@ public class PackageManagerService extends IPackageManager.Stub { return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; } + private static boolean isExternal(PackageSetting ps) { + return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; + } + private static boolean isSystemApp(PackageParser.Package pkg) { return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; } @@ -8359,8 +8376,6 @@ public class PackageManagerService extends IPackageManager.Stub { // little while. mHandler.post(new Runnable() { public void run() { - // TODO fix this; this does nothing. - mHandler.removeCallbacks(this); updateExternalMediaStatusInner(mediaStatus, reportStatus); } }); @@ -8372,13 +8387,13 @@ public class PackageManagerService extends IPackageManager.Stub { * Please note that we always have to report status if reportStatus has been * set to true especially when unloading packages. */ - private void updateExternalMediaStatusInner(boolean mediaStatus, boolean reportStatus) { + private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus) { // Collection of uids int uidArr[] = null; // Collection of stale containers HashSet<String> removeCids = new HashSet<String>(); // Collection of packages on external media with valid containers. - HashMap<SdInstallArgs, String> processCids = new HashMap<SdInstallArgs, String>(); + HashMap<AsecInstallArgs, String> processCids = new HashMap<AsecInstallArgs, String>(); // Get list of secure containers. final String list[] = PackageHelper.getSecureContainerList(); if (list == null || list.length == 0) { @@ -8391,7 +8406,7 @@ public class PackageManagerService extends IPackageManager.Stub { // reader synchronized (mPackages) { for (String cid : list) { - SdInstallArgs args = new SdInstallArgs(cid); + AsecInstallArgs args = new AsecInstallArgs(cid); if (DEBUG_SD_INSTALL) Log.i(TAG, "Processing container " + cid); String pkgName = args.getPackageName(); @@ -8441,7 +8456,7 @@ public class PackageManagerService extends IPackageManager.Stub { } } // Process packages with valid entries. - if (mediaStatus) { + if (isMounted) { if (DEBUG_SD_INSTALL) Log.i(TAG, "Loading packages"); loadMediaPackages(processCids, uidArr, removeCids); @@ -8476,12 +8491,12 @@ public class PackageManagerService extends IPackageManager.Stub { * the cid is added to list of removeCids. We currently don't delete stale * containers. */ - private void loadMediaPackages(HashMap<SdInstallArgs, String> processCids, int uidArr[], + private void loadMediaPackages(HashMap<AsecInstallArgs, String> processCids, int uidArr[], HashSet<String> removeCids) { ArrayList<String> pkgList = new ArrayList<String>(); - Set<SdInstallArgs> keys = processCids.keySet(); + Set<AsecInstallArgs> keys = processCids.keySet(); boolean doGc = false; - for (SdInstallArgs args : keys) { + for (AsecInstallArgs args : keys) { String codePath = processCids.get(args); if (DEBUG_SD_INSTALL) Log.i(TAG, "Loading container : " + args.cid); @@ -8517,7 +8532,8 @@ public class PackageManagerService extends IPackageManager.Stub { retCode = PackageManager.INSTALL_SUCCEEDED; pkgList.add(pkg.packageName); // Post process args - args.doPostInstall(PackageManager.INSTALL_SUCCEEDED); + args.doPostInstall(PackageManager.INSTALL_SUCCEEDED, + pkg.applicationInfo.uid); } } else { Slog.i(TAG, "Failed to install pkg from " + codePath + " from sdcard"); @@ -8580,9 +8596,9 @@ public class PackageManagerService extends IPackageManager.Stub { /* * Utility method to unload a list of specified containers */ - private void unloadAllContainers(Set<SdInstallArgs> cidArgs) { + private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) { // Just unmount all valid containers. - for (SdInstallArgs arg : cidArgs) { + for (AsecInstallArgs arg : cidArgs) { synchronized (mInstallLock) { arg.doPostDeleteLI(false); } @@ -8598,14 +8614,14 @@ public class PackageManagerService extends IPackageManager.Stub { * that we always have to post this message if status has been requested no * matter what. */ - private void unloadMediaPackages(HashMap<SdInstallArgs, String> processCids, int uidArr[], + private void unloadMediaPackages(HashMap<AsecInstallArgs, String> processCids, int uidArr[], final boolean reportStatus) { if (DEBUG_SD_INSTALL) Log.i(TAG, "unloading media packages"); ArrayList<String> pkgList = new ArrayList<String>(); - ArrayList<SdInstallArgs> failedList = new ArrayList<SdInstallArgs>(); - final Set<SdInstallArgs> keys = processCids.keySet(); - for (SdInstallArgs args : keys) { + ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>(); + final Set<AsecInstallArgs> keys = processCids.keySet(); + for (AsecInstallArgs args : keys) { String pkgName = args.getPackageName(); if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to unload pkg : " + pkgName); @@ -8666,9 +8682,6 @@ public class PackageManagerService extends IPackageManager.Stub { if (pkg.applicationInfo != null && isSystemApp(pkg)) { Slog.w(TAG, "Cannot move system application"); returnCode = PackageManager.MOVE_FAILED_SYSTEM_PACKAGE; - } else if (pkg.applicationInfo != null && isForwardLocked(pkg)) { - Slog.w(TAG, "Cannot move forward locked app."); - returnCode = PackageManager.MOVE_FAILED_FORWARD_LOCKED; } else if (pkg.mOperationPending) { Slog.w(TAG, "Attempt to move package which has pending operations"); returnCode = PackageManager.MOVE_FAILED_OPERATION_PENDING; @@ -8700,13 +8713,14 @@ public class PackageManagerService extends IPackageManager.Stub { * anyway. */ if (returnCode != PackageManager.MOVE_SUCCEEDED) { - processPendingMove(new MoveParams(null, observer, 0, packageName, null), returnCode); + processPendingMove(new MoveParams(null, observer, 0, packageName, null, -1), + returnCode); } else { Message msg = mHandler.obtainMessage(INIT_COPY); InstallArgs srcArgs = createInstallArgs(currFlags, pkg.applicationInfo.sourceDir, pkg.applicationInfo.publicSourceDir, pkg.applicationInfo.nativeLibraryDir); MoveParams mp = new MoveParams(srcArgs, observer, newFlags, packageName, - pkg.applicationInfo.dataDir); + pkg.applicationInfo.dataDir, pkg.applicationInfo.uid); msg.obj = mp; mHandler.sendMessage(msg); } @@ -8831,7 +8845,8 @@ public class PackageManagerService extends IPackageManager.Stub { if (returnCode != PackageManager.MOVE_SUCCEEDED) { // Clean up failed installation if (mp.targetArgs != null) { - mp.targetArgs.doPostInstall(PackageManager.INSTALL_FAILED_INTERNAL_ERROR); + mp.targetArgs.doPostInstall(PackageManager.INSTALL_FAILED_INTERNAL_ERROR, + -1); } } else { // Force a gc to clear things up. diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java index 183beb1daf50..5afe56c78e86 100644 --- a/telephony/java/android/telephony/PhoneNumberUtils.java +++ b/telephony/java/android/telephony/PhoneNumberUtils.java @@ -1711,6 +1711,13 @@ public class PhoneNumberUtils return false; } + // STOPSHIP: remove this after figuring out issue 5914560, 6383850. + Log.d(LOG_TAG, "System property doesn't provide any emergency numbers." + + " Use embedded logic for determining emergency numbers." + + " number: " + toLogSafePhoneNumber(number) + + ", Iso: " + defaultCountryIso + + ", useExactMatch: " + useExactMatch); + // No ecclist system property, so use our own list. if (defaultCountryIso != null) { ShortNumberUtil util = new ShortNumberUtil(); @@ -1728,6 +1735,21 @@ public class PhoneNumberUtils } } + private static String toLogSafePhoneNumber(String number) { + // Do exactly same thing as Uri#toSafeString() does, which will enable us to compare + // sanitized phone numbers. + StringBuilder builder = new StringBuilder(); + for (int i = 0; i < number.length(); i++) { + char c = number.charAt(i); + if (c == '-' || c == '@' || c == '.') { + builder.append(c); + } else { + builder.append('x'); + } + } + return builder.toString(); + } + /** * Checks if a given number is an emergency number for the country that the user is in. The * current country is determined using the CountryDetector. diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java index 40ee58c078f7..56dbfb87d50f 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java @@ -2322,27 +2322,26 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { String operator = mPhone.mIccRecords.getOperatorNumeric(); int networkType = mPhone.getServiceState().getNetworkType(); - if (requestedApnType.equals(Phone.APN_TYPE_DEFAULT)) { - if (canSetPreferApn && mPreferredApn != null) { - if (DBG) { - log("buildWaitingApns: Preferred APN:" + operator + ":" + if (canSetPreferApn && mPreferredApn != null && + mPreferredApn.canHandleType(requestedApnType)) { + if (DBG) { + log("buildWaitingApns: Preferred APN:" + operator + ":" + mPreferredApn.numeric + ":" + mPreferredApn); - } - if (mPreferredApn.numeric.equals(operator)) { - if (mPreferredApn.bearer == 0 || mPreferredApn.bearer == networkType) { - apnList.add(mPreferredApn); - if (DBG) log("buildWaitingApns: X added preferred apnList=" + apnList); - return apnList; - } else { - if (DBG) log("buildWaitingApns: no preferred APN"); - setPreferredApn(-1); - mPreferredApn = null; - } + } + if (mPreferredApn.numeric.equals(operator)) { + if (mPreferredApn.bearer == 0 || mPreferredApn.bearer == networkType) { + apnList.add(mPreferredApn); + if (DBG) log("buildWaitingApns: X added preferred apnList=" + apnList); + return apnList; } else { if (DBG) log("buildWaitingApns: no preferred APN"); setPreferredApn(-1); mPreferredApn = null; } + } else { + if (DBG) log("buildWaitingApns: no preferred APN"); + setPreferredApn(-1); + mPreferredApn = null; } } if (mAllApns != null) { diff --git a/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeBasicsTest.java b/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeBasicsTest.java index 07d7c3484261..1ecccf6bfc4a 100644 --- a/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeBasicsTest.java +++ b/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeBasicsTest.java @@ -186,6 +186,13 @@ public class JavaBridgeBasicsTest extends JavaBridgeTestBase { assertRaisesException("testController.foo()"); } + public void testUncaughtJavaExceptionRaisesJavaException() throws Throwable { + injectObjectAndReload(new Object() { + public void method() { throw new RuntimeException("foo"); } + }, "testObject"); + assertRaisesException("testObject.method()"); + } + // Note that this requires that we can pass a JavaScript string to Java. public void testTypeOfStaticMethod() throws Throwable { injectObjectAndReload(new ObjectWithStaticMethod(), "testObject"); @@ -394,7 +401,6 @@ public class JavaBridgeBasicsTest extends JavaBridgeTestBase { assertEquals("", mTestController.waitForStringValue()); } - // java.lang.reflect only allows access to public methods and fields. See b/6386557. public void testReflectPublicMethod() throws Throwable { injectObjectAndReload(new Object() { public String method() { return "foo"; } @@ -404,7 +410,6 @@ public class JavaBridgeBasicsTest extends JavaBridgeTestBase { ".toString()")); } - // java.lang.reflect only allows access to public methods and fields. See b/6386557. public void testReflectPublicField() throws Throwable { injectObjectAndReload(new Object() { public String field = "foo"; @@ -412,4 +417,26 @@ public class JavaBridgeBasicsTest extends JavaBridgeTestBase { assertEquals("foo", executeJavaScriptAndGetStringResult( "testObject.getClass().getField('field').get(testObject).toString()")); } + + public void testReflectPrivateMethodRaisesException() throws Throwable { + injectObjectAndReload(new Object() { + private void method() {}; + }, "testObject"); + assertRaisesException("testObject.getClass().getMethod('method', null)"); + // getDeclaredMethod() is able to access a private method, but invoke() + // throws a Java exception. + assertRaisesException( + "testObject.getClass().getDeclaredMethod('method', null).invoke(testObject, null)"); + } + + public void testReflectPrivateFieldRaisesException() throws Throwable { + injectObjectAndReload(new Object() { + private int field; + }, "testObject"); + assertRaisesException("testObject.getClass().getField('field')"); + // getDeclaredField() is able to access a private field, but getInt() + // throws a Java exception. + assertRaisesException( + "testObject.getClass().getDeclaredField('field').getInt(testObject)"); + } } diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp index a4473c8c6951..d428fefc6cd9 100644 --- a/tools/aapt/Command.cpp +++ b/tools/aapt/Command.cpp @@ -1740,20 +1740,6 @@ int doPackage(Bundle* bundle) // Write the R.java file into the appropriate class directory // e.g. gen/com/foo/app/R.java err = writeResourceSymbols(bundle, assets, assets->getPackage(), true); - // If we have library files, we're going to write our R.java file into - // the appropriate class directory for those libraries as well. - // e.g. gen/com/foo/app/lib/R.java - if (bundle->getExtraPackages() != NULL) { - // Split on colon - String8 libs(bundle->getExtraPackages()); - char* packageString = strtok(libs.lockBuffer(libs.length()), ":"); - while (packageString != NULL) { - // Write the R.java file out with the correct package name - err = writeResourceSymbols(bundle, assets, String8(packageString), true); - packageString = strtok(NULL, ":"); - } - libs.unlockBuffer(); - } } else { const String8 customPkg(bundle->getCustomPackage()); err = writeResourceSymbols(bundle, assets, customPkg, true); @@ -1761,6 +1747,23 @@ int doPackage(Bundle* bundle) if (err < 0) { goto bail; } + // If we have library files, we're going to write our R.java file into + // the appropriate class directory for those libraries as well. + // e.g. gen/com/foo/app/lib/R.java + if (bundle->getExtraPackages() != NULL) { + // Split on colon + String8 libs(bundle->getExtraPackages()); + char* packageString = strtok(libs.lockBuffer(libs.length()), ":"); + while (packageString != NULL) { + // Write the R.java file out with the correct package name + err = writeResourceSymbols(bundle, assets, String8(packageString), true); + if (err < 0) { + goto bail; + } + packageString = strtok(NULL, ":"); + } + libs.unlockBuffer(); + } } else { err = writeResourceSymbols(bundle, assets, assets->getPackage(), false); if (err < 0) { diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java index 705e3c7a1ca8..ac0fbfae8f87 100644 --- a/wifi/java/android/net/wifi/WifiStateMachine.java +++ b/wifi/java/android/net/wifi/WifiStateMachine.java @@ -1534,8 +1534,7 @@ public class WifiStateMachine extends StateMachine { private void sendNetworkStateChangeBroadcast(String bssid) { Intent intent = new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION); - intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT - | Intent.FLAG_RECEIVER_REPLACE_PENDING); + intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); intent.putExtra(WifiManager.EXTRA_NETWORK_INFO, new NetworkInfo(mNetworkInfo)); intent.putExtra(WifiManager.EXTRA_LINK_PROPERTIES, new LinkProperties (mLinkProperties)); if (bssid != null) |