diff options
53 files changed, 823 insertions, 289 deletions
diff --git a/api/current.xml b/api/current.xml index 212e661..442fc4f 100644 --- a/api/current.xml +++ b/api/current.xml @@ -72368,6 +72368,19 @@ <parameter name="longitude" type="double"> </parameter> </method> +<method name="setGpsProcessingMethod" + return="void" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="processing_method" type="java.lang.String"> +</parameter> +</method> <method name="setGpsTimestamp" return="void" abstract="false" @@ -74097,7 +74110,7 @@ type="float" transient="false" volatile="false" - value="0.0010f" + value="0.001f" static="true" final="true" deprecated="not deprecated" @@ -85548,7 +85561,7 @@ type="int" transient="false" volatile="false" - value="4" + value="2" static="true" final="true" deprecated="not deprecated" @@ -85566,7 +85579,7 @@ visibility="public" > </field> -<field name="TARGET_SIZE_NORMAL_THUMBNAIL" +<field name="TARGET_SIZE_MINI_THUMBNAIL" type="int" transient="false" volatile="false" @@ -213916,7 +213929,7 @@ deprecated="not deprecated" visibility="public" > -<parameter name="arg0" type="T"> +<parameter name="t" type="T"> </parameter> </method> </interface> diff --git a/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java b/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java index 7e9fd61..67c658d 100644 --- a/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java +++ b/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java @@ -311,7 +311,7 @@ public final class Bmgr { doRestorePackage(arg); } else { try { - long token = Long.parseLong(nextArg(), 16); + long token = Long.parseLong(arg, 16); doRestoreAll(token); } catch (NumberFormatException e) { showUsage(); diff --git a/core/java/android/accounts/AccountAuthenticatorCache.java b/core/java/android/accounts/AccountAuthenticatorCache.java index d6c76a2..d2b3bc7 100644 --- a/core/java/android/accounts/AccountAuthenticatorCache.java +++ b/core/java/android/accounts/AccountAuthenticatorCache.java @@ -19,6 +19,7 @@ package android.accounts; import android.content.pm.PackageManager; import android.content.pm.RegisteredServicesCache; import android.content.pm.XmlSerializerAndParser; +import android.content.res.Resources; import android.content.res.TypedArray; import android.content.Context; import android.util.AttributeSet; @@ -47,8 +48,9 @@ import java.io.IOException; AccountManager.AUTHENTICATOR_ATTRIBUTES_NAME, sSerializer); } - public AuthenticatorDescription parseServiceAttributes(String packageName, AttributeSet attrs) { - TypedArray sa = mContext.getResources().obtainAttributes(attrs, + public AuthenticatorDescription parseServiceAttributes(Resources res, + String packageName, AttributeSet attrs) { + TypedArray sa = res.obtainAttributes(attrs, com.android.internal.R.styleable.AccountAuthenticator); try { final String accountType = diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java index c2afd07..c951ce9 100644 --- a/core/java/android/app/SearchDialog.java +++ b/core/java/android/app/SearchDialog.java @@ -576,7 +576,14 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS } mVoiceButton.setVisibility(visibility); } - + + /** Called by SuggestionsAdapter when the cursor contents changed. */ + void onDataSetChanged() { + if (mSearchAutoComplete != null && mSuggestionsAdapter != null) { + mSearchAutoComplete.onFilterComplete(mSuggestionsAdapter.getCount()); + } + } + /** * Hack to determine whether this is the browser, so we can adjust the UI. */ diff --git a/core/java/android/app/SuggestionsAdapter.java b/core/java/android/app/SuggestionsAdapter.java index 3e11a3f..1ae9315 100644 --- a/core/java/android/app/SuggestionsAdapter.java +++ b/core/java/android/app/SuggestionsAdapter.java @@ -189,6 +189,8 @@ class SuggestionsAdapter extends ResourceCursorAdapter { if (DBG) Log.d(LOG_TAG, "notifyDataSetChanged"); super.notifyDataSetChanged(); + mSearchDialog.onDataSetChanged(); + updateSpinnerState(getCursor()); } diff --git a/core/java/android/app/WallpaperInfo.java b/core/java/android/app/WallpaperInfo.java index 5ca3fb5..7db9fa8 100644 --- a/core/java/android/app/WallpaperInfo.java +++ b/core/java/android/app/WallpaperInfo.java @@ -25,7 +25,9 @@ import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; +import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.Resources.NotFoundException; +import android.content.res.Resources; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; import android.graphics.drawable.Drawable; @@ -96,6 +98,8 @@ public final class WallpaperInfo implements Parcelable { + WallpaperService.SERVICE_META_DATA + " meta-data"); } + Resources res = pm.getResourcesForApplication(si.applicationInfo); + AttributeSet attrs = Xml.asAttributeSet(parser); int type; @@ -109,7 +113,7 @@ public final class WallpaperInfo implements Parcelable { "Meta-data does not start with wallpaper tag"); } - TypedArray sa = context.getResources().obtainAttributes(attrs, + TypedArray sa = res.obtainAttributes(attrs, com.android.internal.R.styleable.Wallpaper); settingsActivityComponent = sa.getString( com.android.internal.R.styleable.Wallpaper_settingsActivity); @@ -125,6 +129,9 @@ public final class WallpaperInfo implements Parcelable { -1); sa.recycle(); + } catch (NameNotFoundException e) { + throw new XmlPullParserException( + "Unable to create context for: " + si.packageName); } finally { if (parser != null) parser.close(); } diff --git a/core/java/android/app/admin/DeviceAdminInfo.java b/core/java/android/app/admin/DeviceAdminInfo.java index c4de812..0bcd65c 100644 --- a/core/java/android/app/admin/DeviceAdminInfo.java +++ b/core/java/android/app/admin/DeviceAdminInfo.java @@ -26,6 +26,8 @@ import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; +import android.content.pm.PackageManager.NameNotFoundException; +import android.content.res.Resources; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; import android.content.res.Resources.NotFoundException; @@ -181,6 +183,8 @@ public final class DeviceAdminInfo implements Parcelable { + DeviceAdminReceiver.DEVICE_ADMIN_META_DATA + " meta-data"); } + Resources res = pm.getResourcesForApplication(ai.applicationInfo); + AttributeSet attrs = Xml.asAttributeSet(parser); int type; @@ -194,7 +198,7 @@ public final class DeviceAdminInfo implements Parcelable { "Meta-data does not start with device-admin tag"); } - TypedArray sa = context.getResources().obtainAttributes(attrs, + TypedArray sa = res.obtainAttributes(attrs, com.android.internal.R.styleable.DeviceAdmin); mVisible = sa.getBoolean( @@ -227,6 +231,9 @@ public final class DeviceAdminInfo implements Parcelable { } } } + } catch (NameNotFoundException e) { + throw new XmlPullParserException( + "Unable to create context for: " + ai.packageName); } finally { if (parser != null) parser.close(); } diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index 179b807..e63851f 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -1423,7 +1423,7 @@ public class Intent implements Parcelable, Cloneable { */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE = - "android.intent.action.EXTERNAL_APPLICATIONS_UNAVAILABILE"; + "android.intent.action.EXTERNAL_APPLICATIONS_UNAVAILABLE"; /** * Broadcast Action: The current system wallpaper has changed. See diff --git a/core/java/android/content/SyncAdaptersCache.java b/core/java/android/content/SyncAdaptersCache.java index 6ade837..98a2595 100644 --- a/core/java/android/content/SyncAdaptersCache.java +++ b/core/java/android/content/SyncAdaptersCache.java @@ -18,6 +18,7 @@ package android.content; import android.content.pm.RegisteredServicesCache; import android.content.pm.XmlSerializerAndParser; +import android.content.res.Resources; import android.content.res.TypedArray; import android.util.AttributeSet; import org.xmlpull.v1.XmlPullParser; @@ -42,8 +43,9 @@ import java.io.IOException; super(context, SERVICE_INTERFACE, SERVICE_META_DATA, ATTRIBUTES_NAME, sSerializer); } - public SyncAdapterType parseServiceAttributes(String packageName, AttributeSet attrs) { - TypedArray sa = mContext.getResources().obtainAttributes(attrs, + public SyncAdapterType parseServiceAttributes(Resources res, + String packageName, AttributeSet attrs) { + TypedArray sa = res.obtainAttributes(attrs, com.android.internal.R.styleable.SyncAdapter); try { final String authority = diff --git a/core/java/android/content/pm/RegisteredServicesCache.java b/core/java/android/content/pm/RegisteredServicesCache.java index b74c073..dce3963 100644 --- a/core/java/android/content/pm/RegisteredServicesCache.java +++ b/core/java/android/content/pm/RegisteredServicesCache.java @@ -21,6 +21,8 @@ import android.content.BroadcastReceiver; import android.content.Intent; import android.content.IntentFilter; import android.content.ComponentName; +import android.content.pm.PackageManager.NameNotFoundException; +import android.content.res.Resources; import android.content.res.XmlResourceParser; import android.os.Environment; import android.os.Handler; @@ -402,7 +404,8 @@ public abstract class RegisteredServicesCache<V> { "Meta-data does not start with " + mAttributesName + " tag"); } - V v = parseServiceAttributes(si.packageName, attrs); + V v = parseServiceAttributes(pm.getResourcesForApplication(si.applicationInfo), + si.packageName, attrs); if (v == null) { return null; } @@ -410,6 +413,9 @@ public abstract class RegisteredServicesCache<V> { final ApplicationInfo applicationInfo = serviceInfo.applicationInfo; final int uid = applicationInfo.uid; return new ServiceInfo<V>(v, componentName, uid); + } catch (NameNotFoundException e) { + throw new XmlPullParserException( + "Unable to load resources for pacakge " + si.packageName); } finally { if (parser != null) parser.close(); } @@ -499,5 +505,6 @@ public abstract class RegisteredServicesCache<V> { } } - public abstract V parseServiceAttributes(String packageName, AttributeSet attrs); + public abstract V parseServiceAttributes(Resources res, + String packageName, AttributeSet attrs); } diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java index 9fa9368..2974981 100644 --- a/core/java/android/database/sqlite/SQLiteDatabase.java +++ b/core/java/android/database/sqlite/SQLiteDatabase.java @@ -1542,7 +1542,6 @@ public class SQLiteDatabase extends SQLiteClosable { } } statement.execute(); - statement.close(); return lastChangeCount(); } catch (SQLiteDatabaseCorruptException e) { onCorruption(); @@ -1638,7 +1637,6 @@ public class SQLiteDatabase extends SQLiteClosable { // Run the program and then cleanup statement.execute(); - statement.close(); int numChangedRows = lastChangeCount(); if (Config.LOGD && Log.isLoggable(TAG, Log.VERBOSE)) { Log.v(TAG, "Updated " + numChangedRows + " using " + values + " and " + sql); diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java index cddbec9..0efcad9 100644 --- a/core/java/android/hardware/Camera.java +++ b/core/java/android/hardware/Camera.java @@ -717,6 +717,7 @@ public class Camera { private static final String KEY_GPS_LONGITUDE = "gps-longitude"; private static final String KEY_GPS_ALTITUDE = "gps-altitude"; private static final String KEY_GPS_TIMESTAMP = "gps-timestamp"; + private static final String KEY_GPS_PROCESSING_METHOD = "gps-processing-method"; private static final String KEY_WHITE_BALANCE = "whitebalance"; private static final String KEY_EFFECT = "effect"; private static final String KEY_ANTIBANDING = "antibanding"; @@ -1327,6 +1328,16 @@ public class Camera { } /** + * Sets GPS processing method. It will store up to 100 characters + * in JPEG EXIF header. + * + * @param processing_method The processing method to get this location. + */ + public void setGpsProcessingMethod(String processing_method) { + set(KEY_GPS_PROCESSING_METHOD, processing_method); + } + + /** * Removes GPS latitude, longitude, altitude, and timestamp from the * parameters. */ @@ -1335,6 +1346,7 @@ public class Camera { remove(KEY_GPS_LONGITUDE); remove(KEY_GPS_ALTITUDE); remove(KEY_GPS_TIMESTAMP); + remove(KEY_GPS_PROCESSING_METHOD); } /** diff --git a/core/java/android/net/SSLCertificateSocketFactory.java b/core/java/android/net/SSLCertificateSocketFactory.java index 6941e57..a8c6f9b 100644 --- a/core/java/android/net/SSLCertificateSocketFactory.java +++ b/core/java/android/net/SSLCertificateSocketFactory.java @@ -158,7 +158,7 @@ public class SSLCertificateSocketFactory extends SSLSocketFactory { private synchronized SSLSocketFactory getDelegate() { // Relax the SSL check if instructed (for this factory, or systemwide) - if (!mSecure || ("0".equals(SystemProperties.get("ro.secure")) && + if (!mSecure || ("1".equals(SystemProperties.get("ro.debuggable")) && "yes".equals(SystemProperties.get("socket.relaxsslcheck")))) { if (mInsecureFactory == null) { if (mSecure) { diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl index 92041d8..d1d8b0a 100644 --- a/core/java/android/os/INetworkManagementService.aidl +++ b/core/java/android/os/INetworkManagementService.aidl @@ -162,4 +162,15 @@ interface INetworkManagementService * Check the status of USB RNDIS support */ boolean isUsbRNDISStarted(); + + /** + * Start Wifi Access Point + */ + void startAccessPoint(); + + /** + * Stop Wifi Access Point + */ + void stopAccessPoint(); + } diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 18e2647..8f410a9 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -2386,6 +2386,13 @@ public final class Settings { public static final String WIFI_ON = "wifi_on"; /** + * Whether the Wi-Fi AP should be on. + * + * @hide + */ + public static final String WIFI_AP_ON = "wifi_ap_on"; + + /** * The acceptable packet loss percentage (range 0 - 100) before trying * another AP on the same network. */ diff --git a/core/java/android/view/VelocityTracker.java b/core/java/android/view/VelocityTracker.java index 91fd6f1..c17a724 100644 --- a/core/java/android/view/VelocityTracker.java +++ b/core/java/android/view/VelocityTracker.java @@ -100,6 +100,7 @@ public final class VelocityTracker implements Poolable<VelocityTracker> { } private VelocityTracker() { + clear(); } /** @@ -109,7 +110,7 @@ public final class VelocityTracker implements Poolable<VelocityTracker> { final long[][] pastTime = mPastTime; for (int p = 0; p < MotionEvent.BASE_AVAIL_POINTERS; p++) { for (int i = 0; i < NUM_PAST; i++) { - pastTime[p][i] = 0; + pastTime[p][i] = Long.MIN_VALUE; } } } @@ -129,7 +130,7 @@ public final class VelocityTracker implements Poolable<VelocityTracker> { int touchIndex = (mLastTouch + 1) % NUM_PAST; for (int i=0; i<N; i++) { for (int id = 0; id < MotionEvent.BASE_AVAIL_POINTERS; id++) { - mPastTime[id][touchIndex] = 0; + mPastTime[id][touchIndex] = Long.MIN_VALUE; } for (int p = 0; p < pointerCount; p++) { int id = ev.getPointerId(p); @@ -141,10 +142,10 @@ public final class VelocityTracker implements Poolable<VelocityTracker> { touchIndex = (touchIndex + 1) % NUM_PAST; } - // During calculation any pointer values with a time of 0 are treated - // as a break in input. Initialize all to 0 for each new touch index. + // During calculation any pointer values with a time of MIN_VALUE are treated + // as a break in input. Initialize all to MIN_VALUE for each new touch index. for (int id = 0; id < MotionEvent.BASE_AVAIL_POINTERS; id++) { - mPastTime[id][touchIndex] = 0; + mPastTime[id][touchIndex] = Long.MIN_VALUE; } final long time = ev.getEventTime(); for (int p = 0; p < pointerCount; p++) { @@ -189,7 +190,7 @@ public final class VelocityTracker implements Poolable<VelocityTracker> { // find oldest acceptable time int oldestTouch = lastTouch; - if (pastTime[lastTouch] > 0) { // cleared ? + if (pastTime[lastTouch] != Long.MIN_VALUE) { // cleared ? final float acceptableTime = pastTime[lastTouch] - LONGEST_PAST_TIME; int nextOldestTouch = (NUM_PAST + oldestTouch - 1) % NUM_PAST; while (pastTime[nextOldestTouch] >= acceptableTime && diff --git a/core/java/android/view/inputmethod/InputMethodInfo.java b/core/java/android/view/inputmethod/InputMethodInfo.java index 316bcd6..357cb5f 100644 --- a/core/java/android/view/inputmethod/InputMethodInfo.java +++ b/core/java/android/view/inputmethod/InputMethodInfo.java @@ -25,6 +25,8 @@ import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; +import android.content.pm.PackageManager.NameNotFoundException; +import android.content.res.Resources; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; import android.graphics.drawable.Drawable; @@ -92,6 +94,8 @@ public final class InputMethodInfo implements Parcelable { + InputMethod.SERVICE_META_DATA + " meta-data"); } + Resources res = pm.getResourcesForApplication(si.applicationInfo); + AttributeSet attrs = Xml.asAttributeSet(parser); int type; @@ -105,13 +109,16 @@ public final class InputMethodInfo implements Parcelable { "Meta-data does not start with input-method tag"); } - TypedArray sa = context.getResources().obtainAttributes(attrs, + TypedArray sa = res.obtainAttributes(attrs, com.android.internal.R.styleable.InputMethod); settingsActivityComponent = sa.getString( com.android.internal.R.styleable.InputMethod_settingsActivity); isDefaultResId = sa.getResourceId( com.android.internal.R.styleable.InputMethod_isDefault, 0); sa.recycle(); + } catch (NameNotFoundException e) { + throw new XmlPullParserException( + "Unable to create context for: " + si.packageName); } finally { if (parser != null) parser.close(); } diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index a555ae4..b78373d 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -2387,6 +2387,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te mVelocityTracker.clear(); } } + awakenScrollBars(); } private int getOverscrollMax() { diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp index 5afa034..a2b7cc4 100644 --- a/core/jni/android_util_AssetManager.cpp +++ b/core/jni/android_util_AssetManager.cpp @@ -18,6 +18,7 @@ #define LOG_TAG "asset" #define DEBUG_STYLES(x) //x +#define THROW_ON_BAD_ID 0 #include <android_runtime/android_util_AssetManager.h> @@ -719,9 +720,21 @@ static jint android_content_AssetManager_loadResourceValue(JNIEnv* env, jobject ResTable_config config; uint32_t typeSpecFlags; ssize_t block = res.getResource(ident, &value, false, &typeSpecFlags, &config); +#if THROW_ON_BAD_ID + if (block == BAD_INDEX) { + jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!"); + return 0; + } +#endif uint32_t ref = ident; if (resolve) { block = res.resolveReference(&value, block, &ref); +#if THROW_ON_BAD_ID + if (block == BAD_INDEX) { + jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!"); + return 0; + } +#endif } return block >= 0 ? copyValue(env, outValue, &res, value, ref, block, typeSpecFlags, &config) : block; } @@ -763,6 +776,12 @@ static jint android_content_AssetManager_loadResourceBagValue(JNIEnv* env, jobje uint32_t ref = ident; if (resolve) { block = res.resolveReference(&value, block, &ref, &typeSpecFlags); +#if THROW_ON_BAD_ID + if (block == BAD_INDEX) { + jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!"); + return 0; + } +#endif } return block >= 0 ? copyValue(env, outValue, &res, value, ref, block, typeSpecFlags) : block; } @@ -852,6 +871,12 @@ static jint android_content_AssetManager_loadThemeAttributeValue( uint32_t ref = 0; if (resolve) { block = res.resolveReference(&value, block, &ref, &typeSpecFlags); +#if THROW_ON_BAD_ID + if (block == BAD_INDEX) { + jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!"); + return 0; + } +#endif } return block >= 0 ? copyValue(env, outValue, &res, value, ref, block, typeSpecFlags) : block; } @@ -1071,6 +1096,12 @@ static jboolean android_content_AssetManager_applyStyle(JNIEnv* env, jobject cla value.dataType, value.data)); newBlock = res.resolveReference(&value, block, &resid, &typeSetFlags, &config); +#if THROW_ON_BAD_ID + if (newBlock == BAD_INDEX) { + jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!"); + return JNI_FALSE; + } +#endif if (newBlock >= 0) block = newBlock; DEBUG_STYLES(LOGI("-> Resolved theme: type=0x%x, data=0x%08x", value.dataType, value.data)); @@ -1207,6 +1238,12 @@ static jboolean android_content_AssetManager_retrieveAttributes(JNIEnv* env, job //printf("Resolving attribute reference\n"); ssize_t newBlock = res.resolveReference(&value, block, &resid, &typeSetFlags, &config); +#if THROW_ON_BAD_ID + if (newBlock == BAD_INDEX) { + jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!"); + return JNI_FALSE; + } +#endif if (newBlock >= 0) block = newBlock; } @@ -1314,6 +1351,12 @@ static jint android_content_AssetManager_retrieveArray(JNIEnv* env, jobject claz //printf("Resolving attribute reference\n"); ssize_t newBlock = res.resolveReference(&value, block, &resid, &typeSetFlags, &config); +#if THROW_ON_BAD_ID + if (newBlock == BAD_INDEX) { + jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!"); + return JNI_FALSE; + } +#endif if (newBlock >= 0) block = newBlock; } @@ -1421,6 +1464,13 @@ static jintArray android_content_AssetManager_getArrayStringInfo(JNIEnv* env, jo stringIndex = value.data; } +#if THROW_ON_BAD_ID + if (stringBlock == BAD_INDEX) { + jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!"); + return array; + } +#endif + //todo: It might be faster to allocate a C array to contain // the blocknums and indices, put them in there and then // do just one SetIntArrayRegion() @@ -1469,6 +1519,12 @@ static jobjectArray android_content_AssetManager_getArrayStringResource(JNIEnv* // Take care of resolving the found resource to its final value. ssize_t block = res.resolveReference(&value, bag->stringBlock, NULL); +#if THROW_ON_BAD_ID + if (block == BAD_INDEX) { + jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!"); + return array; + } +#endif if (value.dataType == Res_value::TYPE_STRING) { const ResStringPool* pool = res.getTableStringBlock(block); const char* str8 = pool->string8At(value.data, &strLen); @@ -1520,6 +1576,12 @@ static jintArray android_content_AssetManager_getArrayIntResource(JNIEnv* env, j // Take care of resolving the found resource to its final value. ssize_t block = res.resolveReference(&value, bag->stringBlock, NULL); +#if THROW_ON_BAD_ID + if (block == BAD_INDEX) { + jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!"); + return array; + } +#endif if (value.dataType >= Res_value::TYPE_FIRST_INT && value.dataType <= Res_value::TYPE_LAST_INT) { int intVal = value.data; diff --git a/core/res/res/drawable-hdpi/progressbar_indeterminate1.png b/core/res/res/drawable-hdpi/progressbar_indeterminate1.png Binary files differindex ea88e32..197b34d 100644..100755 --- a/core/res/res/drawable-hdpi/progressbar_indeterminate1.png +++ b/core/res/res/drawable-hdpi/progressbar_indeterminate1.png diff --git a/core/res/res/drawable-hdpi/progressbar_indeterminate2.png b/core/res/res/drawable-hdpi/progressbar_indeterminate2.png Binary files differindex 436c48c..c6cf008 100644..100755 --- a/core/res/res/drawable-hdpi/progressbar_indeterminate2.png +++ b/core/res/res/drawable-hdpi/progressbar_indeterminate2.png diff --git a/core/res/res/drawable-hdpi/progressbar_indeterminate3.png b/core/res/res/drawable-hdpi/progressbar_indeterminate3.png Binary files differindex ea88e32..bf129e0 100644..100755 --- a/core/res/res/drawable-hdpi/progressbar_indeterminate3.png +++ b/core/res/res/drawable-hdpi/progressbar_indeterminate3.png diff --git a/core/res/res/drawable-hdpi/usb_android.png b/core/res/res/drawable-hdpi/usb_android.png Binary files differindex f6f899a..8b5b1a9 100644 --- a/core/res/res/drawable-hdpi/usb_android.png +++ b/core/res/res/drawable-hdpi/usb_android.png diff --git a/core/res/res/drawable-hdpi/usb_android_connected.png b/core/res/res/drawable-hdpi/usb_android_connected.png Binary files differindex 583ca00..442f2b3 100644 --- a/core/res/res/drawable-hdpi/usb_android_connected.png +++ b/core/res/res/drawable-hdpi/usb_android_connected.png diff --git a/core/res/res/drawable-mdpi/progressbar_indeterminate1.png b/core/res/res/drawable-mdpi/progressbar_indeterminate1.png Binary files differindex 5eddb30..71780ef 100644 --- a/core/res/res/drawable-mdpi/progressbar_indeterminate1.png +++ b/core/res/res/drawable-mdpi/progressbar_indeterminate1.png diff --git a/core/res/res/drawable-mdpi/progressbar_indeterminate2.png b/core/res/res/drawable-mdpi/progressbar_indeterminate2.png Binary files differindex 4ca3a63..236988b 100644 --- a/core/res/res/drawable-mdpi/progressbar_indeterminate2.png +++ b/core/res/res/drawable-mdpi/progressbar_indeterminate2.png diff --git a/core/res/res/drawable-mdpi/progressbar_indeterminate3.png b/core/res/res/drawable-mdpi/progressbar_indeterminate3.png Binary files differindex da8e601..1570235 100644 --- a/core/res/res/drawable-mdpi/progressbar_indeterminate3.png +++ b/core/res/res/drawable-mdpi/progressbar_indeterminate3.png diff --git a/core/res/res/drawable-mdpi/usb_android.png b/core/res/res/drawable-mdpi/usb_android.png Binary files differindex df1afbb..492b6e1 100644 --- a/core/res/res/drawable-mdpi/usb_android.png +++ b/core/res/res/drawable-mdpi/usb_android.png diff --git a/core/res/res/drawable-mdpi/usb_android_connected.png b/core/res/res/drawable-mdpi/usb_android_connected.png Binary files differindex fca77a7..3dd2950 100644 --- a/core/res/res/drawable-mdpi/usb_android_connected.png +++ b/core/res/res/drawable-mdpi/usb_android_connected.png diff --git a/core/res/res/layout/select_dialog.xml b/core/res/res/layout/select_dialog.xml index c665f7a..6e4e5e1 100644 --- a/core/res/res/layout/select_dialog.xml +++ b/core/res/res/layout/select_dialog.xml @@ -31,4 +31,5 @@ android:layout_marginTop="5px" android:cacheColorHint="@null" android:divider="@android:drawable/divider_horizontal_bright" - android:scrollbars="vertical" /> + android:scrollbars="vertical" + android:overscrollMode="ifContentScrolls" /> diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml index 0c8bafc..72fd0ad 100644 --- a/core/res/res/values-zh-rTW/strings.xml +++ b/core/res/res/values-zh-rTW/strings.xml @@ -185,18 +185,12 @@ <string name="permdesc_setDebugApp" msgid="5584310661711990702">"允許應用程式為其他程式開啟偵錯功能。請注意:惡意程式可利用此功能終止其他應用程式。"</string> <string name="permlab_changeConfiguration" msgid="8214475779521218295">"變更介面設定"</string> <string name="permdesc_changeConfiguration" msgid="3465121501528064399">"允許應用程式變更目前設定,例如:地區設定或字型大小。"</string> - <!-- no translation found for permlab_enableCarMode (5684504058192921098) --> - <skip /> - <!-- no translation found for permdesc_enableCarMode (5673461159384850628) --> - <skip /> - <!-- no translation found for permlab_killBackgroundProcesses (8373714752793061963) --> - <skip /> - <!-- no translation found for permdesc_killBackgroundProcesses (2908829602869383753) --> - <skip /> - <!-- no translation found for permlab_forceStopPackages (1447830113260156236) --> - <skip /> - <!-- no translation found for permdesc_forceStopPackages (7263036616161367402) --> - <skip /> + <string name="permlab_enableCarMode" msgid="5684504058192921098">"啟用行車模式"</string> + <string name="permdesc_enableCarMode" msgid="5673461159384850628">"允許應用程式啟用行車模式。"</string> + <string name="permlab_killBackgroundProcesses" msgid="8373714752793061963">"關閉背景程序"</string> + <string name="permdesc_killBackgroundProcesses" msgid="2908829602869383753">"允許應用程式關閉其他應用程式背景程序 (即使記憶體足夠)。"</string> + <string name="permlab_forceStopPackages" msgid="1447830113260156236">"強制停止應用程式"</string> + <string name="permdesc_forceStopPackages" msgid="7263036616161367402">"允許應用程式強制停止其他應用程式。"</string> <string name="permlab_forceBack" msgid="1804196839880393631">"強制關閉應用程式"</string> <string name="permdesc_forceBack" msgid="6534109744159919013">"允許應用程式強制關閉在前端運作的活動並返回。一般應用程式不需要此功能。"</string> <string name="permlab_dump" msgid="1681799862438954752">"接收系統內部狀態"</string> @@ -237,10 +231,8 @@ <string name="permdesc_bindInputMethod" msgid="3734838321027317228">"允許擁有人連結至輸入法的最頂層介面。一般應用程式不需使用此選項。"</string> <string name="permlab_bindWallpaper" msgid="8716400279937856462">"連結至桌布"</string> <string name="permdesc_bindWallpaper" msgid="5287754520361915347">"允許擁有人連結至桌布的最頂層介面,一般應用程式不需使用此選項。"</string> - <!-- no translation found for permlab_bindDeviceAdmin (8704986163711455010) --> - <skip /> - <!-- no translation found for permdesc_bindDeviceAdmin (8714424333082216979) --> - <skip /> + <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"與裝置管理員互動"</string> + <string name="permdesc_bindDeviceAdmin" msgid="8714424333082216979">"允許應用程式將調用請求 (intent) 傳送至裝置管理員;一般應用程式不需使用此選項。"</string> <string name="permlab_setOrientation" msgid="3365947717163866844">"變更螢幕顯示方向"</string> <string name="permdesc_setOrientation" msgid="6335814461615851863">"允許應用程式隨時變更螢幕顯示方向。一般應用程式不需要此功能。"</string> <string name="permlab_signalPersistentProcesses" msgid="4255467255488653854">"傳送 Linux 訊號到應用程式"</string> @@ -324,26 +316,16 @@ <string name="permdesc_mount_unmount_filesystems" msgid="6253263792535859767">"允許應用程式掛載/卸載抽取式儲存設備的檔案系統。"</string> <string name="permlab_mount_format_filesystems" msgid="5523285143576718981">"將外接式儲存裝置格式化"</string> <string name="permdesc_mount_format_filesystems" msgid="574060044906047386">"允許應用程式將可移除式儲存裝置格式化。"</string> - <!-- no translation found for permlab_asec_access (1070364079249834666) --> - <skip /> - <!-- no translation found for permdesc_asec_access (7691616292170590244) --> - <skip /> - <!-- no translation found for permlab_asec_create (7312078032326928899) --> - <skip /> - <!-- no translation found for permdesc_asec_create (7041802322759014035) --> - <skip /> - <!-- no translation found for permlab_asec_destroy (7787322878955261006) --> - <skip /> - <!-- no translation found for permdesc_asec_destroy (5740754114967893169) --> - <skip /> - <!-- no translation found for permlab_asec_mount_unmount (7517449694667828592) --> - <skip /> - <!-- no translation found for permdesc_asec_mount_unmount (5438078121718738625) --> - <skip /> - <!-- no translation found for permlab_asec_rename (5685344390439934495) --> - <skip /> - <!-- no translation found for permdesc_asec_rename (1387881770708872470) --> - <skip /> + <string name="permlab_asec_access" msgid="1070364079249834666">"取得安全儲存空間的資訊"</string> + <string name="permdesc_asec_access" msgid="7691616292170590244">"允許應用程式取得安全儲存空間的資訊。"</string> + <string name="permlab_asec_create" msgid="7312078032326928899">"建立安全儲存空間"</string> + <string name="permdesc_asec_create" msgid="7041802322759014035">"允許應用程式建立安全儲存空間。"</string> + <string name="permlab_asec_destroy" msgid="7787322878955261006">"銷毀安全儲存空間"</string> + <string name="permdesc_asec_destroy" msgid="5740754114967893169">"允許應用程式銷毀安全儲存空間。"</string> + <string name="permlab_asec_mount_unmount" msgid="7517449694667828592">"掛載/卸載安全儲存空間"</string> + <string name="permdesc_asec_mount_unmount" msgid="5438078121718738625">"允許應用程式掛載/卸載安全儲存空間。"</string> + <string name="permlab_asec_rename" msgid="5685344390439934495">"重新命名安全儲存空間"</string> + <string name="permdesc_asec_rename" msgid="1387881770708872470">"允許應用程式重新命名安全儲存空間。"</string> <string name="permlab_vibrate" msgid="7768356019980849603">"控制震動"</string> <string name="permdesc_vibrate" msgid="2886677177257789187">"允許應用程式控制震動。"</string> <string name="permlab_flashlight" msgid="2155920810121984215">"控制閃光燈"</string> @@ -378,10 +360,8 @@ <string name="permdesc_setWallpaperHints" msgid="6019479164008079626">"允許應用程式設定系統桌布大小提示。"</string> <string name="permlab_masterClear" msgid="2315750423139697397">"將系統還原至出廠預設值"</string> <string name="permdesc_masterClear" msgid="5033465107545174514">"允許應用程式將手機完全重設至出廠設定,清除所有資料、設定與已安裝程式。"</string> - <!-- no translation found for permlab_setTime (2021614829591775646) --> - <skip /> - <!-- no translation found for permdesc_setTime (667294309287080045) --> - <skip /> + <string name="permlab_setTime" msgid="2021614829591775646">"設定時間"</string> + <string name="permdesc_setTime" msgid="667294309287080045">"允許應用程式變更手機時鐘時間。"</string> <string name="permlab_setTimeZone" msgid="2945079801013077340">"設定時區"</string> <string name="permdesc_setTimeZone" msgid="1902540227418179364">"允許應用程式變更時區。"</string> <string name="permlab_accountManagerService" msgid="4829262349691386986">"作為 AccountManagerService"</string> @@ -401,12 +381,9 @@ <string name="permlab_writeApnSettings" msgid="7823599210086622545">"輸入存取點名稱設定"</string> <string name="permdesc_writeApnSettings" msgid="7443433457842966680">"允許應用程式修改 APN 設定,例如:Proxy 及 APN 的連接埠。"</string> <string name="permlab_changeNetworkState" msgid="958884291454327309">"變更網路連線"</string> - <!-- no translation found for permdesc_changeNetworkState (4199958910396387075) --> - <skip /> - <!-- no translation found for permlab_changeTetherState (5952584964373017960) --> - <skip /> - <!-- no translation found for permdesc_changeTetherState (8905815579146349568) --> - <skip /> + <string name="permdesc_changeNetworkState" msgid="4199958910396387075">"允許應用程式變更網路連線狀態。"</string> + <string name="permlab_changeTetherState" msgid="5952584964373017960">"變更數據連線"</string> + <string name="permdesc_changeTetherState" msgid="8905815579146349568">"允許應用程式變更數據網路連線狀態。"</string> <string name="permlab_changeBackgroundDataSetting" msgid="1400666012671648741">"變更背景資料使用設定"</string> <string name="permdesc_changeBackgroundDataSetting" msgid="1001482853266638864">"允許應用程式變更背景資料使用設定。"</string> <string name="permlab_accessWifiState" msgid="8100926650211034400">"檢視 Wi-Fi 狀態"</string> @@ -437,30 +414,18 @@ <string name="permdesc_writeDictionary" msgid="2241256206524082880">"允許應用程式將新字詞寫入使用者的字典。"</string> <string name="permlab_sdcardWrite" msgid="8079403759001777291">"修改/刪除 SD 卡的內容"</string> <string name="permdesc_sdcardWrite" msgid="6643963204976471878">"允許應用程式寫入 SD 卡。"</string> - <!-- no translation found for permlab_cache_filesystem (5656487264819669824) --> - <skip /> - <!-- no translation found for permdesc_cache_filesystem (1624734528435659906) --> - <skip /> - <!-- no translation found for policylab_limitPassword (4307861496302850201) --> - <skip /> - <!-- no translation found for policydesc_limitPassword (1719877245692318299) --> - <skip /> - <!-- no translation found for policylab_watchLogin (7374780712664285321) --> - <skip /> - <!-- no translation found for policydesc_watchLogin (1961251179624843483) --> - <skip /> - <!-- no translation found for policylab_resetPassword (9084772090797485420) --> - <skip /> - <!-- no translation found for policydesc_resetPassword (3332167600331799991) --> - <skip /> - <!-- no translation found for policylab_forceLock (5760466025247634488) --> - <skip /> - <!-- no translation found for policydesc_forceLock (2819868664946089740) --> - <skip /> - <!-- no translation found for policylab_wipeData (3910545446758639713) --> - <skip /> - <!-- no translation found for policydesc_wipeData (2314060933796396205) --> - <skip /> + <string name="permlab_cache_filesystem" msgid="5656487264819669824">"存取快取檔案系統"</string> + <string name="permdesc_cache_filesystem" msgid="1624734528435659906">"允許應用程式讀取及寫入快取檔案系統。"</string> + <string name="policylab_limitPassword" msgid="4307861496302850201">"限制密碼設定規則"</string> + <string name="policydesc_limitPassword" msgid="1719877245692318299">"限制允許使用的密碼類型。"</string> + <string name="policylab_watchLogin" msgid="7374780712664285321">"查看登入嘗試記錄"</string> + <string name="policydesc_watchLogin" msgid="1961251179624843483">"監視者無法登入裝置執行部分動作。"</string> + <string name="policylab_resetPassword" msgid="9084772090797485420">"重設密碼"</string> + <string name="policydesc_resetPassword" msgid="3332167600331799991">"強制重新設定密碼。您必須取得以管理員提供的新密碼,才能登入。"</string> + <string name="policylab_forceLock" msgid="5760466025247634488">"強制鎖定"</string> + <string name="policydesc_forceLock" msgid="2819868664946089740">"裝置鎖定時可取得控制,但必須重新輸入密碼。"</string> + <string name="policylab_wipeData" msgid="3910545446758639713">"清除所有資料"</string> + <string name="policydesc_wipeData" msgid="2314060933796396205">"重設為原廠設定 (系統會刪除所有資料,且不會向您進行確認)。"</string> <string-array name="phoneTypes"> <item msgid="8901098336658710359">"住家電話"</item> <item msgid="869923650527136615">"行動電話"</item> @@ -557,8 +522,7 @@ <string name="contact_status_update_attribution" msgid="5112589886094402795">"透過 <xliff:g id="SOURCE">%1$s</xliff:g>"</string> <string name="contact_status_update_attribution_with_date" msgid="5945386376369979909">"<xliff:g id="DATE">%1$s</xliff:g>透過「<xliff:g id="SOURCE">%2$s</xliff:g>」"</string> <string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"輸入 PIN 碼"</string> - <!-- no translation found for keyguard_password_enter_password_code (9138158344813213754) --> - <skip /> + <string name="keyguard_password_enter_password_code" msgid="9138158344813213754">"輸入密碼即可解鎖"</string> <string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"PIN 碼錯誤!"</string> <string name="keyguard_label_text" msgid="861796461028298424">"如要解鎖,請按 Menu 鍵,然後按 0。"</string> <string name="emergency_call_dialog_number_for_display" msgid="696192103195090970">"緊急電話號碼"</string> @@ -579,7 +543,7 @@ <string name="lockscreen_missing_sim_message_short" msgid="7381499217732227295">"沒有 SIM 卡。"</string> <string name="lockscreen_missing_sim_message" msgid="2186920585695169078">"手機未插入 SIM 卡。"</string> <string name="lockscreen_missing_sim_instructions" msgid="8874620818937719067">"請插入 SIM 卡。"</string> - <string name="emergency_calls_only" msgid="6733978304386365407">"只能撥打緊急電話"</string> + <string name="emergency_calls_only" msgid="6733978304386365407">"僅可撥打緊急電話"</string> <string name="lockscreen_network_locked_message" msgid="143389224986028501">"網路已鎖定"</string> <string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"SIM 的 PUK 已鎖定。"</string> <string name="lockscreen_sim_puk_locked_instructions" msgid="635967534992394321">"請參閱《使用者指南》或聯絡客戶服務中心。"</string> @@ -600,12 +564,9 @@ <string name="lockscreen_unlock_label" msgid="737440483220667054">"解除封鎖"</string> <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"開啟音效"</string> <string name="lockscreen_sound_off_label" msgid="996822825154319026">"關閉音效"</string> - <!-- no translation found for password_keyboard_label_symbol_key (992280756256536042) --> - <skip /> - <!-- no translation found for password_keyboard_label_alpha_key (8001096175167485649) --> - <skip /> - <!-- no translation found for password_keyboard_label_alt_key (1284820942620288678) --> - <skip /> + <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string> + <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string> + <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string> <string name="hour_ampm" msgid="4329881288269772723">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string> <string name="hour_cap_ampm" msgid="1829009197680861107">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string> <string name="status_bar_clear_all_button" msgid="7774721344716731603">"清除"</string> @@ -631,10 +592,8 @@ <string name="permdesc_readHistoryBookmarks" msgid="4981489815467617191">"允許應用程式讀取瀏覽器曾經造訪過的所有網址,以及瀏覽器的所有書籤。"</string> <string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"寫入瀏覽器的記錄與書籤"</string> <string name="permdesc_writeHistoryBookmarks" msgid="945571990357114950">"允許應用程式修改儲存在電話上的瀏覽記錄或書籤。請注意:惡意應用程式可能會使用此選項來清除或修改您瀏覽器的資料。"</string> - <!-- no translation found for permlab_writeGeolocationPermissions (4715212655598275532) --> - <skip /> - <!-- no translation found for permdesc_writeGeolocationPermissions (4011908282980861679) --> - <skip /> + <string name="permlab_writeGeolocationPermissions" msgid="4715212655598275532">"修改瀏覽器地理資訊的權限"</string> + <string name="permdesc_writeGeolocationPermissions" msgid="4011908282980861679">"允許應用程式修改瀏覽器的地理位置權限,惡意應用程式可能會透過此方式允許將您的位置資訊任意傳送給某些網站。"</string> <string name="save_password_message" msgid="767344687139195790">"是否記憶此密碼?"</string> <string name="save_password_notnow" msgid="6389675316706699758">"現在不要"</string> <string name="save_password_remember" msgid="6491879678996749466">"記住"</string> @@ -733,11 +692,6 @@ <string name="weeks" msgid="6509623834583944518">"週"</string> <string name="year" msgid="4001118221013892076">"年"</string> <string name="years" msgid="6881577717993213522">"年"</string> - <string name="every_weekday" msgid="8777593878457748503">"每天 (週一至週五)"</string> - <string name="daily" msgid="5738949095624133403">"每天"</string> - <string name="weekly" msgid="983428358394268344">"每週<xliff:g id="DAY">%s</xliff:g>"</string> - <string name="monthly" msgid="2667202947170988834">"每月"</string> - <string name="yearly" msgid="1519577999407493836">"每年"</string> <string name="VideoView_error_title" msgid="3359437293118172396">"無法播放影片"</string> <string name="VideoView_error_text_invalid_progressive_playback" msgid="897920883624437033">"很抱歉,影片格式無效,裝置無法進行串流處理。"</string> <string name="VideoView_error_text_unknown" msgid="710301040038083944">"很抱歉,此影片無法播放。"</string> @@ -820,26 +774,19 @@ <string name="no_permissions" msgid="7283357728219338112">"無須許可"</string> <string name="perms_hide" msgid="7283915391320676226"><b>" 隱藏"</b></string> <string name="perms_show_all" msgid="2671791163933091180"><b>"顯示全部"</b></string> - <!-- no translation found for usb_storage_activity_title (2399289999608900443) --> - <skip /> + <string name="usb_storage_activity_title" msgid="2399289999608900443">"USB 大量儲存裝置"</string> <string name="usb_storage_title" msgid="5901459041398751495">"USB 已連接"</string> - <!-- no translation found for usb_storage_message (4796759646167247178) --> - <skip /> - <!-- no translation found for usb_storage_button_mount (1052259930369508235) --> - <skip /> + <string name="usb_storage_message" msgid="4796759646167247178">"已透過 USB 連接手機與電腦。如要從電腦或 Android 系統的 SD 卡複製檔案,請選取下方按鈕。"</string> + <string name="usb_storage_button_mount" msgid="1052259930369508235">"開啟 USB 儲存裝置"</string> <string name="usb_storage_error_message" msgid="2534784751603345363">"把 SD 卡當成 USB 儲存裝置時發生問題。"</string> <string name="usb_storage_notification_title" msgid="8175892554757216525">"USB 已連接"</string> <string name="usb_storage_notification_message" msgid="7380082404288219341">"選取此項將檔案複製到電腦,或從電腦複製。"</string> <string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"關閉 USB 儲存裝置"</string> <string name="usb_storage_stop_notification_message" msgid="2591813490269841539">"選取此處關閉 USB 儲存裝置。"</string> - <!-- no translation found for usb_storage_stop_title (660129851708775853) --> - <skip /> - <!-- no translation found for usb_storage_stop_message (3613713396426604104) --> - <skip /> - <!-- no translation found for usb_storage_stop_button_mount (7060218034900696029) --> - <skip /> - <!-- no translation found for usb_storage_stop_error_message (143881914840412108) --> - <skip /> + <string name="usb_storage_stop_title" msgid="660129851708775853">"USB 儲存空間使用中"</string> + <string name="usb_storage_stop_message" msgid="3613713396426604104">"關閉 USB 儲存裝置前,請務必先將 Android 系統的 SD 卡從電腦上卸下 (退出)。"</string> + <string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"關閉 USB 儲存裝置"</string> + <string name="usb_storage_stop_error_message" msgid="143881914840412108">"關閉 USB 儲存裝置時發生問題。請檢查您是否已卸載 USB Host,然後再試一次。"</string> <!-- no translation found for dlg_confirm_kill_storage_users_title (203356557714612214) --> <skip /> <!-- no translation found for dlg_confirm_kill_storage_users_text (3902998926994232358) --> @@ -872,10 +819,8 @@ <string name="activity_list_empty" msgid="4168820609403385789">"找不到符合的活動"</string> <string name="permlab_pkgUsageStats" msgid="8787352074326748892">"更新元件使用統計資料"</string> <string name="permdesc_pkgUsageStats" msgid="891553695716752835">"允許修改收集到的元件使用統計資料。一般應用程式不會使用此功能。"</string> - <!-- no translation found for permlab_copyProtectedData (1660908117394854464) --> - <skip /> - <!-- no translation found for permdesc_copyProtectedData (537780957633976401) --> - <skip /> + <string name="permlab_copyProtectedData" msgid="1660908117394854464">"允許觸發預設容器服務,以便複製內容 (不建議一般應用程式使用)。"</string> + <string name="permdesc_copyProtectedData" msgid="537780957633976401">"允許觸發預設容器服務,以便複製內容 (不建議一般應用程式使用)。"</string> <string name="tutorial_double_tap_to_zoom_message_short" msgid="1311810005957319690">"點兩下以進行縮放控制"</string> <string name="gadget_host_error_inflating" msgid="2613287218853846830">"擴大小工具時發生錯誤"</string> <string name="ime_action_go" msgid="8320845651737369027">"開始"</string> @@ -888,12 +833,9 @@ <string name="create_contact_using" msgid="4947405226788104538">"建立手機號碼為 <xliff:g id="NUMBER">%s</xliff:g>"\n"的聯絡人"</string> <string name="accessibility_compound_button_selected" msgid="5612776946036285686">"已勾選"</string> <string name="accessibility_compound_button_unselected" msgid="8864512895673924091">"未勾選"</string> - <!-- no translation found for grant_credentials_permission_message_header (6824538733852821001) --> - <skip /> - <!-- no translation found for grant_credentials_permission_message_footer (3125211343379376561) --> - <skip /> - <!-- no translation found for grant_permissions_header_text (2722567482180797717) --> - <skip /> + <string name="grant_credentials_permission_message_header" msgid="6824538733852821001">"下列一或多個應用程式要求現在及將來的帳戶存取權限。"</string> + <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"您確定要允許這個要求嗎?"</string> + <string name="grant_permissions_header_text" msgid="2722567482180797717">"存取要求"</string> <string name="allow" msgid="7225948811296386551">"允許"</string> <string name="deny" msgid="2081879885755434506">"拒絕"</string> <string name="permission_request_notification_title" msgid="5390555465778213840">"已要求權限"</string> @@ -907,44 +849,27 @@ <string name="l2tp_vpn_description" msgid="3750692169378923304">"第二層通道通訊協定"</string> <string name="l2tp_ipsec_psk_vpn_description" msgid="3945043564008303239">"採用預先共用金鑰的 L2TP/IPSec VPN"</string> <string name="l2tp_ipsec_crt_vpn_description" msgid="5382714073103653577">"採用憑證的 L2TP/IPSec VPN"</string> - <!-- no translation found for upload_file (2897957172366730416) --> - <skip /> - <!-- no translation found for reset (2448168080964209908) --> - <skip /> - <!-- no translation found for submit (1602335572089911941) --> - <skip /> - <!-- no translation found for description_star (2654319874908576133) --> - <skip /> - <!-- no translation found for tether_title (6970447107301643248) --> - <skip /> - <!-- no translation found for tether_message (554549994538298101) --> - <skip /> - <!-- no translation found for tether_button (7409514810151603641) --> - <skip /> - <!-- no translation found for tether_button_cancel (6744369928952219677) --> - <skip /> - <!-- no translation found for tether_error_message (6672110337349077628) --> - <skip /> - <!-- no translation found for tether_available_notification_title (367754042700082080) --> - <skip /> - <!-- no translation found for tether_available_notification_message (8439443306503453793) --> - <skip /> - <!-- no translation found for tether_stop_notification_title (1902246071807668101) --> - <skip /> - <!-- no translation found for tether_stop_notification_message (6920086906891516128) --> - <skip /> - <!-- no translation found for tether_stop_title (3118332507220912235) --> - <skip /> - <!-- no translation found for tether_stop_message (7741840433788363174) --> - <skip /> - <!-- no translation found for tether_stop_button (8061941592702063029) --> - <skip /> - <!-- no translation found for tether_stop_button_cancel (3694669546501300230) --> - <skip /> - <!-- no translation found for tether_stop_error_message (4244697367270211648) --> - <skip /> + <string name="upload_file" msgid="2897957172366730416">"選擇檔案"</string> + <string name="reset" msgid="2448168080964209908">"重設"</string> + <string name="submit" msgid="1602335572089911941">"提交"</string> + <string name="description_star" msgid="2654319874908576133">"我的最愛"</string> + <string name="tether_title" msgid="6970447107301643248">"USB 數據連線運作中"</string> + <string name="tether_message" msgid="554549994538298101">"如要與電腦分享手機的資料連線,請選取 [數據連線]。"</string> + <string name="tether_button" msgid="7409514810151603641">"數據連線"</string> + <string name="tether_button_cancel" msgid="6744369928952219677">"取消"</string> + <!-- no translation found for tether_error_message (950843122853838817) --> + <skip /> + <string name="tether_available_notification_title" msgid="367754042700082080">"USB 數據連線運作中"</string> + <string name="tether_available_notification_message" msgid="8439443306503453793">"選取此選項可讓您的電腦與手機進行數據連線。"</string> + <string name="tether_stop_notification_title" msgid="1902246071807668101">"中斷數據連線"</string> + <string name="tether_stop_notification_message" msgid="6920086906891516128">"選取即可中斷與電腦的數據連線。"</string> + <string name="tether_stop_title" msgid="3118332507220912235">"中斷數據連線"</string> + <string name="tether_stop_message" msgid="7741840433788363174">"您已與電腦分享手機的行動資料連線,如要中斷 USB 數據連線,請選取 [中斷連線]。"</string> + <string name="tether_stop_button" msgid="8061941592702063029">"中斷連線"</string> + <string name="tether_stop_button_cancel" msgid="3694669546501300230">"取消"</string> + <string name="tether_stop_error_message" msgid="4244697367270211648">"關閉數據連線時發生問題,請再試一次。"</string> <!-- no translation found for car_mode_disable_notification_title (3164768212003864316) --> <skip /> - <!-- no translation found for car_mode_disable_notification_message (3262812780382240778) --> + <!-- no translation found for car_mode_disable_notification_message (668663626721675614) --> <skip /> </resources> diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index d34599f..8308801 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -131,9 +131,17 @@ <!-- Displayed to tell the user that emergency service is blocked by access control. --> <string name="RestrictedOnEmergency">Emergency service is blocked.</string> <!-- Displayed to tell the user that normal service is blocked by access control. --> - <string name="RestrictedOnNormal">Voice/SMS service is blocked.</string> - <!-- Displayed to tell the user that all voice service is blocked by access control. --> - <string name="RestrictedOnAll">All voice/SMS services are blocked.</string> + <string name="RestrictedOnNormal">Voice service is blocked.</string> + <!-- Displayed to tell the user that all emergency and normal voice services are blocked by access control. --> + <string name="RestrictedOnAllVoice">All Voice services are blocked.</string> + <!-- Displayed to tell the user that sms service is blocked by access control. --> + <string name="RestrictedOnSms">SMS service is blocked.</string> + <!-- Displayed to tell the user that voice/data service is blocked by access control. --> + <string name="RestrictedOnVoiceData">Voice/Data services are blocked.</string> + <!-- Displayed to tell the user that voice and sms service are blocked by access control. --> + <string name="RestrictedOnVoiceSms">Voice/SMS services are blocked.</string> + <!-- Displayed to tell the user that all service is blocked by access control. --> + <string name="RestrictedOnAll">All Voice/Data/SMS services are blocked.</string> <!-- Mappings between TS 27.007 +CFCC/+CLCK "service classes" and human-readable strings--> <skip /> <!-- Example: Service was enabled for: Voice, Data --> diff --git a/core/tests/coretests/src/android/text/StaticLayoutBidiTest.java b/core/tests/coretests/src/android/text/StaticLayoutBidiTest.java index da6036a..8e7e63e 100644 --- a/core/tests/coretests/src/android/text/StaticLayoutBidiTest.java +++ b/core/tests/coretests/src/android/text/StaticLayoutBidiTest.java @@ -39,42 +39,42 @@ public class StaticLayoutBidiTest extends TestCase { public static final String GIMEL = "\u05d2"; public static final String DALET = "\u05d3"; - @SmallTest + //@SmallTest public void testAllLtr() { expectBidi(REQ_DL, "a test", "000000", L); } - @SmallTest + //@SmallTest public void testLtrRtl() { expectBidi(REQ_DL, "abc " + ALEF + BET + GIMEL, "0000111", L); } - @SmallTest + //@SmallTest public void testAllRtl() { expectBidi(REQ_DL, ALEF + SP + ALEF + BET + GIMEL + DALET, "111111", R); } - @SmallTest + //@SmallTest public void testRtlLtr() { expectBidi(REQ_DL, ALEF + BET + GIMEL + " abc", "1111000", R); } - @SmallTest + //@SmallTest public void testRAllLtr() { expectBidi(REQ_R, "a test", "000000", R); } - @SmallTest + //@SmallTest public void testRLtrRtl() { expectBidi(REQ_R, "abc " + ALEF + BET + GIMEL, "0001111", R); } - @SmallTest + //@SmallTest public void testLAllRtl() { expectBidi(REQ_L, ALEF + SP + ALEF + BET + GIMEL + DALET, "111111", L); } - @SmallTest + //@SmallTest public void testLRtlLtr() { expectBidi(REQ_L, ALEF + BET + GIMEL + " abc", "1110000", L); } @@ -104,7 +104,7 @@ public class StaticLayoutBidiTest extends TestCase { assertEquals("levels", expectedLevels, resultLevels); } - @SmallTest + //@SmallTest public void testNativeBidi() { // native bidi returns levels, not simply directions expectNativeBidi(REQ_DL, ALEF + BET + GIMEL + " abc", "1111222", R); diff --git a/include/camera/CameraParameters.h b/include/camera/CameraParameters.h index 752afc2..6c6d0bc 100644 --- a/include/camera/CameraParameters.h +++ b/include/camera/CameraParameters.h @@ -139,6 +139,9 @@ public: // stored in JPEG EXIF header. // Example value: "1251192757". Write only. static const char KEY_GPS_TIMESTAMP[]; + // GPS Processing Method + // Example value: "GPS" or "NETWORK". Write only. + static const char KEY_GPS_PROCESSING_METHOD[]; // Current white balance setting. // Example value: "auto" or WHITE_BALANCE_XXX constants. Read/write. static const char KEY_WHITE_BALANCE[]; diff --git a/libs/camera/CameraParameters.cpp b/libs/camera/CameraParameters.cpp index cf4cbfa..65785c7 100644 --- a/libs/camera/CameraParameters.cpp +++ b/libs/camera/CameraParameters.cpp @@ -44,6 +44,7 @@ const char CameraParameters::KEY_GPS_LATITUDE[] = "gps-latitude"; const char CameraParameters::KEY_GPS_LONGITUDE[] = "gps-longitude"; const char CameraParameters::KEY_GPS_ALTITUDE[] = "gps-altitude"; const char CameraParameters::KEY_GPS_TIMESTAMP[] = "gps-timestamp"; +const char CameraParameters::KEY_GPS_PROCESSING_METHOD[] = "gps-processing-method"; const char CameraParameters::KEY_WHITE_BALANCE[] = "whitebalance"; const char CameraParameters::KEY_SUPPORTED_WHITE_BALANCE[] = "whitebalance-values"; const char CameraParameters::KEY_EFFECT[] = "effect"; diff --git a/libs/ui/EventHub.cpp b/libs/ui/EventHub.cpp index 57192a5..34cd9d1 100644 --- a/libs/ui/EventHub.cpp +++ b/libs/ui/EventHub.cpp @@ -608,7 +608,7 @@ int EventHub::open_device(const char *deviceName) // consider up through the function keys; we don't want to include // ones after that (play cd etc) so we don't mistakenly consider a // controller to be a keyboard. - uint8_t key_bitmask[(KEY_PLAYCD+1)/8]; + uint8_t key_bitmask[(KEY_MAX+1)/8]; memset(key_bitmask, 0, sizeof(key_bitmask)); LOGV("Getting keys..."); if (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(key_bitmask)), key_bitmask) >= 0) { diff --git a/libs/utils/ResourceTypes.cpp b/libs/utils/ResourceTypes.cpp index 6da11b5..38d8412 100644 --- a/libs/utils/ResourceTypes.cpp +++ b/libs/utils/ResourceTypes.cpp @@ -1850,7 +1850,7 @@ bool ResTable::getResourceName(uint32_t resID, resource_name* outName) const if (Res_GETPACKAGE(resID)+1 == 0) { LOGW("No package identifier when getting name for resource number 0x%08x", resID); } else { - LOGV("Resources don't contain package for resource number 0x%08x", resID); + LOGW("No known package when getting name for resource number 0x%08x", resID); } return false; } @@ -1898,9 +1898,9 @@ ssize_t ResTable::getResource(uint32_t resID, Res_value* outValue, bool mayBeBag if (p < 0) { if (Res_GETPACKAGE(resID)+1 == 0) { - LOGW("No package identifier when getting name for resource number 0x%08x", resID); + LOGW("No package identifier when getting value for resource number 0x%08x", resID); } else { - LOGV("Resources don't contain package for resource number 0x%08x", resID); + LOGW("No known package when getting value for resource number 0x%08x", resID); } return BAD_INDEX; } @@ -1921,7 +1921,7 @@ ssize_t ResTable::getResource(uint32_t resID, Res_value* outValue, bool mayBeBag const PackageGroup* const grp = mPackageGroups[p]; if (grp == NULL) { LOGW("Bad identifier when getting value for resource number 0x%08x", resID); - return false; + return BAD_INDEX; } size_t ip = grp->packages.size(); while (ip > 0) { @@ -2003,7 +2003,7 @@ ssize_t ResTable::getResource(uint32_t resID, Res_value* outValue, bool mayBeBag return bestPackage->header->index; } - return BAD_INDEX; + return BAD_VALUE; } ssize_t ResTable::resolveReference(Res_value* value, ssize_t blockIndex, @@ -2018,6 +2018,9 @@ ssize_t ResTable::resolveReference(Res_value* value, ssize_t blockIndex, uint32_t newFlags = 0; const ssize_t newIndex = getResource(value->data, value, true, &newFlags, outConfig); + if (newIndex == BAD_INDEX) { + return BAD_INDEX; + } TABLE_THEME(LOGI("Resolving reference %p: newIndex=%d, type=0x%x, data=%p\n", (void*)lastRef, (int)newIndex, (int)value->dataType, (void*)value->data)); //printf("Getting reference 0x%08x: newIndex=%d\n", value->data, newIndex); diff --git a/media/java/android/media/ThumbnailUtils.java b/media/java/android/media/ThumbnailUtils.java index 30d95e3..23f850a 100644 --- a/media/java/android/media/ThumbnailUtils.java +++ b/media/java/android/media/ThumbnailUtils.java @@ -52,20 +52,19 @@ public class ThumbnailUtils { /* Options used internally. */ private static final int OPTIONS_NONE = 0x0; - private static final int OPTIONS_DO_NOT_USE_NATIVE = 0x1; - private static final int OPTIONS_SCALE_UP = 0x2; + private static final int OPTIONS_SCALE_UP = 0x1; /** * Constant used to indicate we should recycle the input in * {@link #extractThumbnail(Bitmap, int, int, int)} unless the output is the input. */ - public static final int OPTIONS_RECYCLE_INPUT = 0x4; + public static final int OPTIONS_RECYCLE_INPUT = 0x2; /** - * Constant used to indicate the dimension of normal thumbnail in + * Constant used to indicate the dimension of mini thumbnail in * {@link #extractThumbnail(Bitmap, int, int, int)}. */ - public static final int TARGET_SIZE_NORMAL_THUMBNAIL = 320; + public static final int TARGET_SIZE_MINI_THUMBNAIL = 320; /** * Constant used to indicate the dimension of micro thumbnail in @@ -95,7 +94,7 @@ public class ThumbnailUtils { long origId, int kind, boolean saveMini) { boolean wantMini = (kind == Images.Thumbnails.MINI_KIND || saveMini); int targetSize = wantMini ? - TARGET_SIZE_NORMAL_THUMBNAIL : TARGET_SIZE_MICRO_THUMBNAIL; + TARGET_SIZE_MINI_THUMBNAIL : TARGET_SIZE_MICRO_THUMBNAIL; int maxPixels = wantMini ? MAX_NUM_PIXELS_THUMBNAIL : MAX_NUM_PIXELS_MICRO_THUMBNAIL; SizedThumbnailBitmap sizedThumbnailBitmap = new SizedThumbnailBitmap(); @@ -264,40 +263,16 @@ public class ThumbnailUtils { } /** - * Returns Options that set the native alloc flag for Bitmap decode. - */ - private static BitmapFactory.Options createNativeAllocOptions() { - BitmapFactory.Options options = new BitmapFactory.Options(); - options.inNativeAlloc = true; - return options; - } - - /** * Make a bitmap from a given Uri, minimal side length, and maximum number of pixels. + * The image data will be read from specified ContentResolver. */ private static Bitmap makeBitmap(int minSideLength, int maxNumOfPixels, Uri uri, ContentResolver cr) { - return makeBitmap(minSideLength, maxNumOfPixels, uri, cr, - OPTIONS_DO_NOT_USE_NATIVE); - } - - /** - * Make a bitmap from a given Uri, minimal side length, and maximum number of pixels. - * The image data will be read from specified ContentResolver and clients are allowed to specify - * whether they want the Bitmap be created in native memory. - */ - private static Bitmap makeBitmap(int minSideLength, int maxNumOfPixels, - Uri uri, ContentResolver cr, int opt) { - boolean useNative = (opt & OPTIONS_DO_NOT_USE_NATIVE) != 0; ParcelFileDescriptor input = null; try { input = cr.openFileDescriptor(uri, "r"); - BitmapFactory.Options options = null; - if (useNative) { - options = createNativeAllocOptions(); - } return makeBitmap(minSideLength, maxNumOfPixels, uri, cr, input, - options); + null); } catch (IOException ex) { Log.e(TAG, "", ex); return null; diff --git a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java index c826973..02e1f07 100644 --- a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java +++ b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java @@ -93,11 +93,16 @@ public class DefaultContainerService extends IntentService { * PackageHelper.RECOMMEND_FAILED_INVALID_APK for parse errors. */ public int getRecommendedInstallLocation(final Uri fileUri) { - if (!fileUri.getScheme().equals("file")) { + if (fileUri == null) { + Log.i(TAG, "Invalid package uri " + fileUri); + return PackageHelper.RECOMMEND_FAILED_INVALID_APK; + } + String scheme = fileUri.getScheme(); + if (scheme != null && !scheme.equals("file")) { Log.w(TAG, "Falling back to installing on internal storage only"); return PackageHelper.RECOMMEND_INSTALL_INTERNAL; } - final String archiveFilePath = fileUri.getPath(); + String archiveFilePath = fileUri.getPath(); PackageParser packageParser = new PackageParser(archiveFilePath); File sourceFile = new File(archiveFilePath); DisplayMetrics metrics = new DisplayMetrics(); @@ -166,41 +171,62 @@ public class DefaultContainerService extends IntentService { String codePath = packageURI.getPath(); File codeFile = new File(codePath); String newCachePath = null; + final int CREATE_FAILED = 1; + final int COPY_FAILED = 2; + final int FINALIZE_FAILED = 3; + final int PASS = 4; + int errCode = CREATE_FAILED; // Create new container if ((newCachePath = PackageHelper.createSdDir(codeFile, - newCid, key, Process.myUid())) == null) { - Log.e(TAG, "Failed creating container " + newCid); - return null; + newCid, key, Process.myUid())) != null) { + if (localLOGV) Log.i(TAG, "Created container for " + newCid + + " at path : " + newCachePath); + File resFile = new File(newCachePath, resFileName); + errCode = COPY_FAILED; + // Copy file from codePath + if (FileUtils.copyFile(new File(codePath), resFile)) { + if (localLOGV) Log.i(TAG, "Copied " + codePath + " to " + resFile); + errCode = FINALIZE_FAILED; + if (PackageHelper.finalizeSdDir(newCid)) { + if (localLOGV) Log.i(TAG, "Finalized container " + newCid); + errCode = PASS; + } + } } - if (localLOGV) Log.i(TAG, "Created container for " + newCid - + " at path : " + newCachePath); - File resFile = new File(newCachePath, resFileName); - // Copy file from codePath - if (!FileUtils.copyFile(new File(codePath), resFile)) { - Log.e(TAG, "Failed to copy " + codePath + " to " + resFile); - // Clean up created container - PackageHelper.destroySdDir(newCid); - return null; + // Print error based on errCode + String errMsg = ""; + switch (errCode) { + case CREATE_FAILED: + errMsg = "CREATE_FAILED"; + break; + case COPY_FAILED: + errMsg = "COPY_FAILED"; + if (localLOGV) Log.i(TAG, "Destroying " + newCid + + " at path " + newCachePath + " after " + errMsg); + PackageHelper.destroySdDir(newCid); + break; + case FINALIZE_FAILED: + errMsg = "FINALIZE_FAILED"; + if (localLOGV) Log.i(TAG, "Destroying " + newCid + + " at path " + newCachePath + " after " + errMsg); + PackageHelper.destroySdDir(newCid); + break; + default: + errMsg = "PASS"; + if (PackageHelper.isContainerMounted(newCid)) { + if (localLOGV) Log.i(TAG, "Unmounting " + newCid + + " at path " + newCachePath + " after " + errMsg); + // Force a gc to avoid being killed. + Runtime.getRuntime().gc(); + PackageHelper.unMountSdDir(newCid); + } else { + if (localLOGV) Log.i(TAG, "Container " + newCid + " not mounted"); + } + break; } - if (localLOGV) Log.i(TAG, "Copied " + codePath + " to " + resFile); - // Finalize container now - if (!PackageHelper.finalizeSdDir(newCid)) { - Log.e(TAG, "Failed to finalize " + newCid + " at cache path " + newCachePath); - // Clean up created container - PackageHelper.destroySdDir(newCid); + if (errCode != PASS) { return null; } - if (localLOGV) Log.i(TAG, "Finalized container " + newCid); - // Force a gc to avoid being killed. - Runtime.getRuntime().gc(); - // Unmount container - if (PackageHelper.isContainerMounted(newCid)) { - if (localLOGV) Log.i(TAG, "Unmounting " + newCid + - " at path " + newCachePath); - PackageHelper.unMountSdDir(newCid); - } else { - if (localLOGV) Log.i(TAG, "Container " + newCid + " not mounted"); - } return newCachePath; } @@ -231,7 +257,8 @@ public class DefaultContainerService extends IntentService { } private boolean copyFile(Uri pPackageURI, FileOutputStream outStream) { - if (pPackageURI.getScheme().equals("file")) { + String scheme = pPackageURI.getScheme(); + if (scheme == null || scheme.equals("file")) { final File srcPackageFile = new File(pPackageURI.getPath()); // We copy the source package file to a temp file and then rename it to the // destination file in order to eliminate a window where the package directory @@ -240,7 +267,7 @@ public class DefaultContainerService extends IntentService { Log.e(TAG, "Couldn't copy file: " + srcPackageFile); return false; } - } else if (pPackageURI.getScheme().equals("content")) { + } else if (scheme.equals("content")) { ParcelFileDescriptor fd = null; try { fd = getContentResolver().openFileDescriptor(pPackageURI, "r"); diff --git a/packages/TtsService/jni/android_tts_SynthProxy.cpp b/packages/TtsService/jni/android_tts_SynthProxy.cpp index 2f5cfa3..b7acd96 100644 --- a/packages/TtsService/jni/android_tts_SynthProxy.cpp +++ b/packages/TtsService/jni/android_tts_SynthProxy.cpp @@ -551,7 +551,7 @@ android_tts_SynthProxy_setSpeechRate(JNIEnv *env, jobject thiz, jint jniData, return result; } - int bufSize = 10; + int bufSize = 12; char buffer [bufSize]; sprintf(buffer, "%d", speechRate); @@ -581,7 +581,7 @@ android_tts_SynthProxy_setPitch(JNIEnv *env, jobject thiz, jint jniData, Mutex::Autolock l(engineMutex); - int bufSize = 10; + int bufSize = 12; char buffer [bufSize]; sprintf(buffer, "%d", pitch); diff --git a/services/java/com/android/server/AppWidgetService.java b/services/java/com/android/server/AppWidgetService.java index e5a5e03..5de68f9 100644 --- a/services/java/com/android/server/AppWidgetService.java +++ b/services/java/com/android/server/AppWidgetService.java @@ -29,6 +29,7 @@ import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.pm.PackageInfo; import android.content.pm.ResolveInfo; +import android.content.res.Resources; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; import android.net.Uri; @@ -709,7 +710,10 @@ class AppWidgetService extends IAppWidgetService.Stub info.provider = component; p.uid = activityInfo.applicationInfo.uid; - TypedArray sa = mContext.getResources().obtainAttributes(attrs, + Resources res = mPackageManager.getResourcesForApplication( + activityInfo.applicationInfo); + + TypedArray sa = res.obtainAttributes(attrs, com.android.internal.R.styleable.AppWidgetProviderInfo); // These dimensions has to be resolved in the application's context. diff --git a/services/java/com/android/server/InputDevice.java b/services/java/com/android/server/InputDevice.java index ed7eed0..07a74da 100644 --- a/services/java/com/android/server/InputDevice.java +++ b/services/java/com/android/server/InputDevice.java @@ -36,9 +36,9 @@ public class InputDevice { /** * Slop distance for jumpy pointer detection. - * This is in touchscreen coordinates, not pixels or dips. + * The vertical range of the screen divided by this is our epsilon value. */ - private static final int JUMPY_EPSILON = 30; + private static final int JUMPY_EPSILON_DIVISOR = 212; /** Number of jumpy points to drop for touchscreens that need it. */ private static final int JUMPY_TRANSITION_DROPS = 3; @@ -246,11 +246,17 @@ public class InputDevice { } void dropJumpyPoint(InputDevice dev) { + // We should always have absY, but let's be paranoid. + if (dev.absY == null) { + return; + } + final int jumpyEpsilon = dev.absY.range / JUMPY_EPSILON_DIVISOR; + final int nextNumPointers = mNextNumPointers; final int lastNumPointers = mLastNumPointers; final int[] nextData = mNextData; final int[] lastData = mLastData; - + if (nextNumPointers != mLastNumPointers) { if (DEBUG_HACKS) { Slog.d("InputDevice", "Different pointer count " + lastNumPointers + @@ -330,8 +336,8 @@ public class InputDevice { final int xOther = nextData[joff + MotionEvent.SAMPLE_X]; final int yOther = nextData[joff + MotionEvent.SAMPLE_Y]; - dropx = Math.abs(x - xOther) <= JUMPY_EPSILON; - dropy = Math.abs(y - yOther) <= JUMPY_EPSILON; + dropx = Math.abs(x - xOther) <= jumpyEpsilon; + dropy = Math.abs(y - yOther) <= jumpyEpsilon; } if (dropx) { diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java index 60813f1..e336a35 100644 --- a/services/java/com/android/server/InputMethodManagerService.java +++ b/services/java/com/android/server/InputMethodManagerService.java @@ -1526,13 +1526,15 @@ public class InputMethodManagerService extends IInputMethodManager.Stub mDialogBuilder.setSingleChoiceItems(mItems, checkedItem, new AlertDialog.OnClickListener() { public void onClick(DialogInterface dialog, int which) { - if (mIms == null) { - return; - } synchronized (mMethodMap) { + if (mIms == null || mIms.length <= which) { + return; + } InputMethodInfo im = mIms[which]; hideInputMethodMenu(); - setInputMethodLocked(im.getId()); + if (im != null) { + setInputMethodLocked(im.getId()); + } } } }); diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java index 53076de..aa9ced8 100644 --- a/services/java/com/android/server/NetworkManagementService.java +++ b/services/java/com/android/server/NetworkManagementService.java @@ -456,4 +456,23 @@ class NetworkManagementService extends INetworkManagementService.Stub { } throw new IllegalStateException("Got an empty response"); } + + public void startAccessPoint() + throws IllegalStateException { + mContext.enforceCallingOrSelfPermission( + android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); + mContext.enforceCallingOrSelfPermission( + android.Manifest.permission.CHANGE_WIFI_STATE, "NetworkManagementService"); + mConnector.doCommand(String.format("softap set")); + mConnector.doCommand(String.format("softap start")); + } + + public void stopAccessPoint() throws IllegalStateException { + mContext.enforceCallingOrSelfPermission( + android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); + mContext.enforceCallingOrSelfPermission( + android.Manifest.permission.CHANGE_WIFI_STATE, "NetworkManagementService"); + mConnector.doCommand("softap stop"); + } + } diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java index 1455973..7378333 100644 --- a/services/java/com/android/server/WifiService.java +++ b/services/java/com/android/server/WifiService.java @@ -22,6 +22,12 @@ import static android.net.wifi.WifiManager.WIFI_STATE_ENABLED; import static android.net.wifi.WifiManager.WIFI_STATE_ENABLING; import static android.net.wifi.WifiManager.WIFI_STATE_UNKNOWN; +import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLED; +import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLING; +import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLED; +import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLING; +import static android.net.wifi.WifiManager.WIFI_AP_STATE_FAILED; + import android.app.AlarmManager; import android.app.PendingIntent; import android.bluetooth.BluetoothA2dp; @@ -40,6 +46,8 @@ import android.net.wifi.WifiStateTracker; import android.net.wifi.ScanResult; import android.net.wifi.WifiConfiguration; import android.net.wifi.SupplicantState; +import android.net.ConnectivityManager; +import android.net.InterfaceConfiguration; import android.net.NetworkStateTracker; import android.net.DhcpInfo; import android.net.NetworkUtils; @@ -47,6 +55,7 @@ import android.os.Binder; import android.os.Handler; import android.os.HandlerThread; import android.os.IBinder; +import android.os.INetworkManagementService; import android.os.Looper; import android.os.Message; import android.os.PowerManager; @@ -67,6 +76,7 @@ import java.util.Set; import java.util.regex.Pattern; import java.io.FileDescriptor; import java.io.PrintWriter; +import java.net.UnknownHostException; import com.android.internal.app.IBatteryStats; import android.backup.IBackupManager; @@ -87,6 +97,7 @@ public class WifiService extends IWifiManager.Stub { private Context mContext; private int mWifiState; + private int mWifiApState; private AlarmManager mAlarmManager; private PendingIntent mIdleIntent; @@ -112,6 +123,10 @@ public class WifiService extends IWifiManager.Stub { private final IBatteryStats mBatteryStats; + private INetworkManagementService nwService; + ConnectivityManager mCm; + private String[] mWifiRegexs; + /** * See {@link Settings.Secure#WIFI_IDLE_MS}. This is the default value if a * Settings.Secure value is not present. This timeout value is chosen as @@ -145,6 +160,9 @@ public class WifiService extends IWifiManager.Stub { private static final int MESSAGE_START_WIFI = 3; private static final int MESSAGE_RELEASE_WAKELOCK = 4; private static final int MESSAGE_UPDATE_STATE = 5; + private static final int MESSAGE_START_ACCESS_POINT = 6; + private static final int MESSAGE_STOP_ACCESS_POINT = 7; + private final WifiHandler mWifiHandler; @@ -180,6 +198,9 @@ public class WifiService extends IWifiManager.Stub { mWifiStateTracker.enableRssiPolling(true); mBatteryStats = BatteryStatsService.getService(); + IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); + nwService = INetworkManagementService.Stub.asInterface(b); + mScanResultCache = new LinkedHashMap<String, ScanResult>( SCAN_RESULT_CACHE_SIZE, 0.75f, true) { /* @@ -196,7 +217,9 @@ public class WifiService extends IWifiManager.Stub { mWifiHandler = new WifiHandler(wifiThread.getLooper()); mWifiState = WIFI_STATE_DISABLED; + mWifiApState = WIFI_AP_STATE_DISABLED; boolean wifiEnabled = getPersistedWifiEnabled(); + boolean wifiAPEnabled = wifiEnabled ? false : getPersistedWifiApEnabled(); mAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE); Intent idleIntent = new Intent(ACTION_DEVICE_IDLE, null); @@ -232,7 +255,70 @@ public class WifiService extends IWifiManager.Stub { }, new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED)); + mContext.registerReceiver( + new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + + ArrayList<String> available = intent.getStringArrayListExtra( + ConnectivityManager.EXTRA_AVAILABLE_TETHER); + ArrayList<String> active = intent.getStringArrayListExtra( + ConnectivityManager.EXTRA_ACTIVE_TETHER); + updateTetherState(available, active); + + } + },new IntentFilter(ConnectivityManager.ACTION_TETHER_STATE_CHANGED)); + setWifiEnabledBlocking(wifiEnabled, false, Process.myUid()); + setWifiApEnabledBlocking(wifiAPEnabled, true, Process.myUid(), null); + } + + private void updateTetherState(ArrayList<String> available, ArrayList<String> tethered) { + + boolean wifiTethered = false; + boolean wifiAvailable = false; + + IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); + INetworkManagementService service = INetworkManagementService.Stub.asInterface(b); + + mCm = (ConnectivityManager)mContext.getSystemService(Context.CONNECTIVITY_SERVICE); + mWifiRegexs = mCm.getTetherableWifiRegexs(); + + for (String intf : available) { + for (String regex : mWifiRegexs) { + if (intf.matches(regex)) { + + InterfaceConfiguration ifcg = null; + try { + ifcg = service.getInterfaceConfig(intf); + if (ifcg != null) { + /* IP/netmask: 169.254.2.1/255.255.255.0 */ + ifcg.ipAddr = (169 << 24) + (254 << 16) + (2 << 8) + 1; + ifcg.netmask = (255 << 24) + (255 << 16) + (255 << 8) + 0; + ifcg.interfaceFlags = "up"; + + service.setInterfaceConfig(intf, ifcg); + } + } catch (Exception e) { + /** + * TODO: Add broadcast to indicate tether failed + */ + Slog.e(TAG, "Error configuring interface " + intf + ", :" + e); + return; + } + + /** + * TODO: Add broadcast to indicate tether failed + */ + if(mCm.tether(intf) == ConnectivityManager.TETHER_ERROR_NO_ERROR) { + Slog.d(TAG, "Tethered "+intf); + } else { + Slog.e(TAG, "Error tethering "+intf); + } + break; + } + } + } } private boolean getPersistedWifiEnabled() { @@ -337,12 +423,16 @@ public class WifiService extends IWifiManager.Stub { * Avoid doing a disable when the current Wifi state is UNKNOWN * TODO: Handle driver load fail and supplicant lost as seperate states */ - if (mWifiState == WIFI_STATE_UNKNOWN && !enable) { + if ((mWifiState == WIFI_STATE_UNKNOWN) && !enable) { return false; } setWifiEnabledState(enable ? WIFI_STATE_ENABLING : WIFI_STATE_DISABLING, uid); + if ((mWifiApState == WIFI_AP_STATE_ENABLED) && enable) { + setWifiApEnabledBlocking(false, true, Process.myUid(), null); + } + if (enable) { synchronized (mWifiStateTracker) { if (!WifiNative.loadDriver()) { @@ -490,6 +580,154 @@ public class WifiService extends IWifiManager.Stub { } } + private boolean getPersistedWifiApEnabled() { + final ContentResolver cr = mContext.getContentResolver(); + try { + return Settings.Secure.getInt(cr, Settings.Secure.WIFI_AP_ON) == 1; + } catch (Settings.SettingNotFoundException e) { + Settings.Secure.putInt(cr, Settings.Secure.WIFI_AP_ON, 0); + return false; + } + } + + private void persistWifiApEnabled(boolean enabled) { + final ContentResolver cr = mContext.getContentResolver(); + Settings.Secure.putInt(cr, Settings.Secure.WIFI_AP_ON, enabled ? 1 : 0); + } + + /** + * see {@link android.net.wifi.WifiManager#startAccessPoint(WifiConfiguration)} + * @param wifiConfig SSID, security and channel details as + * part of WifiConfiguration + * @return {@code true} if the start operation was + * started or is already in the queue. + */ + public boolean setWifiApEnabled(WifiConfiguration wifiConfig, boolean enabled) { + enforceChangePermission(); + if (mWifiHandler == null) return false; + + synchronized (mWifiHandler) { + + long ident = Binder.clearCallingIdentity(); + sWakeLock.acquire(); + Binder.restoreCallingIdentity(ident); + + mLastEnableUid = Binder.getCallingUid(); + + sendAccessPointMessage(enabled, wifiConfig, Binder.getCallingUid()); + } + + return true; + } + + /** + * Enables/disables Wi-Fi AP synchronously. The driver is loaded + * and soft access point configured as a single operation. + * @param enable {@code true} to turn Wi-Fi on, {@code false} to turn it off. + * @param persist {@code true} if the setting should be persisted. + * @param uid The UID of the process making the request. + * @param config The WifiConfiguration for AP + * @return {@code true} if the operation succeeds (or if the existing state + * is the same as the requested state) + */ + /** + * TODO: persist needs to go away in WifiService + * This will affect all persist related functions + * for Access Point + */ + private boolean setWifiApEnabledBlocking(boolean enable, + boolean persist, int uid, WifiConfiguration wifiConfig) { + final int eventualWifiApState = enable ? WIFI_AP_STATE_ENABLED : WIFI_AP_STATE_DISABLED; + + if (mWifiApState == eventualWifiApState) { + return true; + } + + setWifiApEnabledState(enable ? WIFI_AP_STATE_ENABLING : WIFI_AP_STATE_DISABLING, uid); + + if (enable && (mWifiState == WIFI_STATE_ENABLED)) { + setWifiEnabledBlocking(false, true, Process.myUid()); + } + + if (enable) { + synchronized (mWifiStateTracker) { + if (!WifiNative.loadDriver()) { + Slog.e(TAG, "Failed to load Wi-Fi driver for AP mode"); + setWifiApEnabledState(WIFI_AP_STATE_FAILED, uid); + return false; + } + } + + try { + nwService.startAccessPoint(); + } catch(Exception e) { + Slog.e(TAG, "Exception in startAccessPoint()"); + } + + } else { + + try { + nwService.stopAccessPoint(); + } catch(Exception e) { + Slog.e(TAG, "Exception in stopAccessPoint()"); + } + + synchronized (mWifiStateTracker) { + if (!WifiNative.unloadDriver()) { + Slog.e(TAG, "Failed to unload Wi-Fi driver for AP mode"); + setWifiApEnabledState(WIFI_AP_STATE_FAILED, uid); + return false; + } + } + } + + // Success! + if (persist) { + persistWifiApEnabled(enable); + } + setWifiApEnabledState(eventualWifiApState, uid); + return true; + } + + /** + * see {@link WifiManager#getWifiApState()} + * @return One of {@link WifiManager#WIFI_AP_STATE_DISABLED}, + * {@link WifiManager#WIFI_AP_STATE_DISABLING}, + * {@link WifiManager#WIFI_AP_STATE_ENABLED}, + * {@link WifiManager#WIFI_AP_STATE_ENABLING}, + * {@link WifiManager#WIFI_AP_STATE_FAILED} + */ + public int getWifiApEnabledState() { + enforceAccessPermission(); + return mWifiApState; + } + + private void setWifiApEnabledState(int wifiAPState, int uid) { + final int previousWifiApState = mWifiApState; + + long ident = Binder.clearCallingIdentity(); + try { + if (wifiAPState == WIFI_AP_STATE_ENABLED) { + mBatteryStats.noteWifiOn(uid); + } else if (wifiAPState == WIFI_AP_STATE_DISABLED) { + mBatteryStats.noteWifiOff(uid); + } + } catch (RemoteException e) { + } finally { + Binder.restoreCallingIdentity(ident); + } + + // Update state + mWifiApState = wifiAPState; + + // Broadcast + final Intent intent = new Intent(WifiManager.WIFI_AP_STATE_CHANGED_ACTION); + intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); + intent.putExtra(WifiManager.EXTRA_WIFI_AP_STATE, wifiAPState); + intent.putExtra(WifiManager.EXTRA_PREVIOUS_WIFI_AP_STATE, previousWifiApState); + mContext.sendStickyBroadcast(intent); + } + /** * see {@link android.net.wifi.WifiManager#getConfiguredNetworks()} * @return the list of configured networks @@ -1472,6 +1710,12 @@ public class WifiService extends IWifiManager.Stub { Message.obtain(mWifiHandler, MESSAGE_START_WIFI, scanOnlyMode ? 1 : 0, 0).sendToTarget(); } + private void sendAccessPointMessage(boolean enable, WifiConfiguration wifiConfig, int uid) { + Message.obtain(mWifiHandler, + (enable ? MESSAGE_START_ACCESS_POINT : MESSAGE_STOP_ACCESS_POINT), + 0, uid, wifiConfig).sendToTarget(); + } + private void updateWifiState() { // send a message so it's all serialized Message.obtain(mWifiHandler, MESSAGE_UPDATE_STATE, 0, 0).sendToTarget(); @@ -1606,6 +1850,21 @@ public class WifiService extends IWifiManager.Stub { } } break; + + case MESSAGE_START_ACCESS_POINT: + setWifiApEnabledBlocking(true, + msg.arg1 == 1, + msg.arg2, + (WifiConfiguration) msg.obj); + break; + + case MESSAGE_STOP_ACCESS_POINT: + setWifiApEnabledBlocking(false, + msg.arg1 == 1, + msg.arg2, + (WifiConfiguration) msg.obj); + sWakeLock.release(); + break; } } } diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java index 8781263..f5d3e8e 100644 --- a/services/java/com/android/server/WindowManagerService.java +++ b/services/java/com/android/server/WindowManagerService.java @@ -9516,6 +9516,9 @@ public class WindowManagerService extends IWindowManager.Stub if (mPolicy.doesForceHide(w, attrs)) { if (!wasAnimating && animating) { + if (DEBUG_VISIBILITY) Slog.v(TAG, + "Animation done that could impact force hide: " + + w); wallpaperForceHidingChanged = true; mFocusMayChange = true; } else if (w.isReadyForDisplay() && w.mAnimation == null) { @@ -9525,19 +9528,31 @@ public class WindowManagerService extends IWindowManager.Stub boolean changed; if (forceHiding) { changed = w.hideLw(false, false); + if (DEBUG_VISIBILITY && changed) Slog.v(TAG, + "Now policy hidden: " + w); } else { changed = w.showLw(false, false); - if (changed && wallpaperForceHidingChanged - && w.isReadyForDisplay()) { - // Assume we will need to animate. If - // we don't (because the wallpaper will - // stay with the lock screen), then we will - // clean up later. - Animation a = mPolicy.createForceHideEnterAnimation(); - if (a != null) { - w.setAnimation(a); + if (DEBUG_VISIBILITY && changed) Slog.v(TAG, + "Now policy shown: " + w); + if (changed) { + if (wallpaperForceHidingChanged + && w.isReadyForDisplay()) { + // Assume we will need to animate. If + // we don't (because the wallpaper will + // stay with the lock screen), then we will + // clean up later. + Animation a = mPolicy.createForceHideEnterAnimation(); + if (a != null) { + w.setAnimation(a); + } + } + if (mCurrentFocus == null || + mCurrentFocus.mLayer < w.mLayer) { + // We are showing on to of the current + // focus, so re-evaluate focus to make + // sure it is correct. + mFocusMayChange = true; } - mFocusMayChange = true; } } if (changed && (attrs.flags diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index 2c82d9c..a263b23 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -1863,6 +1863,8 @@ public final class ActivityManagerService extends ActivityManagerNative implemen + " pid=" + (app != null ? app.pid : -1)); if (app != null && app.pid > 0) { if (!knownToBeDead || app.thread == null) { + // We already have the app running, or are waiting for it to + // come up (we have a pid but not yet its thread), so keep it. return app; } else { // An application record is attached to a previous process, diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java index 6797f78..32e7176 100644 --- a/telephony/java/android/telephony/PhoneNumberUtils.java +++ b/telephony/java/android/telephony/PhoneNumberUtils.java @@ -1311,7 +1311,12 @@ public class PhoneNumberUtils number = extractNetworkPortionAlt(number); // retrieve the list of emergency numbers - String numbers = SystemProperties.get("ro.ril.ecclist"); + // check read-write ecclist property first + String numbers = SystemProperties.get("ril.ecclist"); + if (TextUtils.isEmpty(numbers)) { + // then read-only ecclist property since old RIL only uses this + numbers = SystemProperties.get("ro.ril.ecclist"); + } if (!TextUtils.isEmpty(numbers)) { // searches through the comma-separated list for a match, diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java index 6352b41..e4fcf6c 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java @@ -1630,7 +1630,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker { notificationId = PS_NOTIFICATION; break; case CS_ENABLED: - details = context.getText(com.android.internal.R.string.RestrictedOnAll);; + details = context.getText(com.android.internal.R.string.RestrictedOnAllVoice);; break; case CS_NORMAL_ENABLED: details = context.getText(com.android.internal.R.string.RestrictedOnNormal);; diff --git a/telephony/tests/telephonytests/src/android/telephony/PhoneNumberUtilsTest.java b/telephony/tests/telephonytests/src/android/telephony/PhoneNumberUtilsTest.java index aa2981b..02590d3 100644 --- a/telephony/tests/telephonytests/src/android/telephony/PhoneNumberUtilsTest.java +++ b/telephony/tests/telephonytests/src/android/telephony/PhoneNumberUtilsTest.java @@ -401,7 +401,7 @@ public class PhoneNumberUtilsTest extends TestCase { PhoneNumberUtils.convertKeypadLettersToDigits("(800) ABC-DEFG")); } - @SmallTest + // To run this test, the device has to be registered with network public void testCheckAndProcessPlusCode() { assertEquals("0118475797000", PhoneNumberUtils.cdmaCheckAndProcessPlusCode("+8475797000")); diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/MccTableTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/MccTableTest.java index 1ea1285..2d6977c 100644 --- a/telephony/tests/telephonytests/src/com/android/internal/telephony/MccTableTest.java +++ b/telephony/tests/telephonytests/src/com/android/internal/telephony/MccTableTest.java @@ -33,7 +33,7 @@ public class MccTableTest extends AndroidTestCase { assertEquals(MccTable.defaultTimeZoneForMcc(655), "Africa/Johannesburg"); assertEquals(MccTable.defaultTimeZoneForMcc(440), "Asia/Tokyo"); assertEquals(MccTable.defaultTimeZoneForMcc(441), "Asia/Tokyo"); - assertEquals(MccTable.defaultTimeZoneForMcc(525), "Singapore"); + assertEquals(MccTable.defaultTimeZoneForMcc(525), "Asia/Singapore"); assertEquals(MccTable.defaultTimeZoneForMcc(240), null); // tz not defined, hence default assertEquals(MccTable.defaultTimeZoneForMcc(0), null); // mcc not defined, hence default assertEquals(MccTable.defaultTimeZoneForMcc(2000), null); // mcc not defined, hence default diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl index f3738e3..d833e33 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -29,7 +29,7 @@ import android.net.DhcpInfo; interface IWifiManager { List<WifiConfiguration> getConfiguredNetworks(); - + int addOrUpdateNetwork(in WifiConfiguration config); boolean removeNetwork(int netId); @@ -47,7 +47,7 @@ interface IWifiManager boolean disconnect(); boolean reconnect(); - + boolean reassociate(); WifiInfo getConnectionInfo(); @@ -61,7 +61,7 @@ interface IWifiManager boolean setNumAllowedChannels(int numChannels, boolean persist); int[] getValidChannelCounts(); - + boolean saveConfiguration(); DhcpInfo getDhcpInfo(); @@ -77,5 +77,9 @@ interface IWifiManager void acquireMulticastLock(IBinder binder, String tag); void releaseMulticastLock(); + + boolean setWifiApEnabled(in WifiConfiguration wifiConfig, boolean enable); + + int getWifiApEnabledState(); } diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 178f76e..9ef8ba1 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -123,7 +123,88 @@ public class WifiManager { * @see #getWifiState() */ public static final int WIFI_STATE_UNKNOWN = 4; - + + /** + * Broadcast intent action indicating that Wi-Fi AP has been enabled, disabled, + * enabling, disabling, or failed. + * + * @hide + */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String WIFI_AP_STATE_CHANGED_ACTION = + "android.net.wifi.WIFI_AP_STATE_CHANGED"; + + /** + * The lookup key for an int that indicates whether Wi-Fi AP is enabled, + * disabled, enabling, disabling, or failed. Retrieve it with + * {@link android.content.Intent#getIntExtra(String,int)}. + * + * @see #WIFI_AP_STATE_DISABLED + * @see #WIFI_AP_STATE_DISABLING + * @see #WIFI_AP_STATE_ENABLED + * @see #WIFI_AP_STATE_ENABLING + * @see #WIFI_AP_STATE_FAILED + * + * @hide + */ + public static final String EXTRA_WIFI_AP_STATE = "wifi_state"; + /** + * The previous Wi-Fi state. + * + * @see #EXTRA_WIFI_AP_STATE + * + * @hide + */ + public static final String EXTRA_PREVIOUS_WIFI_AP_STATE = "previous_wifi_state"; + /** + * Wi-Fi AP is currently being disabled. The state will change to + * {@link #WIFI_AP_STATE_DISABLED} if it finishes successfully. + * + * @see #WIFI_AP_STATE_CHANGED_ACTION + * @see #getWifiApState() + * + * @hide + */ + public static final int WIFI_AP_STATE_DISABLING = 0; + /** + * Wi-Fi AP is disabled. + * + * @see #WIFI_AP_STATE_CHANGED_ACTION + * @see #getWifiState() + * + * @hide + */ + public static final int WIFI_AP_STATE_DISABLED = 1; + /** + * Wi-Fi AP is currently being enabled. The state will change to + * {@link #WIFI_AP_STATE_ENABLED} if it finishes successfully. + * + * @see #WIFI_AP_STATE_CHANGED_ACTION + * @see #getWifiApState() + * + * @hide + */ + public static final int WIFI_AP_STATE_ENABLING = 2; + /** + * Wi-Fi AP is enabled. + * + * @see #WIFI_AP_STATE_CHANGED_ACTION + * @see #getWifiApState() + * + * @hide + */ + public static final int WIFI_AP_STATE_ENABLED = 3; + /** + * Wi-Fi AP is in a failed state. This state will occur when an error occurs during + * enabling or disabling + * + * @see #WIFI_AP_STATE_CHANGED_ACTION + * @see #getWifiApState() + * + * @hide + */ + public static final int WIFI_AP_STATE_FAILED = 4; + /** * Broadcast intent action indicating that a connection to the supplicant has * been established (and it is now possible @@ -681,6 +762,54 @@ public class WifiManager { } /** + * Start AccessPoint mode with the specified + * configuration. If the radio is already running in + * AP mode, update the new configuration + * Note that starting in access point mode disables station + * mode operation + * @param wifiConfig SSID, security and channel details as + * part of WifiConfiguration + * @return {@code true} if the operation succeeds, {@code false} otherwise + * + * @hide Dont open up yet + */ + public boolean setWifiApEnabled(WifiConfiguration wifiConfig, boolean enabled) { + try { + return mService.setWifiApEnabled(wifiConfig, enabled); + } catch (RemoteException e) { + return false; + } + } + + /** + * Gets the Wi-Fi enabled state. + * @return One of {@link #WIFI_AP_STATE_DISABLED}, + * {@link #WIFI_AP_STATE_DISABLING}, {@link #WIFI_AP_STATE_ENABLED}, + * {@link #WIFI_AP_STATE_ENABLING}, {@link #WIFI_AP_STATE_FAILED} + * @see #isWifiApEnabled() + * + * @hide Dont open yet + */ + public int getWifiApState() { + try { + return mService.getWifiApEnabledState(); + } catch (RemoteException e) { + return WIFI_AP_STATE_FAILED; + } + } + + /** + * Return whether Wi-Fi AP is enabled or disabled. + * @return {@code true} if Wi-Fi AP is enabled + * @see #getWifiApState() + * + * @hide Dont open yet + */ + public boolean isWifiApEnabled() { + return getWifiApState() == WIFI_AP_STATE_ENABLED; + } + + /** * Allows an application to keep the Wi-Fi radio awake. * Normally the Wi-Fi radio may turn off when the user has not used the device in a while. * Acquiring a WifiLock will keep the radio on until the lock is released. Multiple |
