summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/java/android/annotation/PrivateApi.java31
-rw-r--r--core/java/android/app/ActivityThread.java42
-rw-r--r--core/java/android/app/AppOpsManager.java4
-rw-r--r--core/java/android/app/ContextImpl.java206
-rw-r--r--core/java/android/app/LoadedApk.java51
-rw-r--r--core/java/android/app/Notification.java2
-rw-r--r--core/java/android/app/PendingIntent.java40
-rw-r--r--core/java/android/app/WallpaperManager.java66
-rw-r--r--core/java/android/app/backup/IBackupManager.aidl4
-rw-r--r--core/java/android/bluetooth/BluetoothAdapter.java285
-rw-r--r--core/java/android/bluetooth/BluetoothAdvScanData.java152
-rw-r--r--core/java/android/bluetooth/BluetoothGatt.java72
-rw-r--r--core/java/android/bluetooth/BluetoothGattServer.java2
-rw-r--r--core/java/android/bluetooth/BluetoothGattService.java23
-rw-r--r--core/java/android/bluetooth/BluetoothUuid.java16
-rw-r--r--core/java/android/bluetooth/IBluetoothGatt.aidl15
-rw-r--r--core/java/android/bluetooth/IBluetoothGattCallback.aidl2
-rw-r--r--core/java/android/bluetooth/package.html16
-rw-r--r--core/java/android/content/ClipDescription.java2
-rw-r--r--core/java/android/content/ContentProvider.java6
-rw-r--r--core/java/android/content/ContentResolver.java12
-rw-r--r--core/java/android/content/Intent.java10
-rw-r--r--core/java/android/hardware/Camera.java30
-rw-r--r--core/java/android/hardware/SensorManager.java4
-rw-r--r--core/java/android/hardware/display/DisplayManager.java21
-rw-r--r--core/java/android/hardware/display/DisplayManagerGlobal.java33
-rw-r--r--core/java/android/hardware/display/IDisplayManager.aidl23
-rw-r--r--core/java/android/net/ConnectivityManager.java7
-rw-r--r--core/java/android/net/IConnectivityManager.aidl4
-rw-r--r--core/java/android/net/MobileDataStateTracker.java11
-rw-r--r--core/java/android/net/VpnService.java7
-rw-r--r--core/java/android/os/AsyncTask.java2
-rw-r--r--core/java/android/os/Build.java2
-rw-r--r--core/java/android/os/INetworkManagementService.aidl2
-rw-r--r--core/java/android/os/Vibrator.java4
-rw-r--r--core/java/android/preference/PreferenceActivity.java7
-rw-r--r--core/java/android/print/PrinterCapabilitiesInfo.java6
-rw-r--r--core/java/android/provider/ContactsContract.java15
-rw-r--r--core/java/android/provider/DocumentsContract.java2
-rw-r--r--core/java/android/provider/Settings.java6
-rw-r--r--core/java/android/text/format/Time.java2
-rw-r--r--core/java/android/util/LongSparseArray.java2
-rw-r--r--core/java/android/util/LongSparseLongArray.java2
-rw-r--r--core/java/android/util/SparseArray.java2
-rw-r--r--core/java/android/util/SparseBooleanArray.java2
-rw-r--r--core/java/android/util/SparseIntArray.java2
-rw-r--r--core/java/android/util/SparseLongArray.java2
-rw-r--r--core/java/android/view/View.java2
-rw-r--r--core/java/android/view/ViewConfiguration.java39
-rw-r--r--core/java/android/view/ViewRootImpl.java77
-rw-r--r--core/java/android/view/VolumePanel.java1
-rw-r--r--core/java/android/view/WindowManager.java7
-rw-r--r--core/java/android/webkit/WebView.java9
-rw-r--r--core/java/android/webkit/WebViewFactoryProvider.java5
-rw-r--r--core/java/android/widget/AbsListView.java182
-rw-r--r--core/java/android/widget/CalendarView.java53
-rw-r--r--core/java/android/widget/FastScroller.java30
-rw-r--r--core/java/android/widget/ImageView.java2
-rw-r--r--core/java/android/widget/PopupWindow.java2
-rw-r--r--core/java/android/widget/ProgressBar.java5
-rw-r--r--core/java/android/widget/ShareActionProvider.java2
-rw-r--r--core/java/android/widget/SpellChecker.java6
-rw-r--r--core/java/android/widget/TextView.java4
-rw-r--r--core/java/com/android/internal/app/ProcessStats.java6
-rw-r--r--core/java/com/android/internal/content/PackageMonitor.java10
-rw-r--r--core/java/com/android/internal/os/ZygoteInit.java9
-rw-r--r--core/java/com/android/internal/view/IInputMethodManager.aidl2
-rw-r--r--core/java/com/android/internal/view/menu/ActionMenuPresenter.java36
-rw-r--r--core/java/com/android/internal/view/menu/ListMenuPresenter.java2
-rw-r--r--core/java/com/android/internal/view/menu/MenuBuilder.java14
-rw-r--r--core/jni/android/graphics/Bitmap.cpp24
-rw-r--r--core/jni/android/graphics/BitmapFactory.cpp103
-rw-r--r--core/jni/android/graphics/BitmapRegionDecoder.cpp9
-rw-r--r--core/jni/android/graphics/Canvas.cpp6
-rw-r--r--core/jni/android/graphics/Graphics.cpp44
-rw-r--r--core/jni/android/graphics/GraphicsJNI.h11
-rw-r--r--core/jni/android/graphics/Movie.cpp4
-rw-r--r--core/jni/android/graphics/NinePatchPeeker.cpp17
-rw-r--r--core/jni/android/graphics/Paint.cpp6
-rw-r--r--core/jni/android/graphics/Region.cpp2
-rw-r--r--core/jni/android/graphics/TextLayoutCache.cpp5
-rw-r--r--core/jni/android/graphics/Typeface.cpp64
-rw-r--r--core/jni/android/graphics/Utils.cpp15
-rw-r--r--core/jni/android/graphics/Utils.h24
-rw-r--r--core/jni/android/opengl/util.cpp10
-rw-r--r--core/jni/android_view_Surface.cpp6
-rw-r--r--core/jni/android_view_SurfaceControl.cpp110
-rw-r--r--core/jni/android_view_TextureView.cpp3
-rw-r--r--core/res/AndroidManifest.xml9
-rw-r--r--core/res/res/drawable-hdpi/ic_media_route_disabled_holo_dark.pngbin539 -> 543 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_media_route_disabled_holo_light.pngbin537 -> 561 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_media_route_off_holo_dark.pngbin578 -> 497 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_media_route_off_holo_light.pngbin566 -> 637 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_media_route_on_0_holo_dark.pngbin556 -> 543 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_media_route_on_0_holo_light.pngbin553 -> 581 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_media_route_on_1_holo_dark.pngbin571 -> 565 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_media_route_on_1_holo_light.pngbin564 -> 599 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_media_route_on_2_holo_dark.pngbin566 -> 568 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_media_route_on_2_holo_light.pngbin559 -> 622 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_media_route_on_holo_dark.pngbin580 -> 551 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_media_route_on_holo_light.pngbin576 -> 699 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_notification_cast_0.pngbin448 -> 471 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_notification_cast_1.pngbin457 -> 473 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_notification_cast_2.pngbin465 -> 472 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_notification_cast_on.pngbin414 -> 470 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_media_route_disabled_holo_dark.pngbin388 -> 353 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_media_route_disabled_holo_light.pngbin388 -> 380 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_media_route_off_holo_dark.pngbin401 -> 379 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_media_route_off_holo_light.pngbin398 -> 401 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_media_route_on_0_holo_dark.pngbin395 -> 373 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_media_route_on_0_holo_light.pngbin390 -> 398 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_media_route_on_1_holo_dark.pngbin401 -> 388 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_media_route_on_1_holo_light.pngbin395 -> 401 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_media_route_on_2_holo_dark.pngbin415 -> 383 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_media_route_on_2_holo_light.pngbin398 -> 399 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_media_route_on_holo_dark.pngbin403 -> 402 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_media_route_on_holo_light.pngbin398 -> 438 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_notification_cast_0.pngbin332 -> 329 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_notification_cast_1.pngbin329 -> 330 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_notification_cast_2.pngbin326 -> 351 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_notification_cast_on.pngbin305 -> 342 bytes
-rw-r--r--core/res/res/drawable-xhdpi/cab_background_top_holo_dark.9.pngbin174 -> 1125 bytes
-rw-r--r--core/res/res/drawable-xhdpi/cab_background_top_holo_light.9.pngbin161 -> 1121 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_media_route_disabled_holo_dark.pngbin716 -> 677 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_media_route_disabled_holo_light.pngbin704 -> 689 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_media_route_off_holo_dark.pngbin747 -> 684 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_media_route_off_holo_light.pngbin737 -> 787 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_media_route_on_0_holo_dark.pngbin730 -> 675 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_media_route_on_0_holo_light.pngbin714 -> 721 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_media_route_on_1_holo_dark.pngbin738 -> 698 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_media_route_on_1_holo_light.pngbin723 -> 719 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_media_route_on_2_holo_dark.pngbin731 -> 712 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_media_route_on_2_holo_light.pngbin726 -> 790 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_media_route_on_holo_dark.pngbin750 -> 686 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_media_route_on_holo_light.pngbin743 -> 857 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_notification_cast_0.pngbin557 -> 582 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_notification_cast_1.pngbin585 -> 607 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_notification_cast_2.pngbin589 -> 610 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_notification_cast_on.pngbin555 -> 596 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/cab_background_top_holo_dark.9.pngbin1155 -> 1162 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/cab_background_top_holo_light.9.pngbin1152 -> 1158 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/ic_media_route_disabled_holo_dark.pngbin1043 -> 1000 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/ic_media_route_disabled_holo_light.pngbin1054 -> 1033 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/ic_media_route_off_holo_dark.pngbin1115 -> 1067 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/ic_media_route_off_holo_light.pngbin1098 -> 1130 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/ic_media_route_on_0_holo_dark.pngbin1072 -> 1014 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/ic_media_route_on_0_holo_light.pngbin1068 -> 1062 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/ic_media_route_on_1_holo_dark.pngbin1110 -> 1043 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/ic_media_route_on_1_holo_light.pngbin1104 -> 1093 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/ic_media_route_on_2_holo_dark.pngbin1094 -> 1026 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/ic_media_route_on_2_holo_light.pngbin1090 -> 1110 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/ic_media_route_on_holo_dark.pngbin1108 -> 1148 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/ic_media_route_on_holo_light.pngbin1106 -> 1271 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/ic_notification_cast_0.pngbin812 -> 853 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/ic_notification_cast_1.pngbin847 -> 868 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/ic_notification_cast_2.pngbin827 -> 867 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/ic_notification_cast_on.pngbin768 -> 934 bytes
-rw-r--r--core/res/res/values-ja/bools.xml20
-rw-r--r--core/res/res/values/bools.xml1
-rw-r--r--core/res/res/values/config.xml12
-rw-r--r--core/res/res/values/strings.xml14
-rw-r--r--core/res/res/values/symbols.xml4
-rw-r--r--core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/NetworkState.java33
163 files changed, 1411 insertions, 909 deletions
diff --git a/core/java/android/annotation/PrivateApi.java b/core/java/android/annotation/PrivateApi.java
new file mode 100644
index 0000000..985eafe
--- /dev/null
+++ b/core/java/android/annotation/PrivateApi.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Indicates an API is exposed for use by bundled applications.
+ * <p>
+ * These APIs are not guaranteed to remain consistent release-to-release,
+ * and are not for use by apps linking against the SDK.
+ * @hide
+ */
+@Retention(RetentionPolicy.SOURCE)
+public @interface PrivateApi {
+}
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index b103e71..9a3478e 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -157,7 +157,7 @@ public final class ActivityThread {
private static final int LOG_ON_PAUSE_CALLED = 30021;
private static final int LOG_ON_RESUME_CALLED = 30022;
- static ContextImpl mSystemContext = null;
+ private ContextImpl mSystemContext;
static IPackageManager sPackageManager;
@@ -1700,7 +1700,7 @@ public final class ActivityThread {
? mBoundApplication.processName : null)
+ ")");
packageInfo =
- new LoadedApk(this, aInfo, compatInfo, this, baseLoader,
+ new LoadedApk(this, aInfo, compatInfo, baseLoader,
securityViolation, includeCode &&
(aInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0);
if (includeCode) {
@@ -1753,26 +1753,15 @@ public final class ActivityThread {
public ContextImpl getSystemContext() {
synchronized (this) {
if (mSystemContext == null) {
- ContextImpl context =
- ContextImpl.createSystemContext(this);
- LoadedApk info = new LoadedApk(this, "android", context, null,
- CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO);
- context.init(info, null, this);
- context.getResources().updateConfiguration(mResourcesManager.getConfiguration(),
- mResourcesManager.getDisplayMetricsLocked(Display.DEFAULT_DISPLAY));
- mSystemContext = context;
- //Slog.i(TAG, "Created system resources " + context.getResources()
- // + ": " + context.getResources().getConfiguration());
+ mSystemContext = ContextImpl.createSystemContext(this);
}
+ return mSystemContext;
}
- return mSystemContext;
}
public void installSystemApplicationInfo(ApplicationInfo info) {
synchronized (this) {
- ContextImpl context = getSystemContext();
- context.init(new LoadedApk(this, "android", context, info,
- CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO), null, this);
+ getSystemContext().installSystemApplicationInfo(info);
// give ourselves a default profiler
mProfiler = new Profiler();
@@ -2258,8 +2247,7 @@ public final class ActivityThread {
private Context createBaseContextForActivity(ActivityClientRecord r,
final Activity activity) {
- ContextImpl appContext = new ContextImpl();
- appContext.init(r.packageInfo, r.token, this);
+ ContextImpl appContext = ContextImpl.createActivityContext(this, r.packageInfo, r.token);
appContext.setOuterContext(activity);
// For debugging purposes, if the activity's package name contains the value of
@@ -2544,8 +2532,7 @@ public final class ActivityThread {
agent = (BackupAgent) cl.loadClass(classname).newInstance();
// set up the agent's context
- ContextImpl context = new ContextImpl();
- context.init(packageInfo, null, this);
+ ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
context.setOuterContext(agent);
agent.attach(context);
@@ -2617,11 +2604,10 @@ public final class ActivityThread {
try {
if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);
- ContextImpl context = new ContextImpl();
- context.init(packageInfo, null, this);
+ ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
+ context.setOuterContext(service);
Application app = packageInfo.makeApplication(false, mInstrumentation);
- context.setOuterContext(service);
service.attach(context, this, data.info.name, data.token, app,
ActivityManagerNative.getDefault());
service.onCreate();
@@ -4217,8 +4203,7 @@ public final class ActivityThread {
}
updateDefaultDensity();
- final ContextImpl appContext = new ContextImpl();
- appContext.init(data.info, null, this);
+ final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
if (!Process.isIsolated()) {
final File cacheDir = appContext.getCacheDir();
@@ -4334,8 +4319,7 @@ public final class ActivityThread {
instrApp.nativeLibraryDir = ii.nativeLibraryDir;
LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
appContext.getClassLoader(), false, true);
- ContextImpl instrContext = new ContextImpl();
- instrContext.init(pi, null, this);
+ ContextImpl instrContext = ContextImpl.createAppContext(this, pi);
try {
java.lang.ClassLoader cl = instrContext.getClassLoader();
@@ -4950,8 +4934,8 @@ public final class ActivityThread {
UserHandle.myUserId());
try {
mInstrumentation = new Instrumentation();
- ContextImpl context = new ContextImpl();
- context.init(getSystemContext().mPackageInfo, null, this);
+ ContextImpl context = ContextImpl.createAppContext(
+ this, getSystemContext().mPackageInfo);
Application app = Instrumentation.newApplication(Application.class, context);
mAllApplications.add(app);
mInitialApplication = app;
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index aece462..079cf7a 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -36,7 +36,7 @@ import android.os.RemoteException;
* API for interacting with "application operation" tracking.
*
* <p>This API is not generally intended for third party application developers; most
- * features are only available to system applicatins. Obtain an instance of it through
+ * features are only available to system applications. Obtain an instance of it through
* {@link Context#getSystemService(String) Context.getSystemService} with
* {@link Context#APP_OPS_SERVICE Context.APP_OPS_SERVICE}.</p>
*/
@@ -878,7 +878,7 @@ public class AppOpsManager {
}
/**
- * Like {@link #checkOp but instead of throwing a {@link SecurityException} it
+ * Like {@link #checkOp} but instead of throwing a {@link SecurityException} it
* returns {@link #MODE_ERRORED}.
*/
public int checkOpNoThrow(String op, int uid, String packageName) {
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 8d127c6..df50989 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -183,22 +183,31 @@ class ContextImpl extends Context {
*/
private static ArrayMap<String, ArrayMap<String, SharedPreferencesImpl>> sSharedPrefs;
- /*package*/ LoadedApk mPackageInfo;
- private String mBasePackageName;
- private String mOpPackageName;
- private Resources mResources;
- /*package*/ ActivityThread mMainThread;
+ final ActivityThread mMainThread;
+ final LoadedApk mPackageInfo;
+
+ private final IBinder mActivityToken;
+
+ private final UserHandle mUser;
+
+ private final ApplicationContentResolver mContentResolver;
+
+ private final String mBasePackageName;
+ private final String mOpPackageName;
+
+ private final ResourcesManager mResourcesManager;
+ private final Resources mResources;
+ private final Display mDisplay; // may be null if default display
+ private final DisplayAdjustments mDisplayAdjustments = new DisplayAdjustments();
+ private final Configuration mOverrideConfiguration;
+
+ private final boolean mRestricted;
+
private Context mOuterContext;
- private IBinder mActivityToken = null;
- private ApplicationContentResolver mContentResolver;
private int mThemeResource = 0;
private Resources.Theme mTheme = null;
private PackageManager mPackageManager;
- private Display mDisplay; // may be null if default display
private Context mReceiverRestrictedContext = null;
- private boolean mRestricted;
- private UserHandle mUser;
- private ResourcesManager mResourcesManager;
private final Object mSync = new Object();
@@ -220,8 +229,6 @@ class ContextImpl extends Context {
private static final String[] EMPTY_FILE_LIST = {};
- final private DisplayAdjustments mDisplayAdjustments = new DisplayAdjustments();
-
/**
* Override this class when the system service constructor needs a
* ContextImpl. Else, use StaticServiceFetcher below.
@@ -356,10 +363,11 @@ class ContextImpl extends Context {
ctx.mMainThread.getHandler());
}});
- registerService(CONNECTIVITY_SERVICE, new StaticServiceFetcher() {
- public Object createStaticService() {
+ registerService(CONNECTIVITY_SERVICE, new ServiceFetcher() {
+ public Object createService(ContextImpl ctx) {
IBinder b = ServiceManager.getService(CONNECTIVITY_SERVICE);
- return new ConnectivityManager(IConnectivityManager.Stub.asInterface(b));
+ return new ConnectivityManager(IConnectivityManager.Stub.asInterface(b),
+ ctx.getPackageName());
}});
registerService(COUNTRY_DETECTOR, new StaticServiceFetcher() {
@@ -1878,20 +1886,17 @@ class ContextImpl extends Context {
@Override
public Context createPackageContextAsUser(String packageName, int flags, UserHandle user)
throws NameNotFoundException {
+ final boolean restricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
if (packageName.equals("system") || packageName.equals("android")) {
- final ContextImpl context = new ContextImpl(mMainThread.getSystemContext());
- context.mRestricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
- context.init(mPackageInfo, null, mMainThread, mResources, mBasePackageName, user);
- return context;
+ return new ContextImpl(this, mMainThread, mPackageInfo, mActivityToken,
+ user, restricted, mDisplay, mOverrideConfiguration);
}
- LoadedApk pi =
- mMainThread.getPackageInfo(packageName, mResources.getCompatibilityInfo(), flags,
- user.getIdentifier());
+ LoadedApk pi = mMainThread.getPackageInfo(packageName, mResources.getCompatibilityInfo(),
+ flags, user.getIdentifier());
if (pi != null) {
- ContextImpl c = new ContextImpl();
- c.mRestricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
- c.init(pi, null, mMainThread, mResources, mBasePackageName, user);
+ ContextImpl c = new ContextImpl(this, mMainThread, pi, mActivityToken,
+ user, restricted, mDisplay, mOverrideConfiguration);
if (c.mResources != null) {
return c;
}
@@ -1899,7 +1904,7 @@ class ContextImpl extends Context {
// Should be a better exception.
throw new PackageManager.NameNotFoundException(
- "Application package " + packageName + " not found");
+ "Application package " + packageName + " not found");
}
@Override
@@ -1908,12 +1913,8 @@ class ContextImpl extends Context {
throw new IllegalArgumentException("overrideConfiguration must not be null");
}
- ContextImpl c = new ContextImpl();
- c.init(mPackageInfo, null, mMainThread);
- c.mResources = mResourcesManager.getTopLevelResources(mPackageInfo.getResDir(),
- mPackageInfo.getOverlayDirs(), getDisplayId(), overrideConfiguration,
- mResources.getCompatibilityInfo(), mActivityToken);
- return c;
+ return new ContextImpl(this, mMainThread, mPackageInfo, mActivityToken,
+ mUser, mRestricted, mDisplay, overrideConfiguration);
}
@Override
@@ -1922,15 +1923,8 @@ class ContextImpl extends Context {
throw new IllegalArgumentException("display must not be null");
}
- int displayId = display.getDisplayId();
-
- ContextImpl context = new ContextImpl();
- context.init(mPackageInfo, null, mMainThread);
- context.mDisplay = display;
- DisplayAdjustments daj = getDisplayAdjustments(displayId);
- context.mResources = mResourcesManager.getTopLevelResources(mPackageInfo.getResDir(),
- mPackageInfo.getOverlayDirs(), displayId, null, daj.getCompatibilityInfo(), null);
- return context;
+ return new ContextImpl(this, mMainThread, mPackageInfo, mActivityToken,
+ mUser, mRestricted, display, mOverrideConfiguration);
}
private int getDisplayId() {
@@ -1972,43 +1966,76 @@ class ContextImpl extends Context {
}
static ContextImpl createSystemContext(ActivityThread mainThread) {
- final ContextImpl context = new ContextImpl();
- context.init(Resources.getSystem(), mainThread, Process.myUserHandle());
+ LoadedApk packageInfo = new LoadedApk(mainThread);
+ ContextImpl context = new ContextImpl(null, mainThread,
+ packageInfo, null, null, false, null, null);
+ context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(),
+ context.mResourcesManager.getDisplayMetricsLocked(Display.DEFAULT_DISPLAY));
return context;
}
- ContextImpl() {
- mOuterContext = this;
+ static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) {
+ if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
+ return new ContextImpl(null, mainThread,
+ packageInfo, null, null, false, null, null);
}
- /**
- * Create a new ApplicationContext from an existing one. The new one
- * works and operates the same as the one it is copying.
- *
- * @param context Existing application context.
- */
- public ContextImpl(ContextImpl context) {
- mPackageInfo = context.mPackageInfo;
- mBasePackageName = context.mBasePackageName;
- mOpPackageName = context.mOpPackageName;
- mResources = context.mResources;
- mMainThread = context.mMainThread;
- mContentResolver = context.mContentResolver;
- mUser = context.mUser;
- mDisplay = context.mDisplay;
- mOuterContext = this;
- mDisplayAdjustments.setCompatibilityInfo(mPackageInfo.getCompatibilityInfo());
+ static ContextImpl createActivityContext(ActivityThread mainThread,
+ LoadedApk packageInfo, IBinder activityToken) {
+ if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
+ if (activityToken == null) throw new IllegalArgumentException("activityInfo");
+ return new ContextImpl(null, mainThread,
+ packageInfo, activityToken, null, false, null, null);
}
- final void init(LoadedApk packageInfo, IBinder activityToken, ActivityThread mainThread) {
- init(packageInfo, activityToken, mainThread, null, null, Process.myUserHandle());
- }
+ private ContextImpl(ContextImpl container, ActivityThread mainThread,
+ LoadedApk packageInfo, IBinder activityToken, UserHandle user, boolean restricted,
+ Display display, Configuration overrideConfiguration) {
+ mOuterContext = this;
+
+ mMainThread = mainThread;
+ mActivityToken = activityToken;
+ mRestricted = restricted;
+
+ if (user == null) {
+ user = Process.myUserHandle();
+ }
+ mUser = user;
- final void init(LoadedApk packageInfo, IBinder activityToken, ActivityThread mainThread,
- Resources container, String basePackageName, UserHandle user) {
mPackageInfo = packageInfo;
- if (basePackageName != null) {
- mBasePackageName = mOpPackageName = basePackageName;
+ mContentResolver = new ApplicationContentResolver(this, mainThread, user);
+ mResourcesManager = ResourcesManager.getInstance();
+ mDisplay = display;
+ mOverrideConfiguration = overrideConfiguration;
+
+ final int displayId = getDisplayId();
+ CompatibilityInfo compatInfo = null;
+ if (container != null) {
+ compatInfo = container.getDisplayAdjustments(displayId).getCompatibilityInfo();
+ }
+ if (compatInfo == null && displayId == Display.DEFAULT_DISPLAY) {
+ compatInfo = packageInfo.getCompatibilityInfo();
+ }
+ mDisplayAdjustments.setCompatibilityInfo(compatInfo);
+ mDisplayAdjustments.setActivityToken(activityToken);
+
+ Resources resources = packageInfo.getResources(mainThread);
+ if (resources != null) {
+ if (activityToken != null
+ || displayId != Display.DEFAULT_DISPLAY
+ || overrideConfiguration != null
+ || (compatInfo != null && compatInfo.applicationScale
+ != resources.getCompatibilityInfo().applicationScale)) {
+ resources = mResourcesManager.getTopLevelResources(
+ packageInfo.getResDir(), packageInfo.getOverlayDirs(), displayId,
+ overrideConfiguration, compatInfo, activityToken);
+ }
+ }
+ mResources = resources;
+
+ if (container != null) {
+ mBasePackageName = container.mBasePackageName;
+ mOpPackageName = container.mOpPackageName;
} else {
mBasePackageName = packageInfo.mPackageName;
ApplicationInfo ainfo = packageInfo.getApplicationInfo();
@@ -2022,45 +2049,10 @@ class ContextImpl extends Context {
mOpPackageName = mBasePackageName;
}
}
- mResources = mPackageInfo.getResources(mainThread);
- mResourcesManager = ResourcesManager.getInstance();
-
- CompatibilityInfo compatInfo =
- container == null ? null : container.getCompatibilityInfo();
- if (mResources != null &&
- ((compatInfo != null && compatInfo.applicationScale !=
- mResources.getCompatibilityInfo().applicationScale)
- || activityToken != null)) {
- if (DEBUG) {
- Log.d(TAG, "loaded context has different scaling. Using container's" +
- " compatiblity info:" + container.getDisplayMetrics());
- }
- if (compatInfo == null) {
- compatInfo = packageInfo.getCompatibilityInfo();
- }
- mDisplayAdjustments.setCompatibilityInfo(compatInfo);
- mDisplayAdjustments.setActivityToken(activityToken);
- mResources = mResourcesManager.getTopLevelResources(mPackageInfo.getResDir(),
- mPackageInfo.getOverlayDirs(), Display.DEFAULT_DISPLAY, null, compatInfo,
- activityToken);
- } else {
- mDisplayAdjustments.setCompatibilityInfo(packageInfo.getCompatibilityInfo());
- mDisplayAdjustments.setActivityToken(activityToken);
- }
- mMainThread = mainThread;
- mActivityToken = activityToken;
- mContentResolver = new ApplicationContentResolver(this, mainThread, user);
- mUser = user;
}
- final void init(Resources resources, ActivityThread mainThread, UserHandle user) {
- mPackageInfo = null;
- mBasePackageName = null;
- mOpPackageName = null;
- mResources = resources;
- mMainThread = mainThread;
- mContentResolver = new ApplicationContentResolver(this, mainThread, user);
- mUser = user;
+ void installSystemApplicationInfo(ApplicationInfo info) {
+ mPackageInfo.installSystemApplicationInfo(info);
}
final void scheduleFinalCleanup(String who, String what) {
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index 0115d1b..d409352 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -72,7 +72,7 @@ public final class LoadedApk {
private static final String TAG = "LoadedApk";
private final ActivityThread mActivityThread;
- private final ApplicationInfo mApplicationInfo;
+ private ApplicationInfo mApplicationInfo;
final String mPackageName;
private final String mAppDir;
private final String mResDir;
@@ -111,8 +111,7 @@ public final class LoadedApk {
* so MUST NOT call back out to the activity manager.
*/
public LoadedApk(ActivityThread activityThread, ApplicationInfo aInfo,
- CompatibilityInfo compatInfo,
- ActivityThread mainThread, ClassLoader baseLoader,
+ CompatibilityInfo compatInfo, ClassLoader baseLoader,
boolean securityViolation, boolean includeCode) {
mActivityThread = activityThread;
mApplicationInfo = aInfo;
@@ -134,31 +133,17 @@ public final class LoadedApk {
mSecurityViolation = securityViolation;
mIncludeCode = includeCode;
mDisplayAdjustments.setCompatibilityInfo(compatInfo);
-
- if (mAppDir == null) {
- if (ActivityThread.mSystemContext == null) {
- ActivityThread.mSystemContext =
- ContextImpl.createSystemContext(mainThread);
- ResourcesManager resourcesManager = ResourcesManager.getInstance();
- ActivityThread.mSystemContext.getResources().updateConfiguration(
- resourcesManager.getConfiguration(),
- resourcesManager.getDisplayMetricsLocked(
- Display.DEFAULT_DISPLAY, mDisplayAdjustments), compatInfo);
- //Slog.i(TAG, "Created system resources "
- // + mSystemContext.getResources() + ": "
- // + mSystemContext.getResources().getConfiguration());
- }
- mClassLoader = ActivityThread.mSystemContext.getClassLoader();
- mResources = ActivityThread.mSystemContext.getResources();
- }
}
- public LoadedApk(ActivityThread activityThread, String name,
- Context systemContext, ApplicationInfo info, CompatibilityInfo compatInfo) {
+ /**
+ * Create information about the system package.
+ * Must call {@link #installSystemApplicationInfo} later.
+ */
+ LoadedApk(ActivityThread activityThread) {
mActivityThread = activityThread;
- mApplicationInfo = info != null ? info : new ApplicationInfo();
- mApplicationInfo.packageName = name;
- mPackageName = name;
+ mApplicationInfo = new ApplicationInfo();
+ mApplicationInfo.packageName = "android";
+ mPackageName = "android";
mAppDir = null;
mResDir = null;
mOverlayDirs = null;
@@ -169,9 +154,16 @@ public final class LoadedApk {
mBaseClassLoader = null;
mSecurityViolation = false;
mIncludeCode = true;
- mClassLoader = systemContext.getClassLoader();
- mResources = systemContext.getResources();
- mDisplayAdjustments.setCompatibilityInfo(compatInfo);
+ mClassLoader = ClassLoader.getSystemClassLoader();
+ mResources = Resources.getSystem();
+ }
+
+ /**
+ * Sets application info about the system package.
+ */
+ void installSystemApplicationInfo(ApplicationInfo info) {
+ assert info.packageName.equals("android");
+ mApplicationInfo = info;
}
public String getPackageName() {
@@ -513,8 +505,7 @@ public final class LoadedApk {
try {
java.lang.ClassLoader cl = getClassLoader();
- ContextImpl appContext = new ContextImpl();
- appContext.init(this, null, mActivityThread);
+ ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
appContext.setOuterContext(app);
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index c63e586..cce6fc4 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -1778,7 +1778,7 @@ public class Notification implements Parcelable
RemoteViews button = new RemoteViews(mContext.getPackageName(),
tombstone ? R.layout.notification_action_tombstone
: R.layout.notification_action);
- button.setTextViewCompoundDrawables(R.id.action0, action.icon, 0, 0, 0);
+ button.setTextViewCompoundDrawablesRelative(R.id.action0, action.icon, 0, 0, 0);
button.setTextViewText(R.id.action0, action.title);
if (!tombstone) {
button.setOnClickPendingIntent(R.id.action0, action.actionIntent);
diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java
index bdd0adb..45467b8 100644
--- a/core/java/android/app/PendingIntent.java
+++ b/core/java/android/app/PendingIntent.java
@@ -87,23 +87,25 @@ public final class PendingIntent implements Parcelable {
private final IIntentSender mTarget;
/**
- * Flag for use with {@link #getActivity}, {@link #getBroadcast}, and
- * {@link #getService}: this
- * PendingIntent can only be used once. If set, after
+ * Flag indicating that this PendingIntent can be used only once.
+ * For use with {@link #getActivity}, {@link #getBroadcast}, and
+ * {@link #getService}. <p>If set, after
* {@link #send()} is called on it, it will be automatically
* canceled for you and any future attempt to send through it will fail.
*/
public static final int FLAG_ONE_SHOT = 1<<30;
/**
- * Flag for use with {@link #getActivity}, {@link #getBroadcast}, and
- * {@link #getService}: if the described PendingIntent does not already
- * exist, then simply return null instead of creating it.
+ * Flag indicating that if the described PendingIntent already
+ * exists, then simply return null instead of creating it.
+ * For use with {@link #getActivity}, {@link #getBroadcast}, and
+ * {@link #getService}.
*/
public static final int FLAG_NO_CREATE = 1<<29;
/**
- * Flag for use with {@link #getActivity}, {@link #getBroadcast}, and
- * {@link #getService}: if the described PendingIntent already exists,
- * the current one is canceled before generating a new one. You can use
+ * Flag indicating that if the described PendingIntent already exists,
+ * the current one should be canceled before generating a new one.
+ * For use with {@link #getActivity}, {@link #getBroadcast}, and
+ * {@link #getService}. <p>You can use
* this to retrieve a new PendingIntent when you are only changing the
* extra data in the Intent; by canceling the previous pending intent,
* this ensures that only entities given the new data will be able to
@@ -112,10 +114,10 @@ public final class PendingIntent implements Parcelable {
*/
public static final int FLAG_CANCEL_CURRENT = 1<<28;
/**
- * Flag for use with {@link #getActivity}, {@link #getBroadcast}, and
- * {@link #getService}: if the described PendingIntent already exists,
- * then keep it but its replace its extra data with what is in this new
- * Intent. This can be used if you are creating intents where only the
+ * Flag indicating that if the described PendingIntent already exists,
+ * then keep it but replace its extra data with what is in this new
+ * Intent. For use with {@link #getActivity}, {@link #getBroadcast}, and
+ * {@link #getService}. <p>This can be used if you are creating intents where only the
* extras change, and don't care that any entities that received your
* previous PendingIntent will be able to launch it with your new
* extras even if they are not explicitly given to it.
@@ -203,7 +205,7 @@ public final class PendingIntent implements Parcelable {
* <p class="note">For security reasons, the {@link android.content.Intent}
* you supply here should almost always be an <em>explicit intent</em>,
* that is specify an explicit component to be delivered to through
- * {@link Intent#setClass(android.content.Context, Class)} Intent.setClass</p>
+ * {@link Intent#setClass(android.content.Context, Class) Intent.setClass}</p>
*
* @param context The Context in which this PendingIntent should start
* the activity.
@@ -234,7 +236,7 @@ public final class PendingIntent implements Parcelable {
* <p class="note">For security reasons, the {@link android.content.Intent}
* you supply here should almost always be an <em>explicit intent</em>,
* that is specify an explicit component to be delivered to through
- * {@link Intent#setClass(android.content.Context, Class)} Intent.setClass</p>
+ * {@link Intent#setClass(android.content.Context, Class) Intent.setClass}</p>
*
* @param context The Context in which this PendingIntent should start
* the activity.
@@ -326,7 +328,7 @@ public final class PendingIntent implements Parcelable {
* <p class="note">For security reasons, the {@link android.content.Intent} objects
* you supply here should almost always be <em>explicit intents</em>,
* that is specify an explicit component to be delivered to through
- * {@link Intent#setClass(android.content.Context, Class)} Intent.setClass</p>
+ * {@link Intent#setClass(android.content.Context, Class) Intent.setClass}</p>
*
* @param context The Context in which this PendingIntent should start
* the activity.
@@ -376,7 +378,7 @@ public final class PendingIntent implements Parcelable {
* <p class="note">For security reasons, the {@link android.content.Intent} objects
* you supply here should almost always be <em>explicit intents</em>,
* that is specify an explicit component to be delivered to through
- * {@link Intent#setClass(android.content.Context, Class)} Intent.setClass</p>
+ * {@link Intent#setClass(android.content.Context, Class) Intent.setClass}</p>
*
* @param context The Context in which this PendingIntent should start
* the activity.
@@ -446,7 +448,7 @@ public final class PendingIntent implements Parcelable {
* <p class="note">For security reasons, the {@link android.content.Intent}
* you supply here should almost always be an <em>explicit intent</em>,
* that is specify an explicit component to be delivered to through
- * {@link Intent#setClass(android.content.Context, Class)} Intent.setClass</p>
+ * {@link Intent#setClass(android.content.Context, Class) Intent.setClass}</p>
*
* @param context The Context in which this PendingIntent should perform
* the broadcast.
@@ -500,7 +502,7 @@ public final class PendingIntent implements Parcelable {
* <p class="note">For security reasons, the {@link android.content.Intent}
* you supply here should almost always be an <em>explicit intent</em>,
* that is specify an explicit component to be delivered to through
- * {@link Intent#setClass(android.content.Context, Class)} Intent.setClass</p>
+ * {@link Intent#setClass(android.content.Context, Class) Intent.setClass}</p>
*
* @param context The Context in which this PendingIntent should start
* the service.
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index c2bbff0..62f7147 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -45,9 +45,7 @@ import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.os.ServiceManager;
-import android.util.DisplayMetrics;
import android.util.Log;
-import android.view.WindowManager;
import android.view.WindowManagerGlobal;
import java.io.BufferedInputStream;
@@ -294,9 +292,8 @@ public class WallpaperManager {
try {
BitmapFactory.Options options = new BitmapFactory.Options();
- Bitmap bm = BitmapFactory.decodeFileDescriptor(
+ return BitmapFactory.decodeFileDescriptor(
fd.getFileDescriptor(), null, options);
- return generateBitmap(context, bm, width, height);
} catch (OutOfMemoryError e) {
Log.w(TAG, "Can't decode file", e);
} finally {
@@ -323,8 +320,7 @@ public class WallpaperManager {
try {
BitmapFactory.Options options = new BitmapFactory.Options();
- Bitmap bm = BitmapFactory.decodeStream(is, null, options);
- return generateBitmap(context, bm, width, height);
+ return BitmapFactory.decodeStream(is, null, options);
} catch (OutOfMemoryError e) {
Log.w(TAG, "Can't decode stream", e);
} finally {
@@ -1033,62 +1029,4 @@ public class WallpaperManager {
public void clear() throws IOException {
setResource(com.android.internal.R.drawable.default_wallpaper);
}
-
- static Bitmap generateBitmap(Context context, Bitmap bm, int width, int height) {
- if (bm == null) {
- return null;
- }
-
- WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
- DisplayMetrics metrics = new DisplayMetrics();
- wm.getDefaultDisplay().getMetrics(metrics);
- bm.setDensity(metrics.noncompatDensityDpi);
-
- if (width <= 0 || height <= 0
- || (bm.getWidth() == width && bm.getHeight() == height)) {
- return bm;
- }
-
- // This is the final bitmap we want to return.
- try {
- Bitmap newbm = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
- newbm.setDensity(metrics.noncompatDensityDpi);
-
- Canvas c = new Canvas(newbm);
- Rect targetRect = new Rect();
- targetRect.right = bm.getWidth();
- targetRect.bottom = bm.getHeight();
-
- int deltaw = width - targetRect.right;
- int deltah = height - targetRect.bottom;
-
- if (deltaw > 0 || deltah > 0) {
- // We need to scale up so it covers the entire area.
- float scale;
- if (deltaw > deltah) {
- scale = width / (float)targetRect.right;
- } else {
- scale = height / (float)targetRect.bottom;
- }
- targetRect.right = (int)(targetRect.right*scale);
- targetRect.bottom = (int)(targetRect.bottom*scale);
- deltaw = width - targetRect.right;
- deltah = height - targetRect.bottom;
- }
-
- targetRect.offset(deltaw/2, deltah/2);
-
- Paint paint = new Paint();
- paint.setFilterBitmap(true);
- paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
- c.drawBitmap(bm, null, targetRect, paint);
-
- bm.recycle();
- c.setBitmap(null);
- return newbm;
- } catch (OutOfMemoryError e) {
- Log.w(TAG, "Can't generate default bitmap", e);
- return bm;
- }
- }
}
diff --git a/core/java/android/app/backup/IBackupManager.aidl b/core/java/android/app/backup/IBackupManager.aidl
index bb4f5f1..12ee3b6 100644
--- a/core/java/android/app/backup/IBackupManager.aidl
+++ b/core/java/android/app/backup/IBackupManager.aidl
@@ -43,14 +43,14 @@ interface IBackupManager {
void dataChanged(String packageName);
/**
- * Erase all backed-up data for the given package from the storage
+ * Erase all backed-up data for the given package from the given storage
* destination.
*
* Any application can invoke this method for its own package, but
* only callers who hold the android.permission.BACKUP permission
* may invoke it for arbitrary packages.
*/
- void clearBackupData(String packageName);
+ void clearBackupData(String transportName, String packageName);
/**
* Notifies the Backup Manager Service that an agent has become available. This
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index e2bc80a..75b007c 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -20,21 +20,23 @@ import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.content.Context;
import android.os.Binder;
+import android.os.Handler;
import android.os.IBinder;
+import android.os.Looper;
import android.os.Message;
import android.os.ParcelUuid;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.Log;
import android.util.Pair;
+
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
-import java.util.HashSet;
import java.util.HashMap;
-import java.util.LinkedList;
+import java.util.HashSet;
import java.util.Locale;
import java.util.Map;
import java.util.Random;
@@ -214,6 +216,22 @@ public final class BluetoothAdapter {
"android.bluetooth.adapter.action.SCAN_MODE_CHANGED";
/**
+ * Broadcast Action: Indicate BLE Advertising is started.
+ * @hide
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_BLUETOOTH_ADVERTISING_STARTED =
+ "android.bluetooth.adapter.action.ADVERTISING_STARTED";
+
+ /**
+ * Broadcast Action: Indicated BLE Advertising is stopped.
+ * @hide
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_BLUETOOTH_ADVERTISING_STOPPED =
+ "android.bluetooth.adapter.action.ADVERTISING_STOPPED";
+
+ /**
* Used as an int extra field in {@link #ACTION_SCAN_MODE_CHANGED}
* intents to request the current scan mode. Possible values are:
* {@link #SCAN_MODE_NONE},
@@ -251,7 +269,6 @@ public final class BluetoothAdapter {
*/
public static final int SCAN_MODE_CONNECTABLE_DISCOVERABLE = 23;
-
/**
* Broadcast Action: The local Bluetooth adapter has started the remote
* device discovery process.
@@ -350,9 +367,27 @@ public final class BluetoothAdapter {
/** The profile is in disconnecting state */
public static final int STATE_DISCONNECTING = 3;
+ /** States for Bluetooth LE advertising */
+ /** @hide */
+ public static final int STATE_ADVERTISE_STARTING = 0;
+ /** @hide */
+ public static final int STATE_ADVERTISE_STARTED = 1;
+ /** @hide */
+ public static final int STATE_ADVERTISE_STOPPING = 2;
+ /** @hide */
+ public static final int STATE_ADVERTISE_STOPPED = 3;
+ /**
+ * Force stopping advertising without callback in case the advertising app dies.
+ * @hide
+ */
+ public static final int STATE_ADVERTISE_FORCE_STOPPING = 4;
+
/** @hide */
public static final String BLUETOOTH_MANAGER_SERVICE = "bluetooth_manager";
+ /** @hide */
+ public static final int ADVERTISE_CALLBACK_SUCCESS = 0;
+
private static final int ADDRESS_LENGTH = 17;
/**
@@ -365,6 +400,10 @@ public final class BluetoothAdapter {
private IBluetooth mService;
private final Map<LeScanCallback, GattCallbackWrapper> mLeScanClients;
+ private BluetoothAdvScanData mBluetoothAdvScanData = null;
+ private GattCallbackWrapper mAdvertisingGattCallback;
+ private final Handler mHandler; // Handler to post the advertise callback to run on main thread.
+ private final Object mLock = new Object();
/**
* Get a handle to the default local Bluetooth adapter.
@@ -400,6 +439,7 @@ public final class BluetoothAdapter {
} catch (RemoteException e) {Log.e(TAG, "", e);}
mManagerService = managerService;
mLeScanClients = new HashMap<LeScanCallback, GattCallbackWrapper>();
+ mHandler = new Handler(Looper.getMainLooper());
}
/**
@@ -438,6 +478,129 @@ public final class BluetoothAdapter {
}
/**
+ * Returns a {@link BluetoothAdvScanData} object representing advertising data.
+ * Data will be reset when bluetooth service is turned off.
+ * @hide
+ */
+ public BluetoothAdvScanData getAdvScanData() {
+ try {
+ IBluetoothGatt iGatt = mManagerService.getBluetoothGatt();
+ if (iGatt == null) {
+ // BLE is not supported
+ Log.e(TAG, "failed to start, iGatt null");
+ return null;
+ }
+ if (mBluetoothAdvScanData == null) {
+ mBluetoothAdvScanData = new BluetoothAdvScanData(iGatt, BluetoothAdvScanData.AD);
+ }
+ return mBluetoothAdvScanData;
+ } catch (RemoteException e) {
+ Log.e(TAG, "failed to get advScanData, error: " + e);
+ return null;
+ }
+ }
+
+ /**
+ * Interface for BLE advertising callback.
+ *
+ * @hide
+ */
+ public interface AdvertiseCallback {
+ /**
+ * Callback when advertise starts.
+ * @param status - {@link #ADVERTISE_CALLBACK_SUCCESS} for success, others for failure.
+ */
+ void onAdvertiseStart(int status);
+ /**
+ * Callback when advertise stops.
+ * @param status - {@link #ADVERTISE_CALLBACK_SUCCESS} for success, others for failure.
+ */
+ void onAdvertiseStop(int status);
+ }
+
+ /**
+ * Start BLE advertising using current {@link BluetoothAdvScanData}.
+ * <p>Requires {@link android.Manifest.permission#BLUETOOTH_PRIVILEGED}
+ *
+ * @param callback - {@link AdvertiseCallback}
+ * @return true if BLE advertising succeeds, false otherwise.
+ * @hide
+ */
+ public boolean startAdvertising(final AdvertiseCallback callback) {
+ if (getState() != STATE_ON) return false;
+ try {
+ IBluetoothGatt iGatt = mManagerService.getBluetoothGatt();
+ if (iGatt == null) {
+ // BLE is not supported.
+ return false;
+ }
+ // Restart/reset advertising packets if advertising is in progress.
+ if (isAdvertising()) {
+ // Invalid advertising callback.
+ if (mAdvertisingGattCallback == null || mAdvertisingGattCallback.mLeHandle == -1) {
+ Log.e(TAG, "failed to restart advertising, invalid callback");
+ return false;
+ }
+ iGatt.startAdvertising(mAdvertisingGattCallback.mLeHandle);
+ // Run the callback from main thread.
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ // callback with status success.
+ callback.onAdvertiseStart(ADVERTISE_CALLBACK_SUCCESS);
+ }
+ });
+ return true;
+ }
+ UUID uuid = UUID.randomUUID();
+ GattCallbackWrapper wrapper =
+ new GattCallbackWrapper(this, null, null, callback);
+ iGatt.registerClient(new ParcelUuid(uuid), wrapper);
+ if (!wrapper.advertiseStarted()) {
+ return false;
+ }
+ synchronized (mLock) {
+ mAdvertisingGattCallback = wrapper;
+ }
+ return true;
+ } catch (RemoteException e) {
+ Log.e(TAG, "", e);
+ return false;
+ }
+ }
+
+ /**
+ * Stop BLE advertising.
+ *
+ * @param callback - {@link AdvertiseCallback}
+ * @return true if BLE advertising stops, false otherwise.
+ * @hide
+ */
+ public boolean stopAdvertising(AdvertiseCallback callback) {
+ try {
+ IBluetoothGatt iGatt = mManagerService.getBluetoothGatt();
+ if (iGatt == null) {
+ // BLE is not supported
+ return false;
+ }
+ if (mAdvertisingGattCallback == null) {
+ // no callback.
+ return false;
+ }
+ // Make sure same callback is used for start and stop advertising.
+ if (callback != mAdvertisingGattCallback.mAdvertiseCallback) {
+ Log.e(TAG, "must use the same callback for star/stop advertising");
+ return false;
+ }
+ mAdvertisingGattCallback.stopAdvertising();
+ return true;
+ } catch (RemoteException e) {
+ Log.e(TAG, "", e);
+ return false;
+ }
+ }
+
+ /**
* Return true if Bluetooth is currently enabled and ready for use.
* <p>Equivalent to:
* <code>getBluetoothState() == STATE_ON</code>
@@ -849,6 +1012,23 @@ public final class BluetoothAdapter {
}
/**
+ * Returns whether BLE is currently advertising.
+ * <p>Requires {@link android.Manifest.permission#BLUETOOTH_PRIVILEGED}.
+ *
+ * @hide
+ */
+ public boolean isAdvertising() {
+ if (getState() != STATE_ON) return false;
+ try {
+ IBluetoothGatt iGatt = mManagerService.getBluetoothGatt();
+ return iGatt.isAdvertising();
+ } catch (RemoteException e) {
+ Log.e(TAG, "", e);
+ }
+ return false;
+ }
+
+ /**
* Return the set of {@link BluetoothDevice} objects that are bonded
* (paired) to the local adapter.
* <p>If Bluetooth state is not {@link #STATE_ON}, this API
@@ -1272,6 +1452,8 @@ public final class BluetoothAdapter {
if (VDBG) Log.d(TAG, "onBluetoothServiceDown: " + mService);
synchronized (mManagerCallback) {
mService = null;
+ // Reset bluetooth adv scan data when Gatt service is down.
+ mBluetoothAdvScanData = null;
for (IBluetoothManagerCallback cb : mProxyServiceStateCallbacks ){
try {
if (cb != null) {
@@ -1547,7 +1729,9 @@ public final class BluetoothAdapter {
private static final int LE_CALLBACK_REG_TIMEOUT = 2000;
private static final int LE_CALLBACK_REG_WAIT_COUNT = 5;
+ private final AdvertiseCallback mAdvertiseCallback;
private final LeScanCallback mLeScanCb;
+
// mLeHandle 0: not registered
// -1: scan stopped
// >0: registered and scan started
@@ -1561,16 +1745,34 @@ public final class BluetoothAdapter {
mLeScanCb = leScanCb;
mScanFilter = uuid;
mLeHandle = 0;
+ mAdvertiseCallback = null;
+ }
+
+ public GattCallbackWrapper(BluetoothAdapter bluetoothAdapter, LeScanCallback leScanCb,
+ UUID[] uuid, AdvertiseCallback callback) {
+ mBluetoothAdapter = new WeakReference<BluetoothAdapter>(bluetoothAdapter);
+ mLeScanCb = leScanCb;
+ mScanFilter = uuid;
+ mLeHandle = 0;
+ mAdvertiseCallback = callback;
}
public boolean scanStarted() {
+ return waitForRegisteration(LE_CALLBACK_REG_WAIT_COUNT);
+ }
+
+ public boolean advertiseStarted() {
+ // Wait for registeration callback.
+ return waitForRegisteration(1);
+ }
+
+ private boolean waitForRegisteration(int maxWaitCount) {
boolean started = false;
synchronized(this) {
if (mLeHandle == -1) return false;
-
int count = 0;
// wait for callback registration and LE scan to start
- while (mLeHandle == 0 && count < LE_CALLBACK_REG_WAIT_COUNT) {
+ while (mLeHandle == 0 && count < maxWaitCount) {
try {
wait(LE_CALLBACK_REG_TIMEOUT);
} catch (InterruptedException e) {
@@ -1583,6 +1785,27 @@ public final class BluetoothAdapter {
return started;
}
+ public void stopAdvertising() {
+ synchronized (this) {
+ if (mLeHandle <= 0) {
+ Log.e(TAG, "Error state, mLeHandle: " + mLeHandle);
+ return;
+ }
+ BluetoothAdapter adapter = mBluetoothAdapter.get();
+ if (adapter != null) {
+ try {
+ IBluetoothGatt iGatt = adapter.getBluetoothManager().getBluetoothGatt();
+ iGatt.stopAdvertising();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to stop advertising" + e);
+ }
+ } else {
+ Log.e(TAG, "stopAdvertising, BluetoothAdapter is null");
+ }
+ notifyAll();
+ }
+ }
+
public void stopLeScan() {
synchronized(this) {
if (mLeHandle <= 0) {
@@ -1624,14 +1847,18 @@ public final class BluetoothAdapter {
BluetoothAdapter adapter = mBluetoothAdapter.get();
if (adapter != null) {
iGatt = adapter.getBluetoothManager().getBluetoothGatt();
- if (mScanFilter == null) {
- iGatt.startScan(mLeHandle, false);
+ if (mAdvertiseCallback != null) {
+ iGatt.startAdvertising(mLeHandle);
} else {
- ParcelUuid[] uuids = new ParcelUuid[mScanFilter.length];
- for(int i = 0; i != uuids.length; ++i) {
- uuids[i] = new ParcelUuid(mScanFilter[i]);
- }
- iGatt.startScanWithUuids(mLeHandle, false, uuids);
+ if (mScanFilter == null) {
+ iGatt.startScan(mLeHandle, false);
+ } else {
+ ParcelUuid[] uuids = new ParcelUuid[mScanFilter.length];
+ for(int i = 0; i != uuids.length; ++i) {
+ uuids[i] = new ParcelUuid(mScanFilter[i]);
+ }
+ iGatt.startScanWithUuids(mLeHandle, false, uuids);
+ }
}
} else {
Log.e(TAG, "onClientRegistered, BluetoothAdapter null");
@@ -1642,7 +1869,7 @@ public final class BluetoothAdapter {
mLeHandle = -1;
}
if (mLeHandle == -1) {
- // registration succeeded but start scan failed
+ // registration succeeded but start scan or advertise failed
if (iGatt != null) {
try {
iGatt.unregisterClient(mLeHandle);
@@ -1670,7 +1897,7 @@ public final class BluetoothAdapter {
* @hide
*/
public void onScanResult(String address, int rssi, byte[] advData) {
- if (DBG) Log.d(TAG, "onScanResult() - Device=" + address + " RSSI=" +rssi);
+ if (VDBG) Log.d(TAG, "onScanResult() - Device=" + address + " RSSI=" +rssi);
// Check null in case the scan has been stopped
synchronized(this) {
@@ -1759,9 +1986,33 @@ public final class BluetoothAdapter {
// no op
}
- public void onListen(int status) {
- // no op
+ public void onAdvertiseStateChange(int advertiseState, int status) {
+ Log.d(TAG, "on advertise call back, state: " + advertiseState + " status: " + status);
+ if (advertiseState == STATE_ADVERTISE_STARTED) {
+ mAdvertiseCallback.onAdvertiseStart(status);
+ } else {
+ synchronized (this) {
+ if (status == ADVERTISE_CALLBACK_SUCCESS) {
+ BluetoothAdapter adapter = mBluetoothAdapter.get();
+ if (adapter != null) {
+ try {
+ IBluetoothGatt iGatt =
+ adapter.getBluetoothManager().getBluetoothGatt();
+ Log.d(TAG, "unregistering client " + mLeHandle);
+ iGatt.unregisterClient(mLeHandle);
+ // Reset advertise app handle.
+ mLeHandle = -1;
+ adapter.mAdvertisingGattCallback = null;
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to unregister client" + e);
+ }
+ } else {
+ Log.e(TAG, "cannot unregister client, BluetoothAdapter is null");
+ }
+ }
+ }
+ mAdvertiseCallback.onAdvertiseStop(status);
+ }
}
}
-
}
diff --git a/core/java/android/bluetooth/BluetoothAdvScanData.java b/core/java/android/bluetooth/BluetoothAdvScanData.java
new file mode 100644
index 0000000..df2c256
--- /dev/null
+++ b/core/java/android/bluetooth/BluetoothAdvScanData.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.bluetooth;
+import android.os.ParcelUuid;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.util.Collections;
+import java.util.List;
+
+
+/**
+ * This class provides the public APIs to set advertising and scan response data when BLE device
+ * operates in peripheral mode. <br>
+ * The exact format is defined in Bluetooth 4.0 specification, Volume 3, Part C, Section 11
+ * @hide
+ */
+public final class BluetoothAdvScanData {
+
+ /**
+ * Available data types of {@link BluetoothAdvScanData}.
+ */
+ public static final int AD = 0; // Advertising Data
+ public static final int SCAN_RESPONSE = 1; // Scan Response
+ public static final int EIR = 2; // Extended Inquiry Response
+
+ private static final String TAG = "BluetoothAdvScanData";
+
+ /**
+ * Data type of BluetoothAdvScanData.
+ */
+ private final int mDataType;
+ /**
+ * Bluetooth Gatt Service.
+ */
+ private IBluetoothGatt mBluetoothGatt;
+
+ /**
+ * @param mBluetoothGatt
+ * @param dataType
+ */
+ public BluetoothAdvScanData(IBluetoothGatt mBluetoothGatt, int dataType) {
+ this.mBluetoothGatt = mBluetoothGatt;
+ this.mDataType = dataType;
+ }
+
+ /**
+ * @return advertising data type.
+ */
+ public int getDataType() {
+ return mDataType;
+ }
+
+ /**
+ * Set manufactureCode and manufactureData.
+ * Returns true if manufacturer data is set, false if there is no enough room to set
+ * manufacturer data or the data is already set.
+ * @param manufacturerCode - unique identifier for the manufacturer
+ * @param manufacturerData - data associated with the specific manufacturer.
+ */
+ public boolean setManufacturerData(int manufacturerCode, byte[] manufacturerData) {
+ if (mDataType != AD) return false;
+ try {
+ return mBluetoothGatt.setAdvManufacturerCodeAndData(manufacturerCode, manufacturerData);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Unable to set manufacturer id and data.", e);
+ return false;
+ }
+ }
+
+ /**
+ * Set service data. Note the service data can only be set when the data type is {@code AD};
+ * @param serviceData
+ */
+ public boolean setServiceData(byte[] serviceData) {
+
+ if (mDataType != AD) return false;
+ if (serviceData == null) return false;
+ try {
+ return mBluetoothGatt.setAdvServiceData(serviceData);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Unable to set service data.", e);
+ return false;
+ }
+ }
+
+ /**
+ * Returns an immutable list of service uuids that will be advertised.
+ */
+ public List<ParcelUuid> getServiceUuids() {
+ try {
+ return Collections.unmodifiableList(mBluetoothGatt.getAdvServiceUuids());
+ } catch (RemoteException e) {
+ Log.e(TAG, "Unable to get service uuids.", e);
+ return null;
+ }
+ }
+
+ /**
+ * Returns manufacturer data.
+ */
+ public byte[] getManufacturerData() {
+ if (mBluetoothGatt == null) return null;
+ try {
+ return mBluetoothGatt.getAdvManufacturerData();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Unable to get manufacturer data.", e);
+ return null;
+ }
+ }
+
+ /**
+ * Returns service data.
+ */
+ public byte[] getServiceData() {
+ if (mBluetoothGatt == null) return null;
+ try {
+ return mBluetoothGatt.getAdvServiceData();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Unable to get service data.", e);
+ return null;
+ }
+ }
+
+ /**
+ * Remove manufacturer data based on given manufacturer code.
+ * @param manufacturerCode
+ */
+ public void removeManufacturerCodeAndData(int manufacturerCode) {
+ if (mBluetoothGatt != null) {
+ try {
+ mBluetoothGatt.removeAdvManufacturerCodeAndData(manufacturerCode);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Unable to remove manufacturer : " + manufacturerCode, e);
+ }
+ }
+ }
+}
diff --git a/core/java/android/bluetooth/BluetoothGatt.java b/core/java/android/bluetooth/BluetoothGatt.java
index a2bb78c..ae6ad3b 100644
--- a/core/java/android/bluetooth/BluetoothGatt.java
+++ b/core/java/android/bluetooth/BluetoothGatt.java
@@ -555,11 +555,12 @@ public final class BluetoothGatt implements BluetoothProfile {
}
/**
- * Listen command status callback
+ * Advertise state change callback
* @hide
*/
- public void onListen(int status) {
- if (DBG) Log.d(TAG, "onListen() - status=" + status);
+ public void onAdvertiseStateChange(int state, int status) {
+ if (DBG) Log.d(TAG, "onAdvertiseStateChange() - state = "
+ + state + " status=" + status);
}
};
@@ -693,71 +694,6 @@ public final class BluetoothGatt implements BluetoothProfile {
return true;
}
- /**
- * Starts or stops sending of advertisement packages to listen for connection
- * requests from a central devices.
- *
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
- *
- * @param start Start or stop advertising
- */
- /*package*/ void listen(boolean start) {
- if (mContext == null || !mContext.getResources().
- getBoolean(com.android.internal.R.bool.config_bluetooth_le_peripheral_mode_supported)) {
- throw new UnsupportedOperationException("BluetoothGatt#listen is blocked");
- }
- if (DBG) Log.d(TAG, "listen() - start: " + start);
- if (mService == null || mClientIf == 0) return;
-
- try {
- mService.clientListen(mClientIf, start);
- } catch (RemoteException e) {
- Log.e(TAG,"",e);
- }
- }
-
- /**
- * Sets the advertising data contained in the adv. response packet.
- *
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
- *
- * @param advData true to set adv. data, false to set scan response
- * @param includeName Inlucde the name in the adv. response
- * @param includeTxPower Include TX power value
- * @param minInterval Minimum desired scan interval (optional)
- * @param maxInterval Maximum desired scan interval (optional)
- * @param appearance The appearance flags for the device (optional)
- * @param manufacturerData Manufacturer specific data including company ID (optional)
- */
- /*package*/ void setAdvData(boolean advData, boolean includeName, boolean includeTxPower,
- Integer minInterval, Integer maxInterval,
- Integer appearance, Byte[] manufacturerData) {
- if (mContext == null || !mContext.getResources().
- getBoolean(com.android.internal.R.bool.config_bluetooth_le_peripheral_mode_supported)) {
- throw new UnsupportedOperationException("BluetoothGatt#setAdvData is blocked");
- }
- if (DBG) Log.d(TAG, "setAdvData()");
- if (mService == null || mClientIf == 0) return;
-
- byte[] data = new byte[0];
- if (manufacturerData != null) {
- data = new byte[manufacturerData.length];
- for(int i = 0; i != manufacturerData.length; ++i) {
- data[i] = manufacturerData[i];
- }
- }
-
- try {
- mService.setAdvData(mClientIf, !advData,
- includeName, includeTxPower,
- minInterval != null ? minInterval : 0,
- maxInterval != null ? maxInterval : 0,
- appearance != null ? appearance : 0, data);
- } catch (RemoteException e) {
- Log.e(TAG,"",e);
- }
- }
-
/**
* Disconnects an established connection, or cancels a connection attempt
* currently in progress.
diff --git a/core/java/android/bluetooth/BluetoothGattServer.java b/core/java/android/bluetooth/BluetoothGattServer.java
index 58ee54f..153215c 100644
--- a/core/java/android/bluetooth/BluetoothGattServer.java
+++ b/core/java/android/bluetooth/BluetoothGattServer.java
@@ -537,7 +537,7 @@ public final class BluetoothGattServer implements BluetoothProfile {
try {
mService.beginServiceDeclaration(mServerIf, service.getType(),
service.getInstanceId(), service.getHandles(),
- new ParcelUuid(service.getUuid()));
+ new ParcelUuid(service.getUuid()), service.isAdvertisePreferred());
List<BluetoothGattService> includedServices = service.getIncludedServices();
for (BluetoothGattService includedService : includedServices) {
diff --git a/core/java/android/bluetooth/BluetoothGattService.java b/core/java/android/bluetooth/BluetoothGattService.java
index 1e66369..52bc0f7 100644
--- a/core/java/android/bluetooth/BluetoothGattService.java
+++ b/core/java/android/bluetooth/BluetoothGattService.java
@@ -15,8 +15,6 @@
*/
package android.bluetooth;
-import android.bluetooth.BluetoothDevice;
-
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
@@ -82,6 +80,11 @@ public class BluetoothGattService {
protected List<BluetoothGattService> mIncludedServices;
/**
+ * Whether the service uuid should be advertised.
+ */
+ private boolean mAdvertisePreferred;
+
+ /**
* Create a new BluetoothGattService.
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
@@ -263,4 +266,20 @@ public class BluetoothGattService {
}
return null;
}
+
+ /**
+ * Returns whether the uuid of the service should be advertised.
+ * @hide
+ */
+ public boolean isAdvertisePreferred() {
+ return mAdvertisePreferred;
+ }
+
+ /**
+ * Set whether the service uuid should be advertised.
+ * @hide
+ */
+ public void setAdvertisePreferred(boolean advertisePreferred) {
+ this.mAdvertisePreferred = advertisePreferred;
+ }
}
diff --git a/core/java/android/bluetooth/BluetoothUuid.java b/core/java/android/bluetooth/BluetoothUuid.java
index abdf949..4b28516 100644
--- a/core/java/android/bluetooth/BluetoothUuid.java
+++ b/core/java/android/bluetooth/BluetoothUuid.java
@@ -73,6 +73,9 @@ public final class BluetoothUuid {
public static final ParcelUuid MAS =
ParcelUuid.fromString("00001132-0000-1000-8000-00805F9B34FB");
+ public static final ParcelUuid BASE_UUID =
+ ParcelUuid.fromString("00000000-0000-1000-8000-00805F9B34FB");
+
public static final ParcelUuid[] RESERVED_UUIDS = {
AudioSink, AudioSource, AdvAudioDist, HSP, Handsfree, AvrcpController, AvrcpTarget,
@@ -211,4 +214,17 @@ public final class BluetoothUuid {
long value = (uuid.getMostSignificantBits() & 0x0000FFFF00000000L) >>> 32;
return (int)value;
}
+
+ /**
+ * Check whether the given parcelUuid can be converted to 16 bit bluetooth uuid.
+ * @param parcelUuid
+ * @return true if the parcelUuid can be converted to 16 bit uuid, false otherwise.
+ */
+ public static boolean isShortUuid(ParcelUuid parcelUuid) {
+ UUID uuid = parcelUuid.getUuid();
+ if (uuid.getLeastSignificantBits() != BASE_UUID.getUuid().getLeastSignificantBits()) {
+ return false;
+ }
+ return ((uuid.getMostSignificantBits() & 0xFFFF0000FFFFFFFFL) == 0x1000L);
+ }
}
diff --git a/core/java/android/bluetooth/IBluetoothGatt.aidl b/core/java/android/bluetooth/IBluetoothGatt.aidl
index df393db..784cdcc 100644
--- a/core/java/android/bluetooth/IBluetoothGatt.aidl
+++ b/core/java/android/bluetooth/IBluetoothGatt.aidl
@@ -37,10 +37,15 @@ interface IBluetoothGatt {
void unregisterClient(in int clientIf);
void clientConnect(in int clientIf, in String address, in boolean isDirect);
void clientDisconnect(in int clientIf, in String address);
- void clientListen(in int clientIf, in boolean start);
- void setAdvData(in int clientIf, in boolean setScanRsp, in boolean inclName,
- in boolean inclTxPower, in int minInterval, in int maxInterval,
- in int appearance, in byte[] manufacturerData);
+ void startAdvertising(in int appIf);
+ void stopAdvertising();
+ boolean setAdvServiceData(in byte[] serviceData);
+ byte[] getAdvServiceData();
+ boolean setAdvManufacturerCodeAndData(int manufactureCode, in byte[] manufacturerData);
+ byte[] getAdvManufacturerData();
+ List<ParcelUuid> getAdvServiceUuids();
+ void removeAdvManufacturerCodeAndData(int manufacturerCode);
+ boolean isAdvertising();
void refreshDevice(in int clientIf, in String address);
void discoverServices(in int clientIf, in String address);
void readCharacteristic(in int clientIf, in String address, in int srvcType,
@@ -75,7 +80,7 @@ interface IBluetoothGatt {
void serverDisconnect(in int serverIf, in String address);
void beginServiceDeclaration(in int serverIf, in int srvcType,
in int srvcInstanceId, in int minHandles,
- in ParcelUuid srvcId);
+ in ParcelUuid srvcId, boolean advertisePreferred);
void addIncludedService(in int serverIf, in int srvcType,
in int srvcInstanceId, in ParcelUuid srvcId);
void addCharacteristic(in int serverIf, in ParcelUuid charId,
diff --git a/core/java/android/bluetooth/IBluetoothGattCallback.aidl b/core/java/android/bluetooth/IBluetoothGattCallback.aidl
index 60c297b..7c69a06 100644
--- a/core/java/android/bluetooth/IBluetoothGattCallback.aidl
+++ b/core/java/android/bluetooth/IBluetoothGattCallback.aidl
@@ -63,5 +63,5 @@ interface IBluetoothGattCallback {
in int charInstId, in ParcelUuid charUuid,
in byte[] value);
void onReadRemoteRssi(in String address, in int rssi, in int status);
- void onListen(in int status);
+ oneway void onAdvertiseStateChange(in int advertiseState, in int status);
}
diff --git a/core/java/android/bluetooth/package.html b/core/java/android/bluetooth/package.html
index 200a21b..d9ca4f1 100644
--- a/core/java/android/bluetooth/package.html
+++ b/core/java/android/bluetooth/package.html
@@ -8,17 +8,19 @@ The Bluetooth API supports both "Classic Bluetooth" and Bluetooth Low Energy.</p
<a href="{@docRoot}guide/topics/connectivity/bluetooth.html">Bluetooth</a> guide.
For more information about Bluetooth Low Energy, see the
<a href="{@docRoot}guide/topics/connectivity/bluetooth-le.html">
-Bluetooth Low Energy</a> guide.</p>
+Bluetooth Low Energy</a> (BLE) guide.</p>
{@more}
<p>The Bluetooth APIs let applications:</p>
<ul>
- <li>Scan for other Bluetooth devices (including Bluetooth Low Energy
- devices)</li>
- <li>Query the local Bluetooth adapter for paired Bluetooth devices</li>
- <li>Establish RFCOMM channels/sockets</li>
- <li>Connect to specified sockets on other devices</li>
- <li>Transfer data to and from other devices</li>
+ <li>Scan for other Bluetooth devices (including BLE devices).</li>
+ <li>Query the local Bluetooth adapter for paired Bluetooth devices.</li>
+ <li>Establish RFCOMM channels/sockets.</li>
+ <li>Connect to specified sockets on other devices.</li>
+ <li>Transfer data to and from other devices.</li>
+ <li>Communicate with BLE devices, such as proximity sensors, heart rate
+ monitors, fitness devices, and so on.</li>
+ <li>Act as a GATT client or a GATT server (BLE).</li>
</ul>
<p>
diff --git a/core/java/android/content/ClipDescription.java b/core/java/android/content/ClipDescription.java
index 5cb6e77..be35f08 100644
--- a/core/java/android/content/ClipDescription.java
+++ b/core/java/android/content/ClipDescription.java
@@ -87,7 +87,7 @@ public class ClipDescription implements Parcelable {
/**
* Helper to compare two MIME types, where one may be a pattern.
* @param concreteType A fully-specified MIME type.
- * @param desiredType A desired MIME type that may be a pattern such as *\/*.
+ * @param desiredType A desired MIME type that may be a pattern such as *&#47;*.
* @return Returns true if the two MIME types match.
*/
public static boolean compareMimeTypes(String concreteType, String desiredType) {
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index 44831fc..02c850b 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -1328,7 +1328,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
*
* @param uri The data in the content provider being queried.
* @param mimeTypeFilter The type of data the client desires. May be
- * a pattern, such as *\/* to retrieve all possible data types.
+ * a pattern, such as *&#47;* to retrieve all possible data types.
* @return Returns {@code null} if there are no possible data streams for the
* given mimeTypeFilter. Otherwise returns an array of all available
* concrete MIME types.
@@ -1366,7 +1366,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
*
* @param uri The data in the content provider being queried.
* @param mimeTypeFilter The type of data the client desires. May be
- * a pattern, such as *\/*, if the caller does not have specific type
+ * a pattern, such as *&#47;*, if the caller does not have specific type
* requirements; in this case the content provider will pick its best
* type matching the pattern.
* @param opts Additional options from the client. The definitions of
@@ -1427,7 +1427,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
*
* @param uri The data in the content provider being queried.
* @param mimeTypeFilter The type of data the client desires. May be
- * a pattern, such as *\/*, if the caller does not have specific type
+ * a pattern, such as *&#47;*, if the caller does not have specific type
* requirements; in this case the content provider will pick its best
* type matching the pattern.
* @param opts Additional options from the client. The definitions of
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 4e6cc92..2bf4d7d 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -344,7 +344,7 @@ public abstract class ContentResolver {
* @param url A Uri identifying content (either a list or specific type),
* using the content:// scheme.
* @param mimeTypeFilter The desired MIME type. This may be a pattern,
- * such as *\/*, to query for all available MIME types that match the
+ * such as *&#47;*, to query for all available MIME types that match the
* pattern.
* @return Returns an array of MIME type strings for all available
* data streams that match the given mimeTypeFilter. If there are none,
@@ -815,7 +815,7 @@ public abstract class ContentResolver {
*
* <p>Note that if this function is called for read-only input (mode is "r")
* on a content: URI, it will instead call {@link #openTypedAssetFileDescriptor}
- * for you with a MIME type of "*\/*". This allows such callers to benefit
+ * for you with a MIME type of "*&#47;*". This allows such callers to benefit
* from any built-in data conversion that a provider implements.
*
* @param uri The desired URI to open.
@@ -868,7 +868,7 @@ public abstract class ContentResolver {
*
* <p>Note that if this function is called for read-only input (mode is "r")
* on a content: URI, it will instead call {@link #openTypedAssetFileDescriptor}
- * for you with a MIME type of "*\/*". This allows such callers to benefit
+ * for you with a MIME type of "*&#47;*". This allows such callers to benefit
* from any built-in data conversion that a provider implements.
*
* @param uri The desired URI to open.
@@ -993,7 +993,7 @@ public abstract class ContentResolver {
*
* @param uri The desired URI to open.
* @param mimeType The desired MIME type of the returned data. This can
- * be a pattern such as *\/*, which will allow the content provider to
+ * be a pattern such as *&#47;*, which will allow the content provider to
* select a type, though there is no way for you to determine what type
* it is returning.
* @param opts Additional provider-dependent options.
@@ -1026,7 +1026,7 @@ public abstract class ContentResolver {
*
* @param uri The desired URI to open.
* @param mimeType The desired MIME type of the returned data. This can
- * be a pattern such as *\/*, which will allow the content provider to
+ * be a pattern such as *&#47;*, which will allow the content provider to
* select a type, though there is no way for you to determine what type
* it is returning.
* @param opts Additional provider-dependent options.
@@ -1535,7 +1535,7 @@ public abstract class ContentResolver {
* for a whole class of content.
* @param notifyForDescendents If <code>true</code> changes to URIs beginning with <code>uri</code>
* will also cause notifications to be sent. If <code>false</code> only changes to the exact URI
- * specified by <em>uri</em> will cause notifications to be sent. If true, than any URI values
+ * specified by <em>uri</em> will cause notifications to be sent. If <code>true</code>, any URI values
* at or below the specified URI will also trigger a match.
* @param observer The object that receives callbacks when changes occur.
* @see #unregisterContentObserver
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 2e2d4b8..a50b650 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -844,7 +844,7 @@ public class Intent implements Parcelable, Cloneable {
* {@link #FLAG_GRANT_WRITE_URI_PERMISSION}, then these flags will also be
* set in the returned chooser intent, with its ClipData set appropriately:
* either a direct reflection of {@link #getClipData()} if that is non-null,
- * or a new ClipData build from {@link #getData()}.
+ * or a new ClipData built from {@link #getData()}.
*
* @param target The Intent that the user will be selecting an activity
* to perform.
@@ -4424,7 +4424,7 @@ public class Intent implements Parcelable, Cloneable {
* Return the {@link ClipData} associated with this Intent. If there is
* none, returns null. See {@link #setClipData} for more information.
*
- * @see #setClipData;
+ * @see #setClipData
*/
public ClipData getClipData() {
return mClipData;
@@ -5440,7 +5440,7 @@ public class Intent implements Parcelable, Cloneable {
* directly used by Intent. Applications should generally rely on the
* MIME type of the Intent itself, not what it may find in the ClipData.
* A common practice is to construct a ClipData for use with an Intent
- * with a MIME type of "*\/*".
+ * with a MIME type of "*&#47;*".
*
* @param clip The new clip to set. May be null to clear the current clip.
*/
@@ -7162,8 +7162,8 @@ public class Intent implements Parcelable, Cloneable {
*
* @param type MIME data type to normalize
* @return normalized MIME data type, or null if the input was null
- * @see {@link #setType}
- * @see {@link #setTypeAndNormalize}
+ * @see #setType
+ * @see #setTypeAndNormalize
*/
public static String normalizeMimeType(String type) {
if (type == null) {
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 111062d..eae4a46 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -45,6 +45,7 @@ import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;
@@ -2150,10 +2151,20 @@ public class Camera {
private static final String PIXEL_FORMAT_JPEG = "jpeg";
private static final String PIXEL_FORMAT_BAYER_RGGB = "bayer-rggb";
- private HashMap<String, String> mMap;
+ /**
+ * Order matters: Keys that are {@link #set(String, String) set} later
+ * will take precedence over keys that are set earlier (if the two keys
+ * conflict with each other).
+ *
+ * <p>One example is {@link #setPreviewFpsRange(int, int)} , since it
+ * conflicts with {@link #setPreviewFrameRate(int)} whichever key is set later
+ * is the one that will take precedence.
+ * </p>
+ */
+ private final LinkedHashMap<String, String> mMap;
private Parameters() {
- mMap = new HashMap<String, String>(64);
+ mMap = new LinkedHashMap<String, String>(/*initialCapacity*/64);
}
/**
@@ -2233,7 +2244,7 @@ public class Camera {
return;
}
- mMap.put(key, value);
+ put(key, value);
}
/**
@@ -2243,7 +2254,18 @@ public class Camera {
* @param value the int value of the parameter
*/
public void set(String key, int value) {
- mMap.put(key, Integer.toString(value));
+ put(key, Integer.toString(value));
+ }
+
+ private void put(String key, String value) {
+ /*
+ * Remove the key if it already exists.
+ *
+ * This way setting a new value for an already existing key will always move
+ * that key to be ordered the latest in the map.
+ */
+ mMap.remove(key);
+ mMap.put(key, value);
}
private void set(String key, List<Area> areas) {
diff --git a/core/java/android/hardware/SensorManager.java b/core/java/android/hardware/SensorManager.java
index ac9189d..5f2b5f0 100644
--- a/core/java/android/hardware/SensorManager.java
+++ b/core/java/android/hardware/SensorManager.java
@@ -1056,8 +1056,8 @@ public abstract class SensorManager {
* is mapped.
*
* @param outR
- * the transformed rotation matrix. inR and outR can be the same
- * array, but it is not recommended for performance reason.
+ * the transformed rotation matrix. inR and outR should not be the same
+ * array.
*
* @return <code>true</code> on success. <code>false</code> if the input
* parameters are incorrect, for instance if X and Y define the same
diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java
index d5208d9..093e0e9 100644
--- a/core/java/android/hardware/display/DisplayManager.java
+++ b/core/java/android/hardware/display/DisplayManager.java
@@ -297,16 +297,31 @@ public final class DisplayManager {
}
/**
- * Initiates a fresh scan of availble Wifi displays.
+ * Starts scanning for available Wifi displays.
* The results are sent as a {@link #ACTION_WIFI_DISPLAY_STATUS_CHANGED} broadcast.
* <p>
+ * Calls to this method nest and must be matched by an equal number of calls to
+ * {@link #stopWifiDisplayScan()}.
+ * </p><p>
+ * Requires {@link android.Manifest.permission#CONFIGURE_WIFI_DISPLAY}.
+ * </p>
+ *
+ * @hide
+ */
+ public void startWifiDisplayScan() {
+ mGlobal.startWifiDisplayScan();
+ }
+
+ /**
+ * Stops scanning for available Wifi displays.
+ * <p>
* Requires {@link android.Manifest.permission#CONFIGURE_WIFI_DISPLAY}.
* </p>
*
* @hide
*/
- public void scanWifiDisplays() {
- mGlobal.scanWifiDisplays();
+ public void stopWifiDisplayScan() {
+ mGlobal.stopWifiDisplayScan();
}
/**
diff --git a/core/java/android/hardware/display/DisplayManagerGlobal.java b/core/java/android/hardware/display/DisplayManagerGlobal.java
index 936a086..3417430 100644
--- a/core/java/android/hardware/display/DisplayManagerGlobal.java
+++ b/core/java/android/hardware/display/DisplayManagerGlobal.java
@@ -72,6 +72,8 @@ public final class DisplayManagerGlobal {
private final SparseArray<DisplayInfo> mDisplayInfoCache = new SparseArray<DisplayInfo>();
private int[] mDisplayIdCache;
+ private int mWifiDisplayScanNestCount;
+
private DisplayManagerGlobal(IDisplayManager dm) {
mDm = dm;
}
@@ -267,11 +269,32 @@ public final class DisplayManagerGlobal {
}
}
- public void scanWifiDisplays() {
- try {
- mDm.scanWifiDisplays();
- } catch (RemoteException ex) {
- Log.e(TAG, "Failed to scan for Wifi displays.", ex);
+ public void startWifiDisplayScan() {
+ synchronized (mLock) {
+ if (mWifiDisplayScanNestCount++ == 0) {
+ registerCallbackIfNeededLocked();
+ try {
+ mDm.startWifiDisplayScan();
+ } catch (RemoteException ex) {
+ Log.e(TAG, "Failed to scan for Wifi displays.", ex);
+ }
+ }
+ }
+ }
+
+ public void stopWifiDisplayScan() {
+ synchronized (mLock) {
+ if (--mWifiDisplayScanNestCount == 0) {
+ try {
+ mDm.stopWifiDisplayScan();
+ } catch (RemoteException ex) {
+ Log.e(TAG, "Failed to scan for Wifi displays.", ex);
+ }
+ } else if (mWifiDisplayScanNestCount < 0) {
+ Log.wtf(TAG, "Wifi display scan nest count became negative: "
+ + mWifiDisplayScanNestCount);
+ mWifiDisplayScanNestCount = 0;
+ }
}
}
diff --git a/core/java/android/hardware/display/IDisplayManager.aidl b/core/java/android/hardware/display/IDisplayManager.aidl
index 6b2c887..68eb13f 100644
--- a/core/java/android/hardware/display/IDisplayManager.aidl
+++ b/core/java/android/hardware/display/IDisplayManager.aidl
@@ -29,11 +29,14 @@ interface IDisplayManager {
void registerCallback(in IDisplayManagerCallback callback);
- // No permissions required.
- void scanWifiDisplays();
+ // Requires CONFIGURE_WIFI_DISPLAY permission.
+ // The process must have previously registered a callback.
+ void startWifiDisplayScan();
- // Requires CONFIGURE_WIFI_DISPLAY permission to connect to an unknown device.
- // No permissions required to connect to a known device.
+ // Requires CONFIGURE_WIFI_DISPLAY permission.
+ void stopWifiDisplayScan();
+
+ // Requires CONFIGURE_WIFI_DISPLAY permission.
void connectWifiDisplay(String address);
// No permissions required.
@@ -45,6 +48,12 @@ interface IDisplayManager {
// Requires CONFIGURE_WIFI_DISPLAY permission.
void forgetWifiDisplay(String address);
+ // Requires CONFIGURE_WIFI_DISPLAY permission.
+ void pauseWifiDisplay();
+
+ // Requires CONFIGURE_WIFI_DISPLAY permission.
+ void resumeWifiDisplay();
+
// No permissions required.
WifiDisplayStatus getWifiDisplayStatus();
@@ -55,10 +64,4 @@ interface IDisplayManager {
// No permissions required but must be same Uid as the creator.
void releaseVirtualDisplay(in IBinder token);
-
- // Requires CONFIGURE_WIFI_DISPLAY permission.
- void pauseWifiDisplay();
-
- // Requires CONFIGURE_WIFI_DISPLAY permission.
- void resumeWifiDisplay();
}
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index c78a973..70c8750 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -395,6 +395,8 @@ public class ConnectivityManager {
private final IConnectivityManager mService;
+ private final String mPackageName;
+
/**
* Tests if a given integer represents a valid network type.
* @param networkType the type to be tested
@@ -802,7 +804,7 @@ public class ConnectivityManager {
public boolean requestRouteToHostAddress(int networkType, InetAddress hostAddress) {
byte[] address = hostAddress.getAddress();
try {
- return mService.requestRouteToHostAddress(networkType, address);
+ return mService.requestRouteToHostAddress(networkType, address, mPackageName);
} catch (RemoteException e) {
return false;
}
@@ -898,8 +900,9 @@ public class ConnectivityManager {
/**
* {@hide}
*/
- public ConnectivityManager(IConnectivityManager service) {
+ public ConnectivityManager(IConnectivityManager service, String packageName) {
mService = checkNotNull(service, "missing IConnectivityManager");
+ mPackageName = checkNotNull(packageName, "missing package name");
}
/** {@hide} */
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index c1da2e3..4bca7fe 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -71,9 +71,9 @@ interface IConnectivityManager
int stopUsingNetworkFeature(int networkType, in String feature);
- boolean requestRouteToHost(int networkType, int hostAddress);
+ boolean requestRouteToHost(int networkType, int hostAddress, String packageName);
- boolean requestRouteToHostAddress(int networkType, in byte[] hostAddress);
+ boolean requestRouteToHostAddress(int networkType, in byte[] hostAddress, String packageName);
boolean getMobileDataEnabled();
void setMobileDataEnabled(boolean enabled);
diff --git a/core/java/android/net/MobileDataStateTracker.java b/core/java/android/net/MobileDataStateTracker.java
index c106514..21352bf 100644
--- a/core/java/android/net/MobileDataStateTracker.java
+++ b/core/java/android/net/MobileDataStateTracker.java
@@ -566,6 +566,17 @@ public class MobileDataStateTracker extends BaseNetworkStateTracker {
return false;
}
+
+ public void setInternalDataEnable(boolean enabled) {
+ if (DBG) log("setInternalDataEnable: E enabled=" + enabled);
+ final AsyncChannel channel = mDataConnectionTrackerAc;
+ if (channel != null) {
+ channel.sendMessage(DctConstants.EVENT_SET_INTERNAL_DATA_ENABLE,
+ enabled ? DctConstants.ENABLED : DctConstants.DISABLED);
+ }
+ if (VDBG) log("setInternalDataEnable: X enabled=" + enabled);
+ }
+
@Override
public void setUserDataEnable(boolean enabled) {
if (DBG) log("setUserDataEnable: E enabled=" + enabled);
diff --git a/core/java/android/net/VpnService.java b/core/java/android/net/VpnService.java
index d7dc7f5..7385dff 100644
--- a/core/java/android/net/VpnService.java
+++ b/core/java/android/net/VpnService.java
@@ -151,9 +151,10 @@ public class VpnService extends Service {
}
/**
- * Protect a socket from VPN connections. The socket will be bound to the
- * current default network interface, so its traffic will not be forwarded
- * through VPN. This method is useful if some connections need to be kept
+ * Protect a socket from VPN connections. After protecting, data sent
+ * through this socket will go directly to the underlying network,
+ * so its traffic will not be forwarded through the VPN.
+ * This method is useful if some connections need to be kept
* outside of VPN. For example, a VPN tunnel should protect itself if its
* destination is covered by VPN routes. Otherwise its outgoing packets
* will be sent back to the VPN interface and cause an infinite loop. This
diff --git a/core/java/android/os/AsyncTask.java b/core/java/android/os/AsyncTask.java
index d4a3006..26e09b6 100644
--- a/core/java/android/os/AsyncTask.java
+++ b/core/java/android/os/AsyncTask.java
@@ -610,7 +610,7 @@ public abstract class AsyncTask<Params, Progress, Result> {
* still running. Each call to this method will trigger the execution of
* {@link #onProgressUpdate} on the UI thread.
*
- * {@link #onProgressUpdate} will note be called if the task has been
+ * {@link #onProgressUpdate} will not be called if the task has been
* canceled.
*
* @param values The progress values to update the UI with.
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 1bddc7a..ab45f02 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -49,7 +49,7 @@ public class Build {
/** The manufacturer of the product/hardware. */
public static final String MANUFACTURER = getString("ro.product.manufacturer");
- /** The brand (e.g., carrier) the software is customized for, if any. */
+ /** The consumer-visible brand with which the product/hardware will be associated, if any. */
public static final String BRAND = getString("ro.product.brand");
/** The end-user-visible name for the end product. */
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index 21b8ae5..f65b6ba 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -420,7 +420,7 @@ interface INetworkManagementService
/**
* Clear a user range from being associated with an interface.
*/
- void clearDnsInterfaceForUidRange(int uid_start, int uid_end);
+ void clearDnsInterfaceForUidRange(String iface, int uid_start, int uid_end);
/**
* Clear the mappings from pid to Dns interface and from uid range to Dns interface.
diff --git a/core/java/android/os/Vibrator.java b/core/java/android/os/Vibrator.java
index 6650fca..5d55143 100644
--- a/core/java/android/os/Vibrator.java
+++ b/core/java/android/os/Vibrator.java
@@ -21,11 +21,11 @@ import android.content.Context;
/**
* Class that operates the vibrator on the device.
* <p>
- * If your process exits, any vibration you started with will stop.
+ * If your process exits, any vibration you started will stop.
* </p>
*
* To obtain an instance of the system vibrator, call
- * {@link Context#getSystemService} with {@link Context#VIBRATOR_SERVICE} as argument.
+ * {@link Context#getSystemService} with {@link Context#VIBRATOR_SERVICE} as the argument.
*/
public abstract class Vibrator {
/**
diff --git a/core/java/android/preference/PreferenceActivity.java b/core/java/android/preference/PreferenceActivity.java
index 7ddfa87..2ab5a91 100644
--- a/core/java/android/preference/PreferenceActivity.java
+++ b/core/java/android/preference/PreferenceActivity.java
@@ -33,6 +33,7 @@ import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
import android.util.AttributeSet;
+import android.util.Log;
import android.util.TypedValue;
import android.util.Xml;
import android.view.LayoutInflater;
@@ -124,6 +125,8 @@ public abstract class PreferenceActivity extends ListActivity implements
PreferenceManager.OnPreferenceTreeClickListener,
PreferenceFragment.OnPreferenceStartFragmentCallback {
+ private static final String TAG = "PreferenceActivity";
+
// Constants for state save/restore
private static final String HEADERS_TAG = ":android:headers";
private static final String CUR_HEADER_TAG = ":android:cur_header";
@@ -521,9 +524,7 @@ public abstract class PreferenceActivity extends ListActivity implements
int initialTitle = getIntent().getIntExtra(EXTRA_SHOW_FRAGMENT_TITLE, 0);
int initialShortTitle = getIntent().getIntExtra(EXTRA_SHOW_FRAGMENT_SHORT_TITLE, 0);
- // Restore from headers only if they are supported which
- // is in multi-pane mode.
- if (savedInstanceState != null && !mSinglePane) {
+ if (savedInstanceState != null) {
// We are restarting from a previous saved state; used that to
// initialize, instead of starting fresh.
ArrayList<Header> headers = savedInstanceState.getParcelableArrayList(HEADERS_TAG);
diff --git a/core/java/android/print/PrinterCapabilitiesInfo.java b/core/java/android/print/PrinterCapabilitiesInfo.java
index b615600..806a89d 100644
--- a/core/java/android/print/PrinterCapabilitiesInfo.java
+++ b/core/java/android/print/PrinterCapabilitiesInfo.java
@@ -475,6 +475,12 @@ public final class PrinterCapabilitiesInfo implements Parcelable {
* @param colorModes The color mode bit mask.
* @param defaultColorMode The default color mode.
* @return This builder.
+ * <p>
+ * <strong>Note:</strong> On platform version 19 (Kitkat) specifying
+ * only PrintAttributes#COLOR_MODE_MONOCHROME leads to a print spooler
+ * crash. Hence, you should declare either both color modes or
+ * PrintAttributes#COLOR_MODE_COLOR.
+ * </p>
*
* @throws IllegalArgumentException If color modes contains an invalid
* mode bit or if the default color mode is invalid.
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index b16df28..0863368 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -18,6 +18,7 @@ package android.provider;
import android.accounts.Account;
import android.app.Activity;
+import android.content.ActivityNotFoundException;
import android.content.ContentProviderClient;
import android.content.ContentProviderOperation;
import android.content.ContentResolver;
@@ -40,6 +41,7 @@ import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Pair;
import android.view.View;
+import android.widget.Toast;
import java.io.ByteArrayInputStream;
import java.io.IOException;
@@ -7981,7 +7983,7 @@ public final class ContactsContract {
// Trigger with obtained rectangle
Intent intent = composeQuickContactsIntent(context, target, lookupUri, mode,
excludeMimes);
- context.startActivity(intent);
+ startActivityWithErrorToast(context, intent);
}
/**
@@ -8014,7 +8016,16 @@ public final class ContactsContract {
String[] excludeMimes) {
Intent intent = composeQuickContactsIntent(context, target, lookupUri, mode,
excludeMimes);
- context.startActivity(intent);
+ startActivityWithErrorToast(context, intent);
+ }
+
+ private static void startActivityWithErrorToast(Context context, Intent intent) {
+ try {
+ context.startActivity(intent);
+ } catch (ActivityNotFoundException e) {
+ Toast.makeText(context, com.android.internal.R.string.quick_contacts_not_available,
+ Toast.LENGTH_SHORT).show();
+ }
}
}
diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java
index 39775b6..6519f7e 100644
--- a/core/java/android/provider/DocumentsContract.java
+++ b/core/java/android/provider/DocumentsContract.java
@@ -257,8 +257,6 @@ public final class DocumentsContract {
* {@link #MIME_TYPE_DIR}.
*
* @see #COLUMN_FLAGS
- * @see DocumentsContract#createDocument(ContentResolver, Uri, String,
- * String)
* @see DocumentsProvider#createDocument(String, String, String)
*/
public static final int FLAG_DIR_SUPPORTS_CREATE = 1 << 3;
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 04f3f0a..3810eb3 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -5140,6 +5140,12 @@ public final class Settings {
public static final String SMS_SHORT_CODE_RULE = "sms_short_code_rule";
/**
+ * Used to select TCP's default initial receiver window size in segments - defaults to a build config value
+ * @hide
+ */
+ public static final String TCP_DEFAULT_INIT_RWND = "tcp_default_init_rwnd";
+
+ /**
* Used to disable Tethering on a device - defaults to true
* @hide
*/
diff --git a/core/java/android/text/format/Time.java b/core/java/android/text/format/Time.java
index 5ef86b1..f34e746 100644
--- a/core/java/android/text/format/Time.java
+++ b/core/java/android/text/format/Time.java
@@ -512,7 +512,7 @@ public class Time {
* <pre>
* Time time = new Time();
* time.set(4, 10, 2007); // set the date to Nov 4, 2007, 12am
- * time.normalize(); // this sets isDst = 1
+ * time.normalize(false); // this sets isDst = 1
* time.monthDay += 1; // changes the date to Nov 5, 2007, 12am
* millis = time.toMillis(false); // millis is Nov 4, 2007, 11pm
* millis = time.toMillis(true); // millis is Nov 5, 2007, 12am
diff --git a/core/java/android/util/LongSparseArray.java b/core/java/android/util/LongSparseArray.java
index d6e116f..dab853a 100644
--- a/core/java/android/util/LongSparseArray.java
+++ b/core/java/android/util/LongSparseArray.java
@@ -44,7 +44,7 @@ import com.android.internal.util.ArrayUtils;
* {@link #keyAt(int)} and {@link #valueAt(int)}. Iterating over the keys using
* <code>keyAt(int)</code> with ascending values of the index will return the
* keys in ascending order, or the values corresponding to the keys in ascending
- * order in the case of <code>valueAt(int)<code>.</p>
+ * order in the case of <code>valueAt(int)</code>.</p>
*/
public class LongSparseArray<E> implements Cloneable {
private static final Object DELETED = new Object();
diff --git a/core/java/android/util/LongSparseLongArray.java b/core/java/android/util/LongSparseLongArray.java
index 87d868b..6654899 100644
--- a/core/java/android/util/LongSparseLongArray.java
+++ b/core/java/android/util/LongSparseLongArray.java
@@ -39,7 +39,7 @@ import java.util.Arrays;
* {@link #keyAt(int)} and {@link #valueAt(int)}. Iterating over the keys using
* <code>keyAt(int)</code> with ascending values of the index will return the
* keys in ascending order, or the values corresponding to the keys in ascending
- * order in the case of <code>valueAt(int)<code>.</p>
+ * order in the case of <code>valueAt(int)</code>.</p>
*
* @hide
*/
diff --git a/core/java/android/util/SparseArray.java b/core/java/android/util/SparseArray.java
index 6e168a8..46d9d45 100644
--- a/core/java/android/util/SparseArray.java
+++ b/core/java/android/util/SparseArray.java
@@ -44,7 +44,7 @@ import com.android.internal.util.ArrayUtils;
* {@link #keyAt(int)} and {@link #valueAt(int)}. Iterating over the keys using
* <code>keyAt(int)</code> with ascending values of the index will return the
* keys in ascending order, or the values corresponding to the keys in ascending
- * order in the case of <code>valueAt(int)<code>.</p>
+ * order in the case of <code>valueAt(int)</code>.</p>
*/
public class SparseArray<E> implements Cloneable {
private static final Object DELETED = new Object();
diff --git a/core/java/android/util/SparseBooleanArray.java b/core/java/android/util/SparseBooleanArray.java
index 68487e3..905dcb0 100644
--- a/core/java/android/util/SparseBooleanArray.java
+++ b/core/java/android/util/SparseBooleanArray.java
@@ -38,7 +38,7 @@ import com.android.internal.util.ArrayUtils;
* {@link #keyAt(int)} and {@link #valueAt(int)}. Iterating over the keys using
* <code>keyAt(int)</code> with ascending values of the index will return the
* keys in ascending order, or the values corresponding to the keys in ascending
- * order in the case of <code>valueAt(int)<code>.</p>
+ * order in the case of <code>valueAt(int)</code>.</p>
*/
public class SparseBooleanArray implements Cloneable {
/**
diff --git a/core/java/android/util/SparseIntArray.java b/core/java/android/util/SparseIntArray.java
index 0835cb0..4f5ca07 100644
--- a/core/java/android/util/SparseIntArray.java
+++ b/core/java/android/util/SparseIntArray.java
@@ -37,7 +37,7 @@ import com.android.internal.util.ArrayUtils;
* {@link #keyAt(int)} and {@link #valueAt(int)}. Iterating over the keys using
* <code>keyAt(int)</code> with ascending values of the index will return the
* keys in ascending order, or the values corresponding to the keys in ascending
- * order in the case of <code>valueAt(int)<code>.</p>
+ * order in the case of <code>valueAt(int)</code>.</p>
*/
public class SparseIntArray implements Cloneable {
private int[] mKeys;
diff --git a/core/java/android/util/SparseLongArray.java b/core/java/android/util/SparseLongArray.java
index 62c1c0d..39fc8a3 100644
--- a/core/java/android/util/SparseLongArray.java
+++ b/core/java/android/util/SparseLongArray.java
@@ -37,7 +37,7 @@ import com.android.internal.util.ArrayUtils;
* {@link #keyAt(int)} and {@link #valueAt(int)}. Iterating over the keys using
* <code>keyAt(int)</code> with ascending values of the index will return the
* keys in ascending order, or the values corresponding to the keys in ascending
- * order in the case of <code>valueAt(int)<code>.</p>
+ * order in the case of <code>valueAt(int)</code>.</p>
*/
public class SparseLongArray implements Cloneable {
private int[] mKeys;
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index bdf4141..ef60755 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -6543,7 +6543,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @attr ref android.R.styleable#View_filterTouchesWhenObscured
*/
public void setFilterTouchesWhenObscured(boolean enabled) {
- setFlags(enabled ? 0 : FILTER_TOUCHES_WHEN_OBSCURED,
+ setFlags(enabled ? FILTER_TOUCHES_WHEN_OBSCURED : 0,
FILTER_TOUCHES_WHEN_OBSCURED);
}
diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java
index c3f064f..e67659c 100644
--- a/core/java/android/view/ViewConfiguration.java
+++ b/core/java/android/view/ViewConfiguration.java
@@ -212,6 +212,14 @@ public class ViewConfiguration {
*/
private static final int OVERFLING_DISTANCE = 6;
+ /**
+ * Configuration values for overriding {@link #hasPermanentMenuKey()} behavior.
+ * These constants must match the definition in res/values/config.xml.
+ */
+ private static final int HAS_PERMANENT_MENU_KEY_AUTODETECT = 0;
+ private static final int HAS_PERMANENT_MENU_KEY_TRUE = 1;
+ private static final int HAS_PERMANENT_MENU_KEY_FALSE = 2;
+
private final int mEdgeSlop;
private final int mFadingEdgeLength;
private final int mMinimumFlingVelocity;
@@ -296,12 +304,31 @@ public class ViewConfiguration {
mOverflingDistance = (int) (sizeAndDensity * OVERFLING_DISTANCE + 0.5f);
if (!sHasPermanentMenuKeySet) {
- IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
- try {
- sHasPermanentMenuKey = !wm.hasNavigationBar();
- sHasPermanentMenuKeySet = true;
- } catch (RemoteException ex) {
- sHasPermanentMenuKey = false;
+ final int configVal = res.getInteger(
+ com.android.internal.R.integer.config_overrideHasPermanentMenuKey);
+
+ switch (configVal) {
+ default:
+ case HAS_PERMANENT_MENU_KEY_AUTODETECT: {
+ IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
+ try {
+ sHasPermanentMenuKey = !wm.hasNavigationBar();
+ sHasPermanentMenuKeySet = true;
+ } catch (RemoteException ex) {
+ sHasPermanentMenuKey = false;
+ }
+ }
+ break;
+
+ case HAS_PERMANENT_MENU_KEY_TRUE:
+ sHasPermanentMenuKey = true;
+ sHasPermanentMenuKeySet = true;
+ break;
+
+ case HAS_PERMANENT_MENU_KEY_FALSE:
+ sHasPermanentMenuKey = false;
+ sHasPermanentMenuKeySet = true;
+ break;
}
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 0f633a0..5b2a452 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -232,8 +232,6 @@ public final class ViewRootImpl implements ViewParent,
InputStage mFirstInputStage;
InputStage mFirstPostImeInputStage;
- boolean mFlipControllerFallbackKeys;
-
boolean mWindowAttributesChanged = false;
int mWindowAttributesChangesFlag = 0;
@@ -370,8 +368,6 @@ public final class ViewRootImpl implements ViewParent,
mNoncompatDensity = context.getResources().getDisplayMetrics().noncompatDensityDpi;
mFallbackEventHandler = PolicyManager.makeNewFallbackEventHandler(context);
mChoreographer = Choreographer.getInstance();
- mFlipControllerFallbackKeys =
- context.getResources().getBoolean(R.bool.flip_controller_fallback_keys);
PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
mAttachInfo.mScreenOn = powerManager.isScreenOn();
@@ -674,11 +670,6 @@ public final class ViewRootImpl implements ViewParent,
}
}
- public boolean invokeFunctor(long functor, boolean waitForCompletion) {
- // stub
- return false;
- }
-
private void enableHardwareAcceleration(WindowManager.LayoutParams attrs) {
mAttachInfo.mHardwareAccelerated = false;
mAttachInfo.mHardwareAccelerationRequested = false;
@@ -2917,11 +2908,8 @@ public final class ViewRootImpl implements ViewParent,
mView.dispatchConfigurationChanged(config);
}
}
-
- mFlipControllerFallbackKeys =
- mContext.getResources().getBoolean(R.bool.flip_controller_fallback_keys);
}
-
+
/**
* Return true if child is an ancestor of parent, (or equal to the parent).
*/
@@ -3990,7 +3978,6 @@ public final class ViewRootImpl implements ViewParent,
private final SyntheticJoystickHandler mJoystick = new SyntheticJoystickHandler();
private final SyntheticTouchNavigationHandler mTouchNavigation =
new SyntheticTouchNavigationHandler();
- private final SyntheticKeyHandler mKeys = new SyntheticKeyHandler();
public SyntheticInputStage() {
super(null);
@@ -4013,12 +4000,7 @@ public final class ViewRootImpl implements ViewParent,
mTouchNavigation.process(event);
return FINISH_HANDLED;
}
- } else if (q.mEvent instanceof KeyEvent) {
- if (mKeys.process((KeyEvent) q.mEvent)) {
- return FINISH_HANDLED;
- }
}
-
return FORWARD;
}
@@ -4848,63 +4830,6 @@ public final class ViewRootImpl implements ViewParent,
};
}
- final class SyntheticKeyHandler {
-
- public boolean process(KeyEvent event) {
- // In some locales (like Japan) controllers use B for confirm and A for back, rather
- // than vice versa, so we need to special case this here since the input system itself
- // is not locale-aware.
- int keyCode;
- switch(event.getKeyCode()) {
- case KeyEvent.KEYCODE_BUTTON_A:
- case KeyEvent.KEYCODE_BUTTON_C:
- case KeyEvent.KEYCODE_BUTTON_X:
- case KeyEvent.KEYCODE_BUTTON_Z:
- keyCode = mFlipControllerFallbackKeys ?
- KeyEvent.KEYCODE_BACK : KeyEvent.KEYCODE_DPAD_CENTER;
- break;
- case KeyEvent.KEYCODE_BUTTON_B:
- case KeyEvent.KEYCODE_BUTTON_Y:
- keyCode = mFlipControllerFallbackKeys ?
- KeyEvent.KEYCODE_DPAD_CENTER : KeyEvent.KEYCODE_BACK;
- break;
- case KeyEvent.KEYCODE_BUTTON_THUMBL:
- case KeyEvent.KEYCODE_BUTTON_THUMBR:
- case KeyEvent.KEYCODE_BUTTON_START:
- case KeyEvent.KEYCODE_BUTTON_1:
- case KeyEvent.KEYCODE_BUTTON_2:
- case KeyEvent.KEYCODE_BUTTON_3:
- case KeyEvent.KEYCODE_BUTTON_4:
- case KeyEvent.KEYCODE_BUTTON_5:
- case KeyEvent.KEYCODE_BUTTON_6:
- case KeyEvent.KEYCODE_BUTTON_7:
- case KeyEvent.KEYCODE_BUTTON_8:
- case KeyEvent.KEYCODE_BUTTON_9:
- case KeyEvent.KEYCODE_BUTTON_10:
- case KeyEvent.KEYCODE_BUTTON_11:
- case KeyEvent.KEYCODE_BUTTON_12:
- case KeyEvent.KEYCODE_BUTTON_13:
- case KeyEvent.KEYCODE_BUTTON_14:
- case KeyEvent.KEYCODE_BUTTON_15:
- case KeyEvent.KEYCODE_BUTTON_16:
- keyCode = KeyEvent.KEYCODE_DPAD_CENTER;
- break;
- case KeyEvent.KEYCODE_BUTTON_SELECT:
- case KeyEvent.KEYCODE_BUTTON_MODE:
- keyCode = KeyEvent.KEYCODE_MENU;
- default:
- return false;
- }
-
- enqueueInputEvent(new KeyEvent(event.getDownTime(), event.getEventTime(),
- event.getAction(), keyCode, event.getRepeatCount(), event.getMetaState(),
- event.getDeviceId(), event.getScanCode(),
- event.getFlags() | KeyEvent.FLAG_FALLBACK, event.getSource()));
- return true;
- }
-
- }
-
/**
* Returns true if the key is used for keyboard navigation.
* @param keyEvent The key event.
diff --git a/core/java/android/view/VolumePanel.java b/core/java/android/view/VolumePanel.java
index f0e6677..52f9c0b 100644
--- a/core/java/android/view/VolumePanel.java
+++ b/core/java/android/view/VolumePanel.java
@@ -311,7 +311,6 @@ public class VolumePanel extends Handler implements OnSeekBarChangeListener, Vie
lp.type = LayoutParams.TYPE_VOLUME_OVERLAY;
lp.width = LayoutParams.WRAP_CONTENT;
lp.height = LayoutParams.WRAP_CONTENT;
- lp.privateFlags |= LayoutParams.PRIVATE_FLAG_FORCE_SHOW_NAV_BAR;
window.setAttributes(lp);
window.addFlags(LayoutParams.FLAG_NOT_FOCUSABLE | LayoutParams.FLAG_NOT_TOUCH_MODAL
| LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 0ce4da5..53a4c0d0 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -1063,13 +1063,6 @@ public interface WindowManager extends ViewManager {
public static final int PRIVATE_FLAG_SHOW_FOR_ALL_USERS = 0x00000010;
/**
- * Special flag for the volume overlay: force the window manager out of "hide nav bar"
- * mode while the window is on screen.
- *
- * {@hide} */
- public static final int PRIVATE_FLAG_FORCE_SHOW_NAV_BAR = 0x00000020;
-
- /**
* Never animate position changes of the window.
*
* {@hide} */
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 5bc39f1..d53bb74 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -686,6 +686,15 @@ public class WebView extends AbsoluteLayout
}
/**
+ * Used only by internal tests to free up memory.
+ *
+ * @hide
+ */
+ public static void freeMemoryForTests() {
+ getFactory().getStatics().freeMemoryForTests();
+ }
+
+ /**
* Informs WebView of the network state. This is used to set
* the JavaScript property window.navigator.isOnline and
* generates the online/offline event as specified in HTML5, sec. 5.7.7
diff --git a/core/java/android/webkit/WebViewFactoryProvider.java b/core/java/android/webkit/WebViewFactoryProvider.java
index 9d9d882..e391aaf 100644
--- a/core/java/android/webkit/WebViewFactoryProvider.java
+++ b/core/java/android/webkit/WebViewFactoryProvider.java
@@ -50,6 +50,11 @@ public interface WebViewFactoryProvider {
String getDefaultUserAgent(Context context);
/**
+ * Used for tests only.
+ */
+ void freeMemoryForTests();
+
+ /**
* Implements the API method:
* {@link android.webkit.WebView#setWebContentsDebuggingEnabled(boolean) }
*/
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 092f474..25a43a6 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -723,7 +723,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
*
* @param view The view whose scroll state is being reported
*
- * @param scrollState The current scroll state. One of {@link #SCROLL_STATE_IDLE},
+ * @param scrollState The current scroll state. One of
* {@link #SCROLL_STATE_TOUCH_SCROLL} or {@link #SCROLL_STATE_IDLE}.
*/
public void onScrollStateChanged(AbsListView view, int scrollState);
@@ -2076,22 +2076,23 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
mInLayout = true;
+ final int childCount = getChildCount();
if (changed) {
- int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
getChildAt(i).forceLayout();
}
mRecycler.markChildrenDirty();
}
- if (mFastScroller != null && (mItemCount != mOldItemCount || mDataChanged)) {
- mFastScroller.onItemCountChanged(mItemCount);
- }
-
layoutChildren();
mInLayout = false;
mOverscrollMax = (b - t) / OVERSCROLL_LIMIT_DIVISOR;
+
+ // TODO: Move somewhere sane. This doesn't belong in onLayout().
+ if (mFastScroller != null) {
+ mFastScroller.onItemCountChanged(getChildCount(), mItemCount);
+ }
}
/**
@@ -2228,26 +2229,34 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
Trace.traceBegin(Trace.TRACE_TAG_VIEW, "obtainView");
isScrap[0] = false;
- View scrapView;
- scrapView = mRecycler.getTransientStateView(position);
- if (scrapView == null) {
- scrapView = mRecycler.getScrapView(position);
- }
+ // Check whether we have a transient state view. Attempt to re-bind the
+ // data and discard the view if we fail.
+ final View transientView = mRecycler.getTransientStateView(position);
+ if (transientView != null) {
+ final LayoutParams params = (LayoutParams) transientView.getLayoutParams();
- View child;
- if (scrapView != null) {
- child = mAdapter.getView(position, scrapView, this);
+ // If the view type hasn't changed, attempt to re-bind the data.
+ if (params.viewType == mAdapter.getItemViewType(position)) {
+ final View updatedView = mAdapter.getView(position, transientView, this);
- if (child.getImportantForAccessibility() == IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
- child.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
+ // If we failed to re-bind the data, scrap the obtained view.
+ if (updatedView != transientView) {
+ mRecycler.addScrapView(updatedView, position);
+ }
}
+ // Scrap view implies temporary detachment.
+ isScrap[0] = true;
+ return transientView;
+ }
+
+ final View scrapView = mRecycler.getScrapView(position);
+ final View child = mAdapter.getView(position, scrapView, this);
+ if (scrapView != null) {
if (child != scrapView) {
+ // Failed to re-bind the data, return scrap to the heap.
mRecycler.addScrapView(scrapView, position);
- if (mCacheColorHint != 0) {
- child.setDrawingCacheBackgroundColor(mCacheColorHint);
- }
} else {
isScrap[0] = true;
@@ -2259,16 +2268,14 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
child.dispatchFinishTemporaryDetach();
}
- } else {
- child = mAdapter.getView(position, null, this);
+ }
- if (child.getImportantForAccessibility() == IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
- child.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
- }
+ if (mCacheColorHint != 0) {
+ child.setDrawingCacheBackgroundColor(mCacheColorHint);
+ }
- if (mCacheColorHint != 0) {
- child.setDrawingCacheBackgroundColor(mCacheColorHint);
- }
+ if (child.getImportantForAccessibility() == IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
+ child.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
}
if (mAdapterHasStableIds) {
@@ -6562,12 +6569,8 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
}
}
}
- if (mTransientStateViews != null) {
- mTransientStateViews.clear();
- }
- if (mTransientStateViewsById != null) {
- mTransientStateViewsById.clear();
- }
+
+ clearTransientStateViews();
}
/**
@@ -6634,14 +6637,26 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
}
/**
- * Dump any currently saved views with transient state.
+ * Dumps and fully detaches any currently saved views with transient
+ * state.
*/
void clearTransientStateViews() {
- if (mTransientStateViews != null) {
- mTransientStateViews.clear();
+ final SparseArray<View> viewsByPos = mTransientStateViews;
+ if (viewsByPos != null) {
+ final int N = viewsByPos.size();
+ for (int i = 0; i < N; i++) {
+ removeDetachedView(viewsByPos.valueAt(i), false);
+ }
+ viewsByPos.clear();
}
- if (mTransientStateViewsById != null) {
- mTransientStateViewsById.clear();
+
+ final LongSparseArray<View> viewsById = mTransientStateViewsById;
+ if (viewsById != null) {
+ final int N = viewsById.size();
+ for (int i = 0; i < N; i++) {
+ removeDetachedView(viewsById.valueAt(i), false);
+ }
+ viewsById.clear();
}
}
@@ -6766,44 +6781,48 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
if (victim != null) {
final AbsListView.LayoutParams lp
= (AbsListView.LayoutParams) victim.getLayoutParams();
- int whichScrap = lp.viewType;
+ final int whichScrap = lp.viewType;
activeViews[i] = null;
- final boolean scrapHasTransientState = victim.hasTransientState();
- if (!shouldRecycleViewType(whichScrap) || scrapHasTransientState) {
- // Do not move views that should be ignored
- if (whichScrap != ITEM_VIEW_TYPE_HEADER_OR_FOOTER &&
- scrapHasTransientState) {
+ if (victim.hasTransientState()) {
+ // Store views with transient state for later use.
+ victim.dispatchStartTemporaryDetach();
+
+ if (mAdapter != null && mAdapterHasStableIds) {
+ if (mTransientStateViewsById == null) {
+ mTransientStateViewsById = new LongSparseArray<View>();
+ }
+ long id = mAdapter.getItemId(mFirstActivePosition + i);
+ mTransientStateViewsById.put(id, victim);
+ } else if (!mDataChanged) {
+ if (mTransientStateViews == null) {
+ mTransientStateViews = new SparseArray<View>();
+ }
+ mTransientStateViews.put(mFirstActivePosition + i, victim);
+ } else if (whichScrap != ITEM_VIEW_TYPE_HEADER_OR_FOOTER) {
+ // The data has changed, we can't keep this view.
removeDetachedView(victim, false);
}
- if (scrapHasTransientState) {
- if (mAdapter != null && mAdapterHasStableIds) {
- if (mTransientStateViewsById == null) {
- mTransientStateViewsById = new LongSparseArray<View>();
- }
- long id = mAdapter.getItemId(mFirstActivePosition + i);
- mTransientStateViewsById.put(id, victim);
- } else {
- if (mTransientStateViews == null) {
- mTransientStateViews = new SparseArray<View>();
- }
- mTransientStateViews.put(mFirstActivePosition + i, victim);
- }
+ } else if (!shouldRecycleViewType(whichScrap)) {
+ // Discard non-recyclable views except headers/footers.
+ if (whichScrap != ITEM_VIEW_TYPE_HEADER_OR_FOOTER) {
+ removeDetachedView(victim, false);
+ }
+ } else {
+ // Store everything else on the appropriate scrap heap.
+ if (multipleScraps) {
+ scrapViews = mScrapViews[whichScrap];
}
- continue;
- }
- if (multipleScraps) {
- scrapViews = mScrapViews[whichScrap];
- }
- victim.dispatchStartTemporaryDetach();
- lp.scrappedFromPosition = mFirstActivePosition + i;
- scrapViews.add(victim);
+ victim.dispatchStartTemporaryDetach();
+ lp.scrappedFromPosition = mFirstActivePosition + i;
+ scrapViews.add(victim);
- victim.setAccessibilityDelegate(null);
- if (hasListener) {
- mRecyclerListener.onMovedToScrapHeap(victim);
+ victim.setAccessibilityDelegate(null);
+ if (hasListener) {
+ mRecyclerListener.onMovedToScrapHeap(victim);
+ }
}
}
}
@@ -6812,8 +6831,10 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
}
/**
- * Makes sure that the size of mScrapViews does not exceed the size of mActiveViews.
- * (This can happen if an adapter does not recycle its views).
+ * Makes sure that the size of mScrapViews does not exceed the size of
+ * mActiveViews, which can happen if an adapter does not recycle its
+ * views. Removes cached transient state views that no longer have
+ * transient state.
*/
private void pruneScrapViews() {
final int maxViews = mActiveViews.length;
@@ -6829,20 +6850,25 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
}
}
- if (mTransientStateViews != null) {
- for (int i = 0; i < mTransientStateViews.size(); i++) {
- final View v = mTransientStateViews.valueAt(i);
+ final SparseArray<View> transViewsByPos = mTransientStateViews;
+ if (transViewsByPos != null) {
+ for (int i = 0; i < transViewsByPos.size(); i++) {
+ final View v = transViewsByPos.valueAt(i);
if (!v.hasTransientState()) {
- mTransientStateViews.removeAt(i);
+ removeDetachedView(v, false);
+ transViewsByPos.removeAt(i);
i--;
}
}
}
- if (mTransientStateViewsById != null) {
- for (int i = 0; i < mTransientStateViewsById.size(); i++) {
- final View v = mTransientStateViewsById.valueAt(i);
+
+ final LongSparseArray<View> transViewsById = mTransientStateViewsById;
+ if (transViewsById != null) {
+ for (int i = 0; i < transViewsById.size(); i++) {
+ final View v = transViewsById.valueAt(i);
if (!v.hasTransientState()) {
- mTransientStateViewsById.removeAt(i);
+ removeDetachedView(v, false);
+ transViewsById.removeAt(i);
i--;
}
}
diff --git a/core/java/android/widget/CalendarView.java b/core/java/android/widget/CalendarView.java
index 0957ab4..e90b460 100644
--- a/core/java/android/widget/CalendarView.java
+++ b/core/java/android/widget/CalendarView.java
@@ -1210,35 +1210,38 @@ public class CalendarView extends FrameLayout {
child = (WeekView) view.getChildAt(offset);
}
- // Find out which month we're moving into
- int month;
- if (mIsScrollingUp) {
- month = child.getMonthOfFirstWeekDay();
- } else {
- month = child.getMonthOfLastWeekDay();
- }
-
- // And how it relates to our current highlighted month
- int monthDiff;
- if (mCurrentMonthDisplayed == 11 && month == 0) {
- monthDiff = 1;
- } else if (mCurrentMonthDisplayed == 0 && month == 11) {
- monthDiff = -1;
- } else {
- monthDiff = month - mCurrentMonthDisplayed;
- }
-
- // Only switch months if we're scrolling away from the currently
- // selected month
- if ((!mIsScrollingUp && monthDiff > 0) || (mIsScrollingUp && monthDiff < 0)) {
- Calendar firstDay = child.getFirstDay();
+ if (child != null) {
+ // Find out which month we're moving into
+ int month;
if (mIsScrollingUp) {
- firstDay.add(Calendar.DAY_OF_MONTH, -DAYS_PER_WEEK);
+ month = child.getMonthOfFirstWeekDay();
} else {
- firstDay.add(Calendar.DAY_OF_MONTH, DAYS_PER_WEEK);
+ month = child.getMonthOfLastWeekDay();
+ }
+
+ // And how it relates to our current highlighted month
+ int monthDiff;
+ if (mCurrentMonthDisplayed == 11 && month == 0) {
+ monthDiff = 1;
+ } else if (mCurrentMonthDisplayed == 0 && month == 11) {
+ monthDiff = -1;
+ } else {
+ monthDiff = month - mCurrentMonthDisplayed;
+ }
+
+ // Only switch months if we're scrolling away from the currently
+ // selected month
+ if ((!mIsScrollingUp && monthDiff > 0) || (mIsScrollingUp && monthDiff < 0)) {
+ Calendar firstDay = child.getFirstDay();
+ if (mIsScrollingUp) {
+ firstDay.add(Calendar.DAY_OF_MONTH, -DAYS_PER_WEEK);
+ } else {
+ firstDay.add(Calendar.DAY_OF_MONTH, DAYS_PER_WEEK);
+ }
+ setMonthDisplayed(firstDay);
}
- setMonthDisplayed(firstDay);
}
+
mPreviousScrollPosition = currScroll;
mPreviousScrollState = mCurrentScrollState;
}
diff --git a/core/java/android/widget/FastScroller.java b/core/java/android/widget/FastScroller.java
index 01ac8fd..4379bf6 100644
--- a/core/java/android/widget/FastScroller.java
+++ b/core/java/android/widget/FastScroller.java
@@ -224,6 +224,8 @@ class FastScroller {
mHasPendingDrag = false;
}
};
+ private int mOldItemCount;
+ private int mOldChildCount;
/**
* Used to delay hiding fast scroll decorations.
@@ -248,6 +250,8 @@ class FastScroller {
public FastScroller(AbsListView listView) {
mList = listView;
mOverlay = listView.getOverlay();
+ mOldItemCount = listView.getCount();
+ mOldChildCount = listView.getChildCount();
final Context context = listView.getContext();
mScaledTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
@@ -258,6 +262,7 @@ class FastScroller {
final ImageView trackImage = new ImageView(context);
mTrackImage = trackImage;
+ updateLongList(mOldChildCount, mOldItemCount);
int width = 0;
// Add track to overlay if it has an image.
@@ -445,20 +450,23 @@ class FastScroller {
updateLayout();
}
- public void onItemCountChanged(int totalItemCount) {
- final int visibleItemCount = mList.getChildCount();
- final boolean hasMoreItems = totalItemCount - visibleItemCount > 0;
- if (hasMoreItems && mState != STATE_DRAGGING) {
- final int firstVisibleItem = mList.getFirstVisiblePosition();
- setThumbPos(getPosFromItemCount(firstVisibleItem, visibleItemCount, totalItemCount));
- }
+ public void onItemCountChanged(int childCount, int itemCount) {
+ if (mOldItemCount != itemCount || mOldChildCount != childCount) {
+ mOldItemCount = itemCount;
+ mOldChildCount = childCount;
- updateLongList(visibleItemCount, totalItemCount);
+ final boolean hasMoreItems = itemCount - childCount > 0;
+ if (hasMoreItems && mState != STATE_DRAGGING) {
+ final int firstVisibleItem = mList.getFirstVisiblePosition();
+ setThumbPos(getPosFromItemCount(firstVisibleItem, childCount, itemCount));
+ }
+
+ updateLongList(childCount, itemCount);
+ }
}
- private void updateLongList(int visibleItemCount, int totalItemCount) {
- final boolean longList = visibleItemCount > 0
- && totalItemCount / visibleItemCount >= MIN_PAGES;
+ private void updateLongList(int childCount, int itemCount) {
+ final boolean longList = childCount > 0 && itemCount / childCount >= MIN_PAGES;
if (mLongList != longList) {
mLongList = longList;
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
index 7daf798..f05179b 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -563,7 +563,7 @@ public class ImageView extends View {
}
/** Return the view's optional matrix. This is applied to the
- view's drawable when it is drawn. If there is not matrix,
+ view's drawable when it is drawn. If there is no matrix,
this method will return an identity matrix.
Do not change this matrix in place but make a copy.
If you want a different matrix applied to the drawable,
diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java
index 5663959..be20d2d 100644
--- a/core/java/android/widget/PopupWindow.java
+++ b/core/java/android/widget/PopupWindow.java
@@ -1330,7 +1330,7 @@ public class PopupWindow {
/**
* Updates the state of the popup window, if it is currently being displayed,
- * from the currently set state. This include:
+ * from the currently set state. This includes:
* {@link #setClippingEnabled(boolean)}, {@link #setFocusable(boolean)},
* {@link #setIgnoreCheekPress()}, {@link #setInputMethodMode(int)},
* {@link #setTouchable(boolean)}, and {@link #setAnimationStyle(int)}.
diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java
index 5392a96..6a369a6 100644
--- a/core/java/android/widget/ProgressBar.java
+++ b/core/java/android/widget/ProgressBar.java
@@ -308,6 +308,11 @@ public class ProgressBar extends View {
mMirrorForRtl = a.getBoolean(R.styleable.ProgressBar_mirrorForRtl, mMirrorForRtl);
a.recycle();
+
+ // If not explicitly specified this view is important for accessibility.
+ if (getImportantForAccessibility() == View.IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
+ setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
+ }
}
/**
diff --git a/core/java/android/widget/ShareActionProvider.java b/core/java/android/widget/ShareActionProvider.java
index 62afd2e..bdaaa01 100644
--- a/core/java/android/widget/ShareActionProvider.java
+++ b/core/java/android/widget/ShareActionProvider.java
@@ -266,7 +266,7 @@ public class ShareActionProvider extends ActionProvider {
* Intent shareIntent = new Intent(Intent.ACTION_SEND);
* shareIntent.setType("image/*");
* Uri uri = Uri.fromFile(new File(getFilesDir(), "foo.jpg"));
- * shareIntent.putExtra(Intent.EXTRA_STREAM, uri.toString());</pre>
+ * shareIntent.putExtra(Intent.EXTRA_STREAM, uri));</pre>
*
* @param shareIntent The share intent.
*
diff --git a/core/java/android/widget/SpellChecker.java b/core/java/android/widget/SpellChecker.java
index b204dfd..1cda631 100644
--- a/core/java/android/widget/SpellChecker.java
+++ b/core/java/android/widget/SpellChecker.java
@@ -731,10 +731,14 @@ public class SpellChecker implements SpellCheckerSessionListener {
}
}
- if (scheduleOtherSpellCheck) {
+ if (scheduleOtherSpellCheck && wordStart <= end) {
// Update range span: start new spell check from last wordStart
setRangeSpan(editable, wordStart, end);
} else {
+ if (DBG && scheduleOtherSpellCheck) {
+ Log.w(TAG, "Trying to schedule spellcheck for invalid region, from "
+ + wordStart + " to " + end);
+ }
removeRangeSpan(editable);
}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 3f35875..5ece016 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -8667,6 +8667,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
super.onRtlPropertiesChanged(layoutDirection);
mTextDir = getTextDirectionHeuristic();
+
+ if (mLayout != null) {
+ checkForRelayout();
+ }
}
TextDirectionHeuristic getTextDirectionHeuristic() {
diff --git a/core/java/com/android/internal/app/ProcessStats.java b/core/java/com/android/internal/app/ProcessStats.java
index a87992a..a13a1cb 100644
--- a/core/java/com/android/internal/app/ProcessStats.java
+++ b/core/java/com/android/internal/app/ProcessStats.java
@@ -1004,7 +1004,7 @@ public final class ProcessStats implements Parcelable {
for (int iproc=pkgState.mProcesses.size()-1; iproc>=0; iproc--) {
ProcessState ps = pkgState.mProcesses.valueAt(iproc);
if (ps.isInUse() || ps.mCommonProcess.isInUse()) {
- pkgState.mProcesses.valueAt(iproc).resetSafely(now);
+ ps.resetSafely(now);
} else {
pkgState.mProcesses.valueAt(iproc).makeDead();
pkgState.mProcesses.removeAt(iproc);
@@ -1013,7 +1013,7 @@ public final class ProcessStats implements Parcelable {
for (int isvc=pkgState.mServices.size()-1; isvc>=0; isvc--) {
ServiceState ss = pkgState.mServices.valueAt(isvc);
if (ss.isInUse()) {
- pkgState.mServices.valueAt(isvc).resetSafely(now);
+ ss.resetSafely(now);
} else {
pkgState.mServices.removeAt(isvc);
}
@@ -3014,7 +3014,7 @@ public final class ProcessStats implements Parcelable {
}
public boolean isInUse() {
- return mOwner != null;
+ return mOwner != null || mRestarting;
}
void add(ServiceState other) {
diff --git a/core/java/com/android/internal/content/PackageMonitor.java b/core/java/com/android/internal/content/PackageMonitor.java
index ab871fb..942995b 100644
--- a/core/java/com/android/internal/content/PackageMonitor.java
+++ b/core/java/com/android/internal/content/PackageMonitor.java
@@ -372,23 +372,25 @@ public abstract class PackageMonitor extends android.content.BroadcastReceiver {
} else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(action)) {
String[] pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
mAppearingPackages = pkgList;
- mChangeType = PACKAGE_TEMPORARY_CHANGE;
+ mChangeType = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)
+ ? PACKAGE_UPDATING : PACKAGE_TEMPORARY_CHANGE;
mSomePackagesChanged = true;
if (pkgList != null) {
onPackagesAvailable(pkgList);
for (int i=0; i<pkgList.length; i++) {
- onPackageAppeared(pkgList[i], PACKAGE_TEMPORARY_CHANGE);
+ onPackageAppeared(pkgList[i], mChangeType);
}
}
} else if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) {
String[] pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
mDisappearingPackages = pkgList;
- mChangeType = PACKAGE_TEMPORARY_CHANGE;
+ mChangeType = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)
+ ? PACKAGE_UPDATING : PACKAGE_TEMPORARY_CHANGE;
mSomePackagesChanged = true;
if (pkgList != null) {
onPackagesUnavailable(pkgList);
for (int i=0; i<pkgList.length; i++) {
- onPackageDisappeared(pkgList[i], PACKAGE_TEMPORARY_CHANGE);
+ onPackageDisappeared(pkgList[i], mChangeType);
}
}
}
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index bee1391..3ea749e 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -28,6 +28,7 @@ import android.os.Process;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.Trace;
+import android.system.ErrnoException;
import android.system.Os;
import android.system.OsConstants;
import android.util.EventLog;
@@ -192,10 +193,16 @@ public class ZygoteInit {
static void closeServerSocket() {
try {
if (sServerSocket != null) {
+ FileDescriptor fd = sServerSocket.getFileDescriptor();
sServerSocket.close();
+ if (fd != null) {
+ Os.close(fd);
+ }
}
} catch (IOException ex) {
Log.e(TAG, "Zygote: error closing sockets", ex);
+ } catch (ErrnoException ex) {
+ Log.e(TAG, "Zygote: error closing descriptor", ex);
}
sServerSocket = null;
@@ -238,9 +245,11 @@ public class ZygoteInit {
}
static void preload() {
+ Log.d(TAG, "begin preload");
preloadClasses();
preloadResources();
preloadOpenGL();
+ Log.d(TAG, "end preload");
}
private static void preloadOpenGL() {
diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl
index 12ced68..3724a08 100644
--- a/core/java/com/android/internal/view/IInputMethodManager.aidl
+++ b/core/java/com/android/internal/view/IInputMethodManager.aidl
@@ -73,5 +73,5 @@ interface IInputMethodManager {
boolean switchToNextInputMethod(in IBinder token, boolean onlyCurrentIme);
boolean shouldOfferSwitchingToNextInputMethod(in IBinder token);
boolean setInputMethodEnabled(String id, boolean enabled);
- oneway void setAdditionalInputMethodSubtypes(String id, in InputMethodSubtype[] subtypes);
+ void setAdditionalInputMethodSubtypes(String id, in InputMethodSubtype[] subtypes);
}
diff --git a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
index 4654178..fe1cf72 100644
--- a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
+++ b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
@@ -164,8 +164,24 @@ public class ActionMenuPresenter extends BaseMenuPresenter
}
actionView.setVisibility(item.isActionViewExpanded() ? View.GONE : View.VISIBLE);
+ final ActionMenuView menuParent = (ActionMenuView) parent;
+ final ViewGroup.LayoutParams lp = actionView.getLayoutParams();
+ if (!menuParent.checkLayoutParams(lp)) {
+ actionView.setLayoutParams(menuParent.generateLayoutParams(lp));
+ }
+ return actionView;
+ }
+
+ @Override
+ public void bindItemView(final MenuItemImpl item, MenuView.ItemView itemView) {
+ itemView.initialize(item, 0);
+
+ final ActionMenuView menuView = (ActionMenuView) mMenuView;
+ final ActionMenuItemView actionItemView = (ActionMenuItemView) itemView;
+ actionItemView.setItemInvoker(menuView);
+
if (item.hasSubMenu()) {
- actionView.setOnTouchListener(new ForwardingListener(actionView) {
+ actionItemView.setOnTouchListener(new ForwardingListener(actionItemView) {
@Override
public ListPopupWindow getPopup() {
return mActionButtonPopup != null ? mActionButtonPopup.getPopup() : null;
@@ -182,24 +198,8 @@ public class ActionMenuPresenter extends BaseMenuPresenter
}
});
} else {
- actionView.setOnTouchListener(null);
+ actionItemView.setOnTouchListener(null);
}
-
- final ActionMenuView menuParent = (ActionMenuView) parent;
- final ViewGroup.LayoutParams lp = actionView.getLayoutParams();
- if (!menuParent.checkLayoutParams(lp)) {
- actionView.setLayoutParams(menuParent.generateLayoutParams(lp));
- }
- return actionView;
- }
-
- @Override
- public void bindItemView(MenuItemImpl item, MenuView.ItemView itemView) {
- itemView.initialize(item, 0);
-
- final ActionMenuView menuView = (ActionMenuView) mMenuView;
- ActionMenuItemView actionItemView = (ActionMenuItemView) itemView;
- actionItemView.setItemInvoker(menuView);
}
@Override
diff --git a/core/java/com/android/internal/view/menu/ListMenuPresenter.java b/core/java/com/android/internal/view/menu/ListMenuPresenter.java
index 4882adc..e1bb3621 100644
--- a/core/java/com/android/internal/view/menu/ListMenuPresenter.java
+++ b/core/java/com/android/internal/view/menu/ListMenuPresenter.java
@@ -163,7 +163,7 @@ public class ListMenuPresenter implements MenuPresenter, AdapterView.OnItemClick
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
- mMenu.performItemAction(mAdapter.getItem(position), 0);
+ mMenu.performItemAction(mAdapter.getItem(position), this, 0);
}
@Override
diff --git a/core/java/com/android/internal/view/menu/MenuBuilder.java b/core/java/com/android/internal/view/menu/MenuBuilder.java
index aff697a..195a00d 100644
--- a/core/java/com/android/internal/view/menu/MenuBuilder.java
+++ b/core/java/com/android/internal/view/menu/MenuBuilder.java
@@ -247,11 +247,17 @@ public class MenuBuilder implements Menu {
startDispatchingItemsChanged();
}
- private boolean dispatchSubMenuSelected(SubMenuBuilder subMenu) {
+ private boolean dispatchSubMenuSelected(SubMenuBuilder subMenu,
+ MenuPresenter preferredPresenter) {
if (mPresenters.isEmpty()) return false;
boolean result = false;
+ // Try the preferred presenter first.
+ if (preferredPresenter != null) {
+ result = preferredPresenter.onSubMenuSelected(subMenu);
+ }
+
for (WeakReference<MenuPresenter> ref : mPresenters) {
final MenuPresenter presenter = ref.get();
if (presenter == null) {
@@ -865,6 +871,10 @@ public class MenuBuilder implements Menu {
}
public boolean performItemAction(MenuItem item, int flags) {
+ return performItemAction(item, null, flags);
+ }
+
+ public boolean performItemAction(MenuItem item, MenuPresenter preferredPresenter, int flags) {
MenuItemImpl itemImpl = (MenuItemImpl) item;
if (itemImpl == null || !itemImpl.isEnabled()) {
@@ -889,7 +899,7 @@ public class MenuBuilder implements Menu {
if (providerHasSubMenu) {
provider.onPrepareSubMenu(subMenu);
}
- invoked |= dispatchSubMenuSelected(subMenu);
+ invoked |= dispatchSubMenuSelected(subMenu, preferredPresenter);
if (!invoked) close(true);
} else {
if ((flags & FLAG_PERFORM_NO_CLOSE) == 0) {
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index 7143a8a..d97a945 100644
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -227,7 +227,7 @@ static void ToColor_SI8_Alpha(SkColor dst[], const void* src, int width,
do {
*dst++ = SkUnPreMultiply::PMColorToColor(colors[*s++]);
} while (--width != 0);
- ctable->unlockColors(false);
+ ctable->unlockColors();
}
static void ToColor_SI8_Raw(SkColor dst[], const void* src, int width,
@@ -240,7 +240,7 @@ static void ToColor_SI8_Raw(SkColor dst[], const void* src, int width,
*dst++ = SkColorSetARGB(SkGetPackedA32(c), SkGetPackedR32(c),
SkGetPackedG32(c), SkGetPackedB32(c));
} while (--width != 0);
- ctable->unlockColors(false);
+ ctable->unlockColors();
}
static void ToColor_SI8_Opaque(SkColor dst[], const void* src, int width,
@@ -253,7 +253,7 @@ static void ToColor_SI8_Opaque(SkColor dst[], const void* src, int width,
*dst++ = SkColorSetRGB(SkGetPackedR32(c), SkGetPackedG32(c),
SkGetPackedB32(c));
} while (--width != 0);
- ctable->unlockColors(false);
+ ctable->unlockColors();
}
// can return NULL
@@ -456,10 +456,16 @@ static jboolean Bitmap_hasAlpha(JNIEnv* env, jobject, jlong bitmapHandle) {
return !bitmap->isOpaque() ? JNI_TRUE : JNI_FALSE;
}
-static void Bitmap_setHasAlpha(JNIEnv* env, jobject, jlong bitmapHandle,
- jboolean hasAlpha) {
+static void Bitmap_setAlphaAndPremultiplied(JNIEnv* env, jobject, jlong bitmapHandle,
+ jboolean hasAlpha, jboolean isPremul) {
SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
- bitmap->setIsOpaque(!hasAlpha);
+ if (!hasAlpha) {
+ bitmap->setAlphaType(kOpaque_SkAlphaType);
+ } else if (isPremul) {
+ bitmap->setAlphaType(kPremul_SkAlphaType);
+ } else {
+ bitmap->setAlphaType(kUnpremul_SkAlphaType);
+ }
}
static jboolean Bitmap_hasMipMap(JNIEnv* env, jobject, jlong bitmapHandle) {
@@ -561,14 +567,14 @@ static jboolean Bitmap_writeToParcel(JNIEnv* env, jobject,
p->writeInt32(bitmap->rowBytes());
p->writeInt32(density);
- if (bitmap->getConfig() == SkBitmap::kIndex8_Config) {
+ if (bitmap->config() == SkBitmap::kIndex8_Config) {
SkColorTable* ctable = bitmap->getColorTable();
if (ctable != NULL) {
int count = ctable->count();
p->writeInt32(count);
memcpy(p->writeInplace(count * sizeof(SkPMColor)),
ctable->lockColors(), count * sizeof(SkPMColor));
- ctable->unlockColors(false);
+ ctable->unlockColors();
} else {
p->writeInt32(0); // indicate no ctable
}
@@ -800,7 +806,7 @@ static JNINativeMethod gBitmapMethods[] = {
{ "nativeRowBytes", "(J)I", (void*)Bitmap_rowBytes },
{ "nativeConfig", "(J)I", (void*)Bitmap_config },
{ "nativeHasAlpha", "(J)Z", (void*)Bitmap_hasAlpha },
- { "nativeSetHasAlpha", "(JZ)V", (void*)Bitmap_setHasAlpha },
+ { "nativeSetAlphaAndPremultiplied", "(JZZ)V", (void*)Bitmap_setAlphaAndPremultiplied},
{ "nativeHasMipMap", "(J)Z", (void*)Bitmap_hasMipMap },
{ "nativeSetHasMipMap", "(JZ)V", (void*)Bitmap_setHasMipMap },
{ "nativeCreateFromParcel",
diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp
index 44bf7f8..2b9a5c4 100644
--- a/core/jni/android/graphics/BitmapFactory.cpp
+++ b/core/jni/android/graphics/BitmapFactory.cpp
@@ -21,6 +21,7 @@
#include <androidfw/Asset.h>
#include <androidfw/ResourceTypes.h>
#include <netinet/in.h>
+#include <stdio.h>
#include <sys/mman.h>
#include <sys/stat.h>
@@ -126,12 +127,18 @@ static void scaleNinePatchChunk(android::Res_png_9patch* chunk, float scale) {
static SkPixelRef* installPixelRef(SkBitmap* bitmap, SkStreamRewindable* stream,
int sampleSize, bool ditherImage) {
+ SkImageInfo bitmapInfo;
+ if (!bitmap->asImageInfo(&bitmapInfo)) {
+ ALOGW("bitmap has unknown configuration so no memory has been allocated");
+ return NULL;
+ }
+
SkImageRef* pr;
// only use ashmem for large images, since mmaps come at a price
if (bitmap->getSize() >= 32 * 1024) {
- pr = new SkImageRef_ashmem(stream, bitmap->config(), sampleSize);
+ pr = new SkImageRef_ashmem(bitmapInfo, stream, sampleSize);
} else {
- pr = new SkImageRef_GlobalPool(stream, bitmap->config(), sampleSize);
+ pr = new SkImageRef_GlobalPool(bitmapInfo, stream, sampleSize);
}
pr->setDitherImage(ditherImage);
bitmap->setPixelRef(pr)->unref();
@@ -159,7 +166,7 @@ public:
virtual bool allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable) {
// accounts for scale in final allocation, using eventual size and config
const int bytesPerPixel = SkBitmap::ComputeBytesPerPixel(
- configForScaledOutput(bitmap->getConfig()));
+ configForScaledOutput(bitmap->config()));
const int requestedSize = bytesPerPixel *
int(bitmap->width() * mScale + 0.5f) *
int(bitmap->height() * mScale + 0.5f);
@@ -193,8 +200,15 @@ public:
return false;
}
+ SkImageInfo bitmapInfo;
+ if (!bitmap->asImageInfo(&bitmapInfo)) {
+ ALOGW("unable to reuse a bitmap as the target has an unknown bitmap configuration");
+ return false;
+ }
+
// Create a new pixelref with the new ctable that wraps the previous pixelref
- SkPixelRef* pr = new AndroidPixelRef(*static_cast<AndroidPixelRef*>(mPixelRef), ctable);
+ SkPixelRef* pr = new AndroidPixelRef(*static_cast<AndroidPixelRef*>(mPixelRef),
+ bitmapInfo, bitmap->rowBytes(), ctable);
bitmap->setPixelRef(pr)->unref();
// since we're already allocated, we lockPixels right away
@@ -403,8 +417,11 @@ static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding
// TODO: avoid copying when scaled size equals decodingBitmap size
SkBitmap::Config config = configForScaledOutput(decodingBitmap.config());
- outputBitmap->setConfig(config, scaledWidth, scaledHeight);
- outputBitmap->setIsOpaque(decodingBitmap.isOpaque());
+ // FIXME: If the alphaType is kUnpremul and the image has alpha, the
+ // colors may not be correct, since Skia does not yet support drawing
+ // to/from unpremultiplied bitmaps.
+ outputBitmap->setConfig(config, scaledWidth, scaledHeight, 0,
+ decodingBitmap.alphaType());
if (!outputBitmap->allocPixels(outputAllocator, NULL)) {
return nullObjectReturn("allocation failed for scaled bitmap");
}
@@ -416,7 +433,7 @@ static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding
}
SkPaint paint;
- paint.setFilterBitmap(true);
+ paint.setFilterLevel(SkPaint::kLow_FilterLevel);
SkCanvas canvas(*outputBitmap);
canvas.scale(sx, sy);
@@ -472,6 +489,12 @@ static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding
bitmapCreateFlags, ninePatchChunk, layoutBounds, -1);
}
+// Need to buffer enough input to be able to rewind as much as might be read by a decoder
+// trying to determine the stream's format. Currently the most is 64, read by
+// SkImageDecoder_libwebp.
+// FIXME: Get this number from SkImageDecoder
+#define BYTES_TO_BUFFER 64
+
static jobject nativeDecodeStream(JNIEnv* env, jobject clazz, jobject is, jbyteArray storage,
jobject padding, jobject options) {
@@ -479,11 +502,8 @@ static jobject nativeDecodeStream(JNIEnv* env, jobject clazz, jobject is, jbyteA
SkAutoTUnref<SkStream> stream(CreateJavaInputStreamAdaptor(env, is, storage));
if (stream.get()) {
- // Need to buffer enough input to be able to rewind as much as might be read by a decoder
- // trying to determine the stream's format. Currently the most is 64, read by
- // SkImageDecoder_libwebp.
- // FIXME: Get this number from SkImageDecoder
- SkAutoTUnref<SkStreamRewindable> bufferedStream(SkFrontBufferedStream::Create(stream, 64));
+ SkAutoTUnref<SkStreamRewindable> bufferedStream(
+ SkFrontBufferedStream::Create(stream, BYTES_TO_BUFFER));
SkASSERT(bufferedStream.get() != NULL);
// for now we don't allow purgeable with java inputstreams
bitmap = doDecode(env, bufferedStream, padding, options, false, false);
@@ -504,27 +524,48 @@ static jobject nativeDecodeFileDescriptor(JNIEnv* env, jobject clazz, jobject fi
return nullObjectReturn("fstat return -1");
}
- bool isPurgeable = optionsPurgeable(env, bitmapFactoryOptions);
- bool isShareable = optionsShareable(env, bitmapFactoryOptions);
- bool weOwnTheFD = false;
- if (isPurgeable && isShareable) {
- int newFD = ::dup(descriptor);
- if (-1 != newFD) {
- weOwnTheFD = true;
- descriptor = newFD;
- }
+ // Restore the descriptor's offset on exiting this function.
+ AutoFDSeek autoRestore(descriptor);
+
+ FILE* file = fdopen(descriptor, "r");
+ if (file == NULL) {
+ return nullObjectReturn("Could not open file");
}
- SkAutoTUnref<SkData> data(SkData::NewFromFD(descriptor));
- if (data.get() == NULL) {
- return nullObjectReturn("NewFromFD failed in nativeDecodeFileDescriptor");
+ SkAutoTUnref<SkFILEStream> fileStream(new SkFILEStream(file,
+ SkFILEStream::kCallerRetains_Ownership));
+
+ SkAutoTUnref<SkStreamRewindable> stream;
+
+ // Retain the old behavior of allowing purgeable if both purgeable and
+ // shareable are set to true.
+ bool isPurgeable = optionsPurgeable(env, bitmapFactoryOptions)
+ && optionsShareable(env, bitmapFactoryOptions);
+ if (isPurgeable) {
+ // Copy the stream, so the image can be decoded multiple times without
+ // continuing to modify the original file descriptor.
+ // Copy beginning from the current position.
+ const size_t fileSize = fileStream->getLength() - fileStream->getPosition();
+ void* buffer = sk_malloc_flags(fileSize, 0);
+ if (buffer == NULL) {
+ return nullObjectReturn("Could not make a copy for ashmem");
+ }
+
+ SkAutoTUnref<SkData> data(SkData::NewFromMalloc(buffer, fileSize));
+
+ if (fileStream->read(buffer, fileSize) != fileSize) {
+ return nullObjectReturn("Could not read the file.");
+ }
+
+ stream.reset(new SkMemoryStream(data));
+ } else {
+ // Use a buffered stream. Although an SkFILEStream can be rewound, this
+ // ensures that SkImageDecoder::Factory never rewinds beyond the
+ // current position of the file descriptor.
+ stream.reset(SkFrontBufferedStream::Create(fileStream, BYTES_TO_BUFFER));
}
- SkAutoTUnref<SkMemoryStream> stream(new SkMemoryStream(data));
- /* Allow purgeable iff we own the FD, i.e., in the puregeable and
- shareable case.
- */
- return doDecode(env, stream, padding, bitmapFactoryOptions, weOwnTheFD);
+ return doDecode(env, stream, padding, bitmapFactoryOptions, isPurgeable);
}
static jobject nativeDecodeAsset(JNIEnv* env, jobject clazz, jlong native_asset,
@@ -543,7 +584,9 @@ static jobject nativeDecodeAsset(JNIEnv* env, jobject clazz, jlong native_asset,
} else {
// since we know we'll be done with the asset when we return, we can
// just use a simple wrapper
- stream = new AssetStreamAdaptor(asset);
+ stream = new AssetStreamAdaptor(asset,
+ AssetStreamAdaptor::kNo_OwnAsset,
+ AssetStreamAdaptor::kNo_HasMemoryBase);
}
SkAutoUnref aur(stream);
return doDecode(env, stream, padding, options, forcePurgeable, forcePurgeable);
diff --git a/core/jni/android/graphics/BitmapRegionDecoder.cpp b/core/jni/android/graphics/BitmapRegionDecoder.cpp
index e7d2422..0d67b07 100644
--- a/core/jni/android/graphics/BitmapRegionDecoder.cpp
+++ b/core/jni/android/graphics/BitmapRegionDecoder.cpp
@@ -29,7 +29,6 @@
#include "CreateJavaOutputStreamAdaptor.h"
#include "Utils.h"
#include "JNIHelp.h"
-#include "SkTScopedPtr.h"
#include <android_runtime/AndroidRuntime.h>
#include "android_util_Binder.h"
@@ -76,7 +75,7 @@ private:
int fHeight;
};
-static jobject createBitmapRegionDecoder(JNIEnv* env, SkStream* stream) {
+static jobject createBitmapRegionDecoder(JNIEnv* env, SkStreamRewindable* stream) {
SkImageDecoder* decoder = SkImageDecoder::Factory(stream);
int width, height;
if (NULL == decoder) {
@@ -108,7 +107,7 @@ static jobject nativeNewInstanceFromByteArray(JNIEnv* env, jobject, jbyteArray b
For now we just always copy the array's data if isShareable.
*/
AutoJavaByteArray ar(env, byteArray);
- SkStream* stream = new SkMemoryStream(ar.ptr() + offset, length, true);
+ SkStreamRewindable* stream = new SkMemoryStream(ar.ptr() + offset, length, true);
jobject brd = createBitmapRegionDecoder(env, stream);
SkSafeUnref(stream); // the decoder now holds a reference
@@ -216,7 +215,7 @@ static jobject nativeDecodeRegion(JNIEnv* env, jobject, jlong brdHandle,
region.fRight = start_x + width;
region.fBottom = start_y + height;
SkBitmap* bitmap = NULL;
- SkTScopedPtr<SkBitmap> adb;
+ SkAutoTDelete<SkBitmap> adb;
if (tileBitmap != NULL) {
// Re-use bitmap.
@@ -247,7 +246,7 @@ static jobject nativeDecodeRegion(JNIEnv* env, jobject, jlong brdHandle,
}
// detach bitmap from its autodeleter, since we want to own it now
- adb.release();
+ adb.detach();
JavaPixelAllocator* allocator = (JavaPixelAllocator*) decoder->getAllocator();
jbyteArray buff = allocator->getStorageObjAndReset();
diff --git a/core/jni/android/graphics/Canvas.cpp b/core/jni/android/graphics/Canvas.cpp
index 11089da..f6ab39c 100644
--- a/core/jni/android/graphics/Canvas.cpp
+++ b/core/jni/android/graphics/Canvas.cpp
@@ -549,7 +549,7 @@ public:
if (paint) {
filteredPaint = *paint;
}
- filteredPaint.setFilterBitmap(true);
+ filteredPaint.setFilterLevel(SkPaint::kLow_FilterLevel);
canvas->drawBitmap(*bitmap, left_, top_, &filteredPaint);
} else {
canvas->drawBitmap(*bitmap, left_, top_, paint);
@@ -564,7 +564,7 @@ public:
if (paint) {
filteredPaint = *paint;
}
- filteredPaint.setFilterBitmap(true);
+ filteredPaint.setFilterLevel(SkPaint::kLow_FilterLevel);
canvas->drawBitmap(*bitmap, 0, 0, &filteredPaint);
@@ -587,7 +587,7 @@ public:
if (paint) {
filteredPaint = *paint;
}
- filteredPaint.setFilterBitmap(true);
+ filteredPaint.setFilterLevel(SkPaint::kLow_FilterLevel);
canvas->drawBitmapRect(*bitmap, srcPtr, dst, &filteredPaint);
} else {
canvas->drawBitmapRect(*bitmap, srcPtr, dst, paint);
diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp
index 2f4fd29..5d951ca 100644
--- a/core/jni/android/graphics/Graphics.cpp
+++ b/core/jni/android/graphics/Graphics.cpp
@@ -357,6 +357,18 @@ SkRegion* GraphicsJNI::getNativeRegion(JNIEnv* env, jobject region)
///////////////////////////////////////////////////////////////////////////////////////////
+// Assert that bitmap's SkAlphaType is consistent with isPremultiplied.
+static void assert_premultiplied(const SkBitmap& bitmap, bool isPremultiplied) {
+ // kOpaque_SkAlphaType and kIgnore_SkAlphaType mean that isPremultiplied is
+ // irrelevant. This just tests to ensure that the SkAlphaType is not
+ // opposite of isPremultiplied.
+ if (isPremultiplied) {
+ SkASSERT(bitmap.alphaType() != kUnpremul_SkAlphaType);
+ } else {
+ SkASSERT(bitmap.alphaType() != kPremul_SkAlphaType);
+ }
+}
+
jobject GraphicsJNI::createBitmap(JNIEnv* env, SkBitmap* bitmap, jbyteArray buffer,
int bitmapCreateFlags, jbyteArray ninepatch, jintArray layoutbounds, int density)
{
@@ -365,6 +377,10 @@ jobject GraphicsJNI::createBitmap(JNIEnv* env, SkBitmap* bitmap, jbyteArray buff
bool isMutable = bitmapCreateFlags & kBitmapCreateFlag_Mutable;
bool isPremultiplied = bitmapCreateFlags & kBitmapCreateFlag_Premultiplied;
+ // The caller needs to have already set the alpha type properly, so the
+ // native SkBitmap stays in sync with the Java Bitmap.
+ assert_premultiplied(*bitmap, isPremultiplied);
+
jobject obj = env->NewObject(gBitmap_class, gBitmap_constructorMethodID,
reinterpret_cast<jlong>(bitmap), buffer,
bitmap->width(), bitmap->height(), density, isMutable, isPremultiplied,
@@ -382,6 +398,10 @@ jobject GraphicsJNI::createBitmap(JNIEnv* env, SkBitmap* bitmap, int bitmapCreat
void GraphicsJNI::reinitBitmap(JNIEnv* env, jobject javaBitmap, SkBitmap* bitmap,
bool isPremultiplied)
{
+ // The caller needs to have already set the alpha type properly, so the
+ // native SkBitmap stays in sync with the Java Bitmap.
+ assert_premultiplied(*bitmap, isPremultiplied);
+
env->CallVoidMethod(javaBitmap, gBitmap_reinitMethodID,
bitmap->width(), bitmap->height(), isPremultiplied);
}
@@ -424,8 +444,9 @@ static JNIEnv* vm2env(JavaVM* vm)
///////////////////////////////////////////////////////////////////////////////
-AndroidPixelRef::AndroidPixelRef(JNIEnv* env, void* storage, size_t size, jbyteArray storageObj,
- SkColorTable* ctable) : SkMallocPixelRef(storage, size, ctable, (storageObj == NULL)),
+AndroidPixelRef::AndroidPixelRef(JNIEnv* env, const SkImageInfo& info, void* storage,
+ size_t rowBytes, jbyteArray storageObj, SkColorTable* ctable) :
+ SkMallocPixelRef(info, storage, rowBytes, ctable, (storageObj == NULL)),
fWrappedPixelRef(NULL) {
SkASSERT(storage);
SkASSERT(env);
@@ -440,13 +461,13 @@ AndroidPixelRef::AndroidPixelRef(JNIEnv* env, void* storage, size_t size, jbyteA
// If storageObj is NULL, the memory was NOT allocated on the Java heap
fOnJavaHeap = (storageObj != NULL);
-
}
-AndroidPixelRef::AndroidPixelRef(AndroidPixelRef& wrappedPixelRef, SkColorTable* ctable) :
- SkMallocPixelRef(wrappedPixelRef.getAddr(), wrappedPixelRef.getSize(), ctable, false),
+AndroidPixelRef::AndroidPixelRef(AndroidPixelRef& wrappedPixelRef, const SkImageInfo& info,
+ size_t rowBytes, SkColorTable* ctable) :
+ SkMallocPixelRef(info, wrappedPixelRef.getAddr(), rowBytes, ctable, false),
fWrappedPixelRef(wrappedPixelRef.fWrappedPixelRef ?
- wrappedPixelRef.fWrappedPixelRef : &wrappedPixelRef)
+ wrappedPixelRef.fWrappedPixelRef : &wrappedPixelRef)
{
SkASSERT(fWrappedPixelRef);
SkSafeRef(fWrappedPixelRef);
@@ -548,6 +569,14 @@ jbyteArray GraphicsJNI::allocateJavaPixelRef(JNIEnv* env, SkBitmap* bitmap,
"bitmap size exceeds 32bits");
return NULL;
}
+
+ SkImageInfo bitmapInfo;
+ if (!bitmap->asImageInfo(&bitmapInfo)) {
+ jniThrowException(env, "java/lang/IllegalArgumentException",
+ "unknown bitmap configuration");
+ return NULL;
+ }
+
size_t size = size64.get32();
jbyteArray arrayObj = (jbyteArray) env->CallObjectMethod(gVMRuntime,
gVMRuntime_newNonMovableArray,
@@ -561,7 +590,8 @@ jbyteArray GraphicsJNI::allocateJavaPixelRef(JNIEnv* env, SkBitmap* bitmap,
return NULL;
}
SkASSERT(addr);
- SkPixelRef* pr = new AndroidPixelRef(env, (void*) addr, size, arrayObj, ctable);
+ SkPixelRef* pr = new AndroidPixelRef(env, bitmapInfo, (void*) addr,
+ bitmap->rowBytes(), arrayObj, ctable);
bitmap->setPixelRef(pr)->unref();
// since we're already allocated, we lockPixels right away
// HeapAllocator behaves this way too
diff --git a/core/jni/android/graphics/GraphicsJNI.h b/core/jni/android/graphics/GraphicsJNI.h
index f4590b9..cb154aa 100644
--- a/core/jni/android/graphics/GraphicsJNI.h
+++ b/core/jni/android/graphics/GraphicsJNI.h
@@ -57,6 +57,7 @@ public:
/** Create a java Bitmap object given the native bitmap (required) and optional
storage array (may be null).
+ bitmap's SkAlphaType must already be in sync with bitmapCreateFlags.
*/
static jobject createBitmap(JNIEnv* env, SkBitmap* bitmap, jbyteArray buffer,
int bitmapCreateFlags, jbyteArray ninepatch, jintArray layoutbounds, int density = -1);
@@ -64,6 +65,9 @@ public:
static jobject createBitmap(JNIEnv* env, SkBitmap* bitmap, int bitmapCreateFlags,
jbyteArray ninepatch, int density = -1);
+ /** Reinitialize a bitmap. bitmap must already have its SkAlphaType set in
+ sync with isPremultiplied
+ */
static void reinitBitmap(JNIEnv* env, jobject javaBitmap, SkBitmap* bitmap,
bool isPremultiplied);
@@ -88,15 +92,16 @@ public:
class AndroidPixelRef : public SkMallocPixelRef {
public:
- AndroidPixelRef(JNIEnv* env, void* storage, size_t size, jbyteArray storageObj,
- SkColorTable* ctable);
+ AndroidPixelRef(JNIEnv* env, const SkImageInfo& info, void* storage, size_t rowBytes,
+ jbyteArray storageObj, SkColorTable* ctable);
/**
* Creates an AndroidPixelRef that wraps (and refs) another to reuse/share
* the same storage and java byte array refcounting, yet have a different
* color table.
*/
- AndroidPixelRef(AndroidPixelRef& wrappedPixelRef, SkColorTable* ctable);
+ AndroidPixelRef(AndroidPixelRef& wrappedPixelRef, const SkImageInfo& info,
+ size_t rowBytes, SkColorTable* ctable);
virtual ~AndroidPixelRef();
diff --git a/core/jni/android/graphics/Movie.cpp b/core/jni/android/graphics/Movie.cpp
index 0040b6f..461f723 100644
--- a/core/jni/android/graphics/Movie.cpp
+++ b/core/jni/android/graphics/Movie.cpp
@@ -85,7 +85,9 @@ static void movie_draw(JNIEnv* env, jobject movie, jobject canvas,
static jobject movie_decodeAsset(JNIEnv* env, jobject clazz, jlong native_asset) {
android::Asset* asset = reinterpret_cast<android::Asset*>(native_asset);
if (asset == NULL) return NULL;
- SkAutoTUnref<SkStreamRewindable> stream (new android::AssetStreamAdaptor(asset));
+ SkAutoTUnref<SkStreamRewindable> stream (new android::AssetStreamAdaptor(asset,
+ android::AssetStreamAdaptor::kNo_OwnAsset,
+ android::AssetStreamAdaptor::kNo_HasMemoryBase));
SkMovie* moov = SkMovie::DecodeStream(stream.get());
return create_jmovie(env, moov);
}
diff --git a/core/jni/android/graphics/NinePatchPeeker.cpp b/core/jni/android/graphics/NinePatchPeeker.cpp
index 51392ab..5daa1ad 100644
--- a/core/jni/android/graphics/NinePatchPeeker.cpp
+++ b/core/jni/android/graphics/NinePatchPeeker.cpp
@@ -40,15 +40,14 @@ bool NinePatchPeeker::peek(const char tag[], const void* data, size_t length) {
// now update our host to force index or 32bit config
// 'cause we don't want 565 predithered, since as a 9patch, we know
// we will be stretched, and therefore we want to dither afterwards.
- static const SkBitmap::Config gNo565Pref[] = {
- SkBitmap::kIndex8_Config,
- SkBitmap::kIndex8_Config,
- SkBitmap::kARGB_8888_Config,
- SkBitmap::kARGB_8888_Config,
- SkBitmap::kARGB_8888_Config,
- SkBitmap::kARGB_8888_Config,
- };
- fHost->setPrefConfigTable(gNo565Pref);
+ SkImageDecoder::PrefConfigTable table;
+ table.fPrefFor_8Index_NoAlpha_src = SkBitmap::kIndex8_Config;
+ table.fPrefFor_8Index_YesAlpha_src = SkBitmap::kIndex8_Config;
+ table.fPrefFor_8Gray_src = SkBitmap::kARGB_8888_Config;
+ table.fPrefFor_8bpc_NoAlpha_src = SkBitmap::kARGB_8888_Config;
+ table.fPrefFor_8bpc_YesAlpha_src = SkBitmap::kARGB_8888_Config;
+
+ fHost->setPrefConfigTable(table);
} else if (strcmp("npLb", tag) == 0 && length == sizeof(int) * 4) {
fLayoutBounds = new int[4];
memcpy(fLayoutBounds, data, sizeof(int) * 4);
diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp
index 2523481..dc97c22 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -155,7 +155,8 @@ public:
static void setFilterBitmap(JNIEnv* env, jobject paint, jboolean filterBitmap) {
NPE_CHECK_RETURN_VOID(env, paint);
- GraphicsJNI::getNativePaint(env, paint)->setFilterBitmap(filterBitmap);
+ GraphicsJNI::getNativePaint(env, paint)->setFilterLevel(
+ filterBitmap ? SkPaint::kLow_FilterLevel : SkPaint::kNone_FilterLevel);
}
static void setDither(JNIEnv* env, jobject paint, jboolean dither) {
@@ -609,7 +610,7 @@ public:
return 0;
}
}
- jfloat advancesArray[count];
+ jfloat* advancesArray = new jfloat[count];
jfloat totalAdvance = 0;
TextLayout::getTextRunAdvances(paint, text, start, count, contextCount, flags,
@@ -618,6 +619,7 @@ public:
if (advances != NULL) {
env->SetFloatArrayRegion(advances, advancesIndex, count, advancesArray);
}
+ delete [] advancesArray;
return totalAdvance;
}
diff --git a/core/jni/android/graphics/Region.cpp b/core/jni/android/graphics/Region.cpp
index bcf1273..912968a 100644
--- a/core/jni/android/graphics/Region.cpp
+++ b/core/jni/android/graphics/Region.cpp
@@ -214,7 +214,7 @@ static jlong Region_createFromParcel(JNIEnv* env, jobject clazz, jobject parcel)
SkRegion* region = new SkRegion;
size_t size = p->readInt32();
- region->readFromMemory(p->readInplace(size));
+ region->readFromMemory(p->readInplace(size), size);
return reinterpret_cast<jlong>(region);
}
diff --git a/core/jni/android/graphics/TextLayoutCache.cpp b/core/jni/android/graphics/TextLayoutCache.cpp
index e2c78b1..5db083a 100644
--- a/core/jni/android/graphics/TextLayoutCache.cpp
+++ b/core/jni/android/graphics/TextLayoutCache.cpp
@@ -20,6 +20,7 @@
#include "TextLayoutCache.h"
#include "TextLayout.h"
+#include "SkGlyphCache.h"
#include "SkTypeface_android.h"
#include "HarfBuzzNGFaceSkia.h"
#include <unicode/unistr.h>
@@ -757,8 +758,8 @@ void TextLayoutShaper::computeRunValues(const SkPaint* paint, const UChar* conte
outPos->add(ypos);
totalAdvance += xAdvance;
- // TODO: consider using glyph cache
- const SkGlyph& metrics = mShapingPaint.getGlyphMetrics(glyphId, NULL);
+ SkAutoGlyphCache autoCache(mShapingPaint, NULL, NULL);
+ const SkGlyph& metrics = autoCache.getCache()->getGlyphIDMetrics(glyphId);
outBounds->join(xpos + metrics.fLeft, ypos + metrics.fTop,
xpos + metrics.fLeft + metrics.fWidth, ypos + metrics.fTop + metrics.fHeight);
diff --git a/core/jni/android/graphics/Typeface.cpp b/core/jni/android/graphics/Typeface.cpp
index d096c2a..8164625 100644
--- a/core/jni/android/graphics/Typeface.cpp
+++ b/core/jni/android/graphics/Typeface.cpp
@@ -4,6 +4,7 @@
#include "GraphicsJNI.h"
#include "SkStream.h"
#include "SkTypeface.h"
+#include "Utils.h"
#include <android_runtime/android_util_AssetManager.h>
#include <androidfw/AssetManager.h>
@@ -77,65 +78,6 @@ static jint Typeface_getStyle(JNIEnv* env, jobject obj, jlong faceHandle) {
return static_cast<jint>(face->style());
}
-class AssetStream : public SkStream {
-public:
- AssetStream(Asset* asset, bool hasMemoryBase) : fAsset(asset)
- {
- fMemoryBase = hasMemoryBase ? fAsset->getBuffer(false) : NULL;
- }
-
- virtual ~AssetStream()
- {
- delete fAsset;
- }
-
- virtual const void* getMemoryBase()
- {
- return fMemoryBase;
- }
-
- virtual bool rewind()
- {
- off64_t pos = fAsset->seek(0, SEEK_SET);
- return pos != (off64_t)-1;
- }
-
- virtual size_t read(void* buffer, size_t size)
- {
- ssize_t amount;
-
- if (NULL == buffer)
- {
- if (0 == size) // caller is asking us for our total length
- return fAsset->getLength();
-
- // asset->seek returns new total offset
- // we want to return amount that was skipped
-
- off64_t oldOffset = fAsset->seek(0, SEEK_CUR);
- if (-1 == oldOffset)
- return 0;
- off64_t newOffset = fAsset->seek(size, SEEK_CUR);
- if (-1 == newOffset)
- return 0;
-
- amount = newOffset - oldOffset;
- }
- else
- {
- amount = fAsset->read(buffer, size);
- }
-
- if (amount < 0)
- amount = 0;
- return amount;
- }
-
-private:
- Asset* fAsset;
- const void* fMemoryBase;
-};
-
static jlong Typeface_createFromAsset(JNIEnv* env, jobject,
jobject jassetMgr,
jstring jpath) {
@@ -154,7 +96,9 @@ static jlong Typeface_createFromAsset(JNIEnv* env, jobject,
return NULL;
}
- SkStream* stream = new AssetStream(asset, true);
+ SkStream* stream = new AssetStreamAdaptor(asset,
+ AssetStreamAdaptor::kYes_OwnAsset,
+ AssetStreamAdaptor::kYes_HasMemoryBase);
SkTypeface* face = SkTypeface::CreateFromStream(stream);
// SkTypeFace::CreateFromStream calls ref() on the stream, so we
// need to unref it here or it won't be freed later on
diff --git a/core/jni/android/graphics/Utils.cpp b/core/jni/android/graphics/Utils.cpp
index b7d1f3a..eb416cb 100644
--- a/core/jni/android/graphics/Utils.cpp
+++ b/core/jni/android/graphics/Utils.cpp
@@ -19,6 +19,21 @@
using namespace android;
+AssetStreamAdaptor::AssetStreamAdaptor(Asset* asset, OwnAsset ownAsset,
+ HasMemoryBase hasMemoryBase)
+ : fAsset(asset)
+ , fMemoryBase(kYes_HasMemoryBase == hasMemoryBase ?
+ asset->getBuffer(false) : NULL)
+ , fOwnAsset(ownAsset)
+{
+}
+
+AssetStreamAdaptor::~AssetStreamAdaptor() {
+ if (kYes_OwnAsset == fOwnAsset) {
+ delete fAsset;
+ }
+}
+
bool AssetStreamAdaptor::rewind() {
off64_t pos = fAsset->seek(0, SEEK_SET);
if (pos == (off64_t)-1) {
diff --git a/core/jni/android/graphics/Utils.h b/core/jni/android/graphics/Utils.h
index a1ac72a..b90593c 100644
--- a/core/jni/android/graphics/Utils.h
+++ b/core/jni/android/graphics/Utils.h
@@ -28,16 +28,36 @@ namespace android {
class AssetStreamAdaptor : public SkStreamRewindable {
public:
- AssetStreamAdaptor(Asset* a) : fAsset(a) {}
+ // Enum passed to constructor. If set to kYes_OwnAsset,
+ // the passed in Asset will be deleted upon destruction.
+ enum OwnAsset {
+ kYes_OwnAsset,
+ kNo_OwnAsset,
+ };
+
+ // Enum passed to constructor. If set to kYes_HasMemoryBase,
+ // getMemoryBase will return the Asset's buffer.
+ enum HasMemoryBase {
+ kYes_HasMemoryBase,
+ kNo_HasMemoryBase,
+ };
+
+ AssetStreamAdaptor(Asset*, OwnAsset, HasMemoryBase);
+ ~AssetStreamAdaptor();
+
virtual bool rewind();
virtual size_t read(void* buffer, size_t size);
virtual bool hasLength() const { return true; }
virtual size_t getLength() const;
virtual bool isAtEnd() const;
+ virtual const void* getMemoryBase() { return fMemoryBase; }
+
virtual SkStreamRewindable* duplicate() const;
private:
- Asset* fAsset;
+ Asset* fAsset;
+ const void* const fMemoryBase;
+ const OwnAsset fOwnAsset;
};
/**
diff --git a/core/jni/android/opengl/util.cpp b/core/jni/android/opengl/util.cpp
index 48367ff..a17f328 100644
--- a/core/jni/android/opengl/util.cpp
+++ b/core/jni/android/opengl/util.cpp
@@ -632,7 +632,7 @@ static jint util_getInternalFormat(JNIEnv *env, jclass clazz,
SkBitmap const * nativeBitmap =
(SkBitmap const *)env->GetLongField(jbitmap, nativeBitmapID);
const SkBitmap& bitmap(*nativeBitmap);
- SkBitmap::Config config = bitmap.getConfig();
+ SkBitmap::Config config = bitmap.config();
return getInternalFormat(config);
}
@@ -642,7 +642,7 @@ static jint util_getType(JNIEnv *env, jclass clazz,
SkBitmap const * nativeBitmap =
(SkBitmap const *)env->GetLongField(jbitmap, nativeBitmapID);
const SkBitmap& bitmap(*nativeBitmap);
- SkBitmap::Config config = bitmap.getConfig();
+ SkBitmap::Config config = bitmap.config();
return getType(config);
}
@@ -653,7 +653,7 @@ static jint util_texImage2D(JNIEnv *env, jclass clazz,
SkBitmap const * nativeBitmap =
(SkBitmap const *)env->GetLongField(jbitmap, nativeBitmapID);
const SkBitmap& bitmap(*nativeBitmap);
- SkBitmap::Config config = bitmap.getConfig();
+ SkBitmap::Config config = bitmap.config();
if (internalformat < 0) {
internalformat = getInternalFormat(config);
}
@@ -681,7 +681,7 @@ static jint util_texImage2D(JNIEnv *env, jclass clazz,
SkColorTable* ctable = bitmap.getColorTable();
memcpy(data, ctable->lockColors(), ctable->count() * sizeof(SkPMColor));
memcpy(pixels, p, size);
- ctable->unlockColors(false);
+ ctable->unlockColors();
glCompressedTexImage2D(target, level, internalformat, w, h, border, imageSize, data);
free(data);
} else {
@@ -702,7 +702,7 @@ static jint util_texSubImage2D(JNIEnv *env, jclass clazz,
SkBitmap const * nativeBitmap =
(SkBitmap const *)env->GetLongField(jbitmap, nativeBitmapID);
const SkBitmap& bitmap(*nativeBitmap);
- SkBitmap::Config config = bitmap.getConfig();
+ SkBitmap::Config config = bitmap.config();
if (format < 0) {
format = getInternalFormat(config);
if (format == GL_PALETTE8_RGBA8_OES)
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index c2d4ec0..ab6c1e0 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -39,6 +39,7 @@
#include <SkCanvas.h>
#include <SkBitmap.h>
+#include <SkImage.h>
#include <SkRegion.h>
#include <utils/misc.h>
@@ -179,7 +180,8 @@ static jboolean nativeIsConsumerRunningBehind(JNIEnv* env, jclass clazz, jlong n
static inline SkBitmap::Config convertPixelFormat(PixelFormat format) {
/* note: if PIXEL_FORMAT_RGBX_8888 means that all alpha bytes are 0xFF, then
we can map to SkBitmap::kARGB_8888_Config, and optionally call
- bitmap.setIsOpaque(true) on the resulting SkBitmap (as an accelerator)
+ bitmap.setAlphaType(kOpaque_SkAlphaType) on the resulting SkBitmap
+ (as an accelerator)
*/
switch (format) {
case PIXEL_FORMAT_RGBX_8888: return SkBitmap::kARGB_8888_Config;
@@ -235,7 +237,7 @@ static jlong nativeLockCanvas(JNIEnv* env, jclass clazz,
ssize_t bpr = outBuffer.stride * bytesPerPixel(outBuffer.format);
bitmap.setConfig(convertPixelFormat(outBuffer.format), outBuffer.width, outBuffer.height, bpr);
if (outBuffer.format == PIXEL_FORMAT_RGBX_8888) {
- bitmap.setIsOpaque(true);
+ bitmap.setAlphaType(kOpaque_SkAlphaType);
}
if (outBuffer.width > 0 && outBuffer.height > 0) {
bitmap.setPixels(outBuffer.bits);
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index bd53095..ed84a64 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -61,51 +61,21 @@ static struct {
class ScreenshotPixelRef : public SkPixelRef {
public:
- ScreenshotPixelRef(SkColorTable* ctable) {
- fCTable = ctable;
- SkSafeRef(ctable);
+ ScreenshotPixelRef(const SkImageInfo& info, ScreenshotClient* screenshot) :
+ SkPixelRef(info),
+ mScreenshot(screenshot) {
setImmutable();
}
virtual ~ScreenshotPixelRef() {
- SkSafeUnref(fCTable);
- }
-
- status_t update(const sp<IBinder>& display, int width, int height,
- int minLayer, int maxLayer, bool allLayers) {
- status_t res = (width > 0 && height > 0)
- ? (allLayers
- ? mScreenshot.update(display, width, height)
- : mScreenshot.update(display, width, height, minLayer, maxLayer))
- : mScreenshot.update(display);
- if (res != NO_ERROR) {
- return res;
- }
-
- return NO_ERROR;
- }
-
- uint32_t getWidth() const {
- return mScreenshot.getWidth();
- }
-
- uint32_t getHeight() const {
- return mScreenshot.getHeight();
- }
-
- uint32_t getStride() const {
- return mScreenshot.getStride();
- }
-
- uint32_t getFormat() const {
- return mScreenshot.getFormat();
+ delete mScreenshot;
}
protected:
// overrides from SkPixelRef
virtual void* onLockPixels(SkColorTable** ct) {
- *ct = fCTable;
- return (void*)mScreenshot.getPixels();
+ *ct = NULL;
+ return (void*)mScreenshot->getPixels();
}
virtual void onUnlockPixels() {
@@ -113,8 +83,7 @@ protected:
SK_DECLARE_UNFLATTENABLE_OBJECT()
private:
- ScreenshotClient mScreenshot;
- SkColorTable* fCTable;
+ ScreenshotClient* mScreenshot;
typedef SkPixelRef INHERITED;
};
@@ -147,19 +116,6 @@ static void nativeDestroy(JNIEnv* env, jclass clazz, jlong nativeObject) {
ctrl->decStrong((void *)nativeCreate);
}
-static inline SkBitmap::Config convertPixelFormat(PixelFormat format) {
- /* note: if PIXEL_FORMAT_RGBX_8888 means that all alpha bytes are 0xFF, then
- we can map to SkBitmap::kARGB_8888_Config, and optionally call
- bitmap.setIsOpaque(true) on the resulting SkBitmap (as an accelerator)
- */
- switch (format) {
- case PIXEL_FORMAT_RGBX_8888: return SkBitmap::kARGB_8888_Config;
- case PIXEL_FORMAT_RGBA_8888: return SkBitmap::kARGB_8888_Config;
- case PIXEL_FORMAT_RGB_565: return SkBitmap::kRGB_565_Config;
- default: return SkBitmap::kNo_Config;
- }
-}
-
static jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz, jobject displayTokenObj,
jint width, jint height, jint minLayer, jint maxLayer, bool allLayers) {
sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj);
@@ -167,26 +123,50 @@ static jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz, jobject display
return NULL;
}
- ScreenshotPixelRef* pixels = new ScreenshotPixelRef(NULL);
- if (pixels->update(displayToken, width, height,
- minLayer, maxLayer, allLayers) != NO_ERROR) {
- delete pixels;
+ ScreenshotClient* screenshot = new ScreenshotClient();
+ status_t res = (width > 0 && height > 0)
+ ? (allLayers
+ ? screenshot->update(displayToken, width, height)
+ : screenshot->update(displayToken, width, height, minLayer, maxLayer))
+ : screenshot->update(displayToken);
+ if (res != NO_ERROR) {
+ delete screenshot;
return NULL;
}
- uint32_t w = pixels->getWidth();
- uint32_t h = pixels->getHeight();
- uint32_t s = pixels->getStride();
- uint32_t f = pixels->getFormat();
- ssize_t bpr = s * android::bytesPerPixel(f);
+ SkImageInfo screenshotInfo;
+ screenshotInfo.fWidth = screenshot->getWidth();
+ screenshotInfo.fHeight = screenshot->getHeight();
- SkBitmap* bitmap = new SkBitmap();
- bitmap->setConfig(convertPixelFormat(f), w, h, bpr);
- if (f == PIXEL_FORMAT_RGBX_8888) {
- bitmap->setIsOpaque(true);
+ switch (screenshot->getFormat()) {
+ case PIXEL_FORMAT_RGBX_8888: {
+ screenshotInfo.fColorType = kRGBA_8888_SkColorType;
+ screenshotInfo.fAlphaType = kIgnore_SkAlphaType;
+ break;
+ }
+ case PIXEL_FORMAT_RGBA_8888: {
+ screenshotInfo.fColorType = kRGBA_8888_SkColorType;
+ screenshotInfo.fAlphaType = kPremul_SkAlphaType;
+ break;
+ }
+ case PIXEL_FORMAT_RGB_565: {
+ screenshotInfo.fColorType = kRGB_565_SkColorType;
+ screenshotInfo.fAlphaType = kIgnore_SkAlphaType;
+ break;
+ }
+ default: {
+ delete screenshot;
+ return NULL;
+ }
}
- if (w > 0 && h > 0) {
+ // takes ownership of ScreenshotClient
+ ScreenshotPixelRef* pixels = new ScreenshotPixelRef(screenshotInfo, screenshot);
+ ssize_t rowBytes = screenshot->getStride() * android::bytesPerPixel(screenshot->getFormat());
+
+ SkBitmap* bitmap = new SkBitmap();
+ bitmap->setConfig(screenshotInfo, rowBytes);
+ if (screenshotInfo.fWidth > 0 && screenshotInfo.fHeight > 0) {
bitmap->setPixelRef(pixels)->unref();
bitmap->lockPixels();
} else {
diff --git a/core/jni/android_view_TextureView.cpp b/core/jni/android_view_TextureView.cpp
index 54f9278..77ede33 100644
--- a/core/jni/android_view_TextureView.cpp
+++ b/core/jni/android_view_TextureView.cpp
@@ -27,6 +27,7 @@
#include <SkBitmap.h>
#include <SkCanvas.h>
+#include <SkImage.h>
namespace android {
@@ -162,7 +163,7 @@ static jboolean android_view_TextureView_lockCanvas(JNIEnv* env, jobject,
bitmap.setConfig(convertPixelFormat(buffer.format), buffer.width, buffer.height, bytesCount);
if (buffer.format == WINDOW_FORMAT_RGBX_8888) {
- bitmap.setIsOpaque(true);
+ bitmap.setAlphaType(kOpaque_SkAlphaType);
}
if (buffer.width > 0 && buffer.height > 0) {
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 8355928..8ec2d64 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1056,8 +1056,9 @@
android:permissionGroupFlags="personalInfo"
android:priority="370" />
- <!-- Allows an application to monitor, modify, or abort outgoing
- calls. -->
+ <!-- Allows an application to see the number being dialed during an outgoing
+ call with the option to redirect the call to a different number or
+ abort the call altogether. -->
<permission android:name="android.permission.PROCESS_OUTGOING_CALLS"
android:permissionGroup="android.permission-group.PHONE_CALLS"
android:protectionLevel="dangerous"
@@ -1199,7 +1200,7 @@
android:permissionGroup="android.permission-group.STORAGE"
android:label="@string/permlab_manageDocs"
android:description="@string/permdesc_manageDocs"
- android:protectionLevel="signature|system" />
+ android:protectionLevel="signature" />
<!-- ================================== -->
<!-- Permissions for screenlock -->
@@ -1534,7 +1535,7 @@
@hide -->
<permission android:name="android.permission.FORCE_STOP_PACKAGES"
android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
- android:protectionLevel="signature"
+ android:protectionLevel="signature|system"
android:label="@string/permlab_forceStopPackages"
android:description="@string/permdesc_forceStopPackages" />
diff --git a/core/res/res/drawable-hdpi/ic_media_route_disabled_holo_dark.png b/core/res/res/drawable-hdpi/ic_media_route_disabled_holo_dark.png
index 458a2a6..e215b96 100644
--- a/core/res/res/drawable-hdpi/ic_media_route_disabled_holo_dark.png
+++ b/core/res/res/drawable-hdpi/ic_media_route_disabled_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_route_disabled_holo_light.png b/core/res/res/drawable-hdpi/ic_media_route_disabled_holo_light.png
index 03b0d2a..a014e91 100644
--- a/core/res/res/drawable-hdpi/ic_media_route_disabled_holo_light.png
+++ b/core/res/res/drawable-hdpi/ic_media_route_disabled_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_route_off_holo_dark.png b/core/res/res/drawable-hdpi/ic_media_route_off_holo_dark.png
index c91faa9..bb8bec1 100644
--- a/core/res/res/drawable-hdpi/ic_media_route_off_holo_dark.png
+++ b/core/res/res/drawable-hdpi/ic_media_route_off_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_route_off_holo_light.png b/core/res/res/drawable-hdpi/ic_media_route_off_holo_light.png
index 14c9183..aa1737e 100644
--- a/core/res/res/drawable-hdpi/ic_media_route_off_holo_light.png
+++ b/core/res/res/drawable-hdpi/ic_media_route_off_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_route_on_0_holo_dark.png b/core/res/res/drawable-hdpi/ic_media_route_on_0_holo_dark.png
index b388d86..2c1434b 100644
--- a/core/res/res/drawable-hdpi/ic_media_route_on_0_holo_dark.png
+++ b/core/res/res/drawable-hdpi/ic_media_route_on_0_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_route_on_0_holo_light.png b/core/res/res/drawable-hdpi/ic_media_route_on_0_holo_light.png
index 76c1323..dbdce3e 100644
--- a/core/res/res/drawable-hdpi/ic_media_route_on_0_holo_light.png
+++ b/core/res/res/drawable-hdpi/ic_media_route_on_0_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_route_on_1_holo_dark.png b/core/res/res/drawable-hdpi/ic_media_route_on_1_holo_dark.png
index fd39f9d..1101864 100644
--- a/core/res/res/drawable-hdpi/ic_media_route_on_1_holo_dark.png
+++ b/core/res/res/drawable-hdpi/ic_media_route_on_1_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_route_on_1_holo_light.png b/core/res/res/drawable-hdpi/ic_media_route_on_1_holo_light.png
index c74727a..e8e9069 100644
--- a/core/res/res/drawable-hdpi/ic_media_route_on_1_holo_light.png
+++ b/core/res/res/drawable-hdpi/ic_media_route_on_1_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_route_on_2_holo_dark.png b/core/res/res/drawable-hdpi/ic_media_route_on_2_holo_dark.png
index 826c9ae..8595158 100644
--- a/core/res/res/drawable-hdpi/ic_media_route_on_2_holo_dark.png
+++ b/core/res/res/drawable-hdpi/ic_media_route_on_2_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_route_on_2_holo_light.png b/core/res/res/drawable-hdpi/ic_media_route_on_2_holo_light.png
index d0baec3..14844d4 100644
--- a/core/res/res/drawable-hdpi/ic_media_route_on_2_holo_light.png
+++ b/core/res/res/drawable-hdpi/ic_media_route_on_2_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_route_on_holo_dark.png b/core/res/res/drawable-hdpi/ic_media_route_on_holo_dark.png
index c60ff59..1565a29 100644
--- a/core/res/res/drawable-hdpi/ic_media_route_on_holo_dark.png
+++ b/core/res/res/drawable-hdpi/ic_media_route_on_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_route_on_holo_light.png b/core/res/res/drawable-hdpi/ic_media_route_on_holo_light.png
index 75552cc..9b8fe87 100644
--- a/core/res/res/drawable-hdpi/ic_media_route_on_holo_light.png
+++ b/core/res/res/drawable-hdpi/ic_media_route_on_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_notification_cast_0.png b/core/res/res/drawable-hdpi/ic_notification_cast_0.png
index a35f281..74f7dc0 100644
--- a/core/res/res/drawable-hdpi/ic_notification_cast_0.png
+++ b/core/res/res/drawable-hdpi/ic_notification_cast_0.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_notification_cast_1.png b/core/res/res/drawable-hdpi/ic_notification_cast_1.png
index 9f6e2ad..c6d267d 100644
--- a/core/res/res/drawable-hdpi/ic_notification_cast_1.png
+++ b/core/res/res/drawable-hdpi/ic_notification_cast_1.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_notification_cast_2.png b/core/res/res/drawable-hdpi/ic_notification_cast_2.png
index 737137a..699b299 100644
--- a/core/res/res/drawable-hdpi/ic_notification_cast_2.png
+++ b/core/res/res/drawable-hdpi/ic_notification_cast_2.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_notification_cast_on.png b/core/res/res/drawable-hdpi/ic_notification_cast_on.png
index ff2753a..3eaf13a 100644
--- a/core/res/res/drawable-hdpi/ic_notification_cast_on.png
+++ b/core/res/res/drawable-hdpi/ic_notification_cast_on.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_route_disabled_holo_dark.png b/core/res/res/drawable-mdpi/ic_media_route_disabled_holo_dark.png
index fa22d82..52e3a5a 100644
--- a/core/res/res/drawable-mdpi/ic_media_route_disabled_holo_dark.png
+++ b/core/res/res/drawable-mdpi/ic_media_route_disabled_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_route_disabled_holo_light.png b/core/res/res/drawable-mdpi/ic_media_route_disabled_holo_light.png
index a686cd1..319c57e 100644
--- a/core/res/res/drawable-mdpi/ic_media_route_disabled_holo_light.png
+++ b/core/res/res/drawable-mdpi/ic_media_route_disabled_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_route_off_holo_dark.png b/core/res/res/drawable-mdpi/ic_media_route_off_holo_dark.png
index 9d92648..f98c0a8 100644
--- a/core/res/res/drawable-mdpi/ic_media_route_off_holo_dark.png
+++ b/core/res/res/drawable-mdpi/ic_media_route_off_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_route_off_holo_light.png b/core/res/res/drawable-mdpi/ic_media_route_off_holo_light.png
index 3e27fc8..b74cdb5 100644
--- a/core/res/res/drawable-mdpi/ic_media_route_off_holo_light.png
+++ b/core/res/res/drawable-mdpi/ic_media_route_off_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_route_on_0_holo_dark.png b/core/res/res/drawable-mdpi/ic_media_route_on_0_holo_dark.png
index 72b9e78..a6a4bd0 100644
--- a/core/res/res/drawable-mdpi/ic_media_route_on_0_holo_dark.png
+++ b/core/res/res/drawable-mdpi/ic_media_route_on_0_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_route_on_0_holo_light.png b/core/res/res/drawable-mdpi/ic_media_route_on_0_holo_light.png
index bd462a2..106fd3a 100644
--- a/core/res/res/drawable-mdpi/ic_media_route_on_0_holo_light.png
+++ b/core/res/res/drawable-mdpi/ic_media_route_on_0_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_route_on_1_holo_dark.png b/core/res/res/drawable-mdpi/ic_media_route_on_1_holo_dark.png
index 0a2cc89..2c141ab 100644
--- a/core/res/res/drawable-mdpi/ic_media_route_on_1_holo_dark.png
+++ b/core/res/res/drawable-mdpi/ic_media_route_on_1_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_route_on_1_holo_light.png b/core/res/res/drawable-mdpi/ic_media_route_on_1_holo_light.png
index d162503..0b62d0b 100644
--- a/core/res/res/drawable-mdpi/ic_media_route_on_1_holo_light.png
+++ b/core/res/res/drawable-mdpi/ic_media_route_on_1_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_route_on_2_holo_dark.png b/core/res/res/drawable-mdpi/ic_media_route_on_2_holo_dark.png
index 997e32b..23442b0 100644
--- a/core/res/res/drawable-mdpi/ic_media_route_on_2_holo_dark.png
+++ b/core/res/res/drawable-mdpi/ic_media_route_on_2_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_route_on_2_holo_light.png b/core/res/res/drawable-mdpi/ic_media_route_on_2_holo_light.png
index d314967..42b329f 100644
--- a/core/res/res/drawable-mdpi/ic_media_route_on_2_holo_light.png
+++ b/core/res/res/drawable-mdpi/ic_media_route_on_2_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_route_on_holo_dark.png b/core/res/res/drawable-mdpi/ic_media_route_on_holo_dark.png
index f15d7a9..58ff506 100644
--- a/core/res/res/drawable-mdpi/ic_media_route_on_holo_dark.png
+++ b/core/res/res/drawable-mdpi/ic_media_route_on_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_route_on_holo_light.png b/core/res/res/drawable-mdpi/ic_media_route_on_holo_light.png
index 26d46f8..25257f8 100644
--- a/core/res/res/drawable-mdpi/ic_media_route_on_holo_light.png
+++ b/core/res/res/drawable-mdpi/ic_media_route_on_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_notification_cast_0.png b/core/res/res/drawable-mdpi/ic_notification_cast_0.png
index d9cedbd..a51a3cb 100644
--- a/core/res/res/drawable-mdpi/ic_notification_cast_0.png
+++ b/core/res/res/drawable-mdpi/ic_notification_cast_0.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_notification_cast_1.png b/core/res/res/drawable-mdpi/ic_notification_cast_1.png
index 414c67f..e081367 100644
--- a/core/res/res/drawable-mdpi/ic_notification_cast_1.png
+++ b/core/res/res/drawable-mdpi/ic_notification_cast_1.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_notification_cast_2.png b/core/res/res/drawable-mdpi/ic_notification_cast_2.png
index 280a888..a7f4de4 100644
--- a/core/res/res/drawable-mdpi/ic_notification_cast_2.png
+++ b/core/res/res/drawable-mdpi/ic_notification_cast_2.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_notification_cast_on.png b/core/res/res/drawable-mdpi/ic_notification_cast_on.png
index ab5f1d7..42de8c4 100644
--- a/core/res/res/drawable-mdpi/ic_notification_cast_on.png
+++ b/core/res/res/drawable-mdpi/ic_notification_cast_on.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/cab_background_top_holo_dark.9.png b/core/res/res/drawable-xhdpi/cab_background_top_holo_dark.9.png
index 6b31579..7b6d48b 100644
--- a/core/res/res/drawable-xhdpi/cab_background_top_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/cab_background_top_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/cab_background_top_holo_light.9.png b/core/res/res/drawable-xhdpi/cab_background_top_holo_light.9.png
index df0121b..bafe878 100644
--- a/core/res/res/drawable-xhdpi/cab_background_top_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/cab_background_top_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_route_disabled_holo_dark.png b/core/res/res/drawable-xhdpi/ic_media_route_disabled_holo_dark.png
index 045eee0..4119cff 100644
--- a/core/res/res/drawable-xhdpi/ic_media_route_disabled_holo_dark.png
+++ b/core/res/res/drawable-xhdpi/ic_media_route_disabled_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_route_disabled_holo_light.png b/core/res/res/drawable-xhdpi/ic_media_route_disabled_holo_light.png
index 6e14e29..b629a57 100644
--- a/core/res/res/drawable-xhdpi/ic_media_route_disabled_holo_light.png
+++ b/core/res/res/drawable-xhdpi/ic_media_route_disabled_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_route_off_holo_dark.png b/core/res/res/drawable-xhdpi/ic_media_route_off_holo_dark.png
index 121bbf6..fe81128 100644
--- a/core/res/res/drawable-xhdpi/ic_media_route_off_holo_dark.png
+++ b/core/res/res/drawable-xhdpi/ic_media_route_off_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_route_off_holo_light.png b/core/res/res/drawable-xhdpi/ic_media_route_off_holo_light.png
index 468a0c3..9b59eaf 100644
--- a/core/res/res/drawable-xhdpi/ic_media_route_off_holo_light.png
+++ b/core/res/res/drawable-xhdpi/ic_media_route_off_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_route_on_0_holo_dark.png b/core/res/res/drawable-xhdpi/ic_media_route_on_0_holo_dark.png
index 414a322..1a513c1 100644
--- a/core/res/res/drawable-xhdpi/ic_media_route_on_0_holo_dark.png
+++ b/core/res/res/drawable-xhdpi/ic_media_route_on_0_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_route_on_0_holo_light.png b/core/res/res/drawable-xhdpi/ic_media_route_on_0_holo_light.png
index 6088a48..ff78803 100644
--- a/core/res/res/drawable-xhdpi/ic_media_route_on_0_holo_light.png
+++ b/core/res/res/drawable-xhdpi/ic_media_route_on_0_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_route_on_1_holo_dark.png b/core/res/res/drawable-xhdpi/ic_media_route_on_1_holo_dark.png
index 363d7d4..4c4b624 100644
--- a/core/res/res/drawable-xhdpi/ic_media_route_on_1_holo_dark.png
+++ b/core/res/res/drawable-xhdpi/ic_media_route_on_1_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_route_on_1_holo_light.png b/core/res/res/drawable-xhdpi/ic_media_route_on_1_holo_light.png
index edf731e..60f8c4d 100644
--- a/core/res/res/drawable-xhdpi/ic_media_route_on_1_holo_light.png
+++ b/core/res/res/drawable-xhdpi/ic_media_route_on_1_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_route_on_2_holo_dark.png b/core/res/res/drawable-xhdpi/ic_media_route_on_2_holo_dark.png
index 85cba7b..cdb2f30 100644
--- a/core/res/res/drawable-xhdpi/ic_media_route_on_2_holo_dark.png
+++ b/core/res/res/drawable-xhdpi/ic_media_route_on_2_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_route_on_2_holo_light.png b/core/res/res/drawable-xhdpi/ic_media_route_on_2_holo_light.png
index e65ac31..97a10a3 100644
--- a/core/res/res/drawable-xhdpi/ic_media_route_on_2_holo_light.png
+++ b/core/res/res/drawable-xhdpi/ic_media_route_on_2_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_route_on_holo_dark.png b/core/res/res/drawable-xhdpi/ic_media_route_on_holo_dark.png
index d8e3e3a..a19a083 100644
--- a/core/res/res/drawable-xhdpi/ic_media_route_on_holo_dark.png
+++ b/core/res/res/drawable-xhdpi/ic_media_route_on_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_route_on_holo_light.png b/core/res/res/drawable-xhdpi/ic_media_route_on_holo_light.png
index 562dc9a..db30613 100644
--- a/core/res/res/drawable-xhdpi/ic_media_route_on_holo_light.png
+++ b/core/res/res/drawable-xhdpi/ic_media_route_on_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_notification_cast_0.png b/core/res/res/drawable-xhdpi/ic_notification_cast_0.png
index 5fb23a0..818c1cd 100644
--- a/core/res/res/drawable-xhdpi/ic_notification_cast_0.png
+++ b/core/res/res/drawable-xhdpi/ic_notification_cast_0.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_notification_cast_1.png b/core/res/res/drawable-xhdpi/ic_notification_cast_1.png
index f01d17d..2a56e31 100644
--- a/core/res/res/drawable-xhdpi/ic_notification_cast_1.png
+++ b/core/res/res/drawable-xhdpi/ic_notification_cast_1.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_notification_cast_2.png b/core/res/res/drawable-xhdpi/ic_notification_cast_2.png
index 4f4ba7f..3515a76 100644
--- a/core/res/res/drawable-xhdpi/ic_notification_cast_2.png
+++ b/core/res/res/drawable-xhdpi/ic_notification_cast_2.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_notification_cast_on.png b/core/res/res/drawable-xhdpi/ic_notification_cast_on.png
index 38f15dd..142065b 100644
--- a/core/res/res/drawable-xhdpi/ic_notification_cast_on.png
+++ b/core/res/res/drawable-xhdpi/ic_notification_cast_on.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/cab_background_top_holo_dark.9.png b/core/res/res/drawable-xxhdpi/cab_background_top_holo_dark.9.png
index 418f322..cbb4f4c 100644
--- a/core/res/res/drawable-xxhdpi/cab_background_top_holo_dark.9.png
+++ b/core/res/res/drawable-xxhdpi/cab_background_top_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/cab_background_top_holo_light.9.png b/core/res/res/drawable-xxhdpi/cab_background_top_holo_light.9.png
index a5a59d4..6d467f7 100644
--- a/core/res/res/drawable-xxhdpi/cab_background_top_holo_light.9.png
+++ b/core/res/res/drawable-xxhdpi/cab_background_top_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_route_disabled_holo_dark.png b/core/res/res/drawable-xxhdpi/ic_media_route_disabled_holo_dark.png
index 178774c..6fad4a64 100644
--- a/core/res/res/drawable-xxhdpi/ic_media_route_disabled_holo_dark.png
+++ b/core/res/res/drawable-xxhdpi/ic_media_route_disabled_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_route_disabled_holo_light.png b/core/res/res/drawable-xxhdpi/ic_media_route_disabled_holo_light.png
index 2dc2092..865617c 100644
--- a/core/res/res/drawable-xxhdpi/ic_media_route_disabled_holo_light.png
+++ b/core/res/res/drawable-xxhdpi/ic_media_route_disabled_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_route_off_holo_dark.png b/core/res/res/drawable-xxhdpi/ic_media_route_off_holo_dark.png
index 592ee8c..44d98d5 100644
--- a/core/res/res/drawable-xxhdpi/ic_media_route_off_holo_dark.png
+++ b/core/res/res/drawable-xxhdpi/ic_media_route_off_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_route_off_holo_light.png b/core/res/res/drawable-xxhdpi/ic_media_route_off_holo_light.png
index f0549e2..b5b29b0 100644
--- a/core/res/res/drawable-xxhdpi/ic_media_route_off_holo_light.png
+++ b/core/res/res/drawable-xxhdpi/ic_media_route_off_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_route_on_0_holo_dark.png b/core/res/res/drawable-xxhdpi/ic_media_route_on_0_holo_dark.png
index 91268f5..c807b50 100644
--- a/core/res/res/drawable-xxhdpi/ic_media_route_on_0_holo_dark.png
+++ b/core/res/res/drawable-xxhdpi/ic_media_route_on_0_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_route_on_0_holo_light.png b/core/res/res/drawable-xxhdpi/ic_media_route_on_0_holo_light.png
index 9d5436f..3fc7188 100644
--- a/core/res/res/drawable-xxhdpi/ic_media_route_on_0_holo_light.png
+++ b/core/res/res/drawable-xxhdpi/ic_media_route_on_0_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_route_on_1_holo_dark.png b/core/res/res/drawable-xxhdpi/ic_media_route_on_1_holo_dark.png
index 8e77483..d54f44a 100644
--- a/core/res/res/drawable-xxhdpi/ic_media_route_on_1_holo_dark.png
+++ b/core/res/res/drawable-xxhdpi/ic_media_route_on_1_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_route_on_1_holo_light.png b/core/res/res/drawable-xxhdpi/ic_media_route_on_1_holo_light.png
index f396d22..092fe8c 100644
--- a/core/res/res/drawable-xxhdpi/ic_media_route_on_1_holo_light.png
+++ b/core/res/res/drawable-xxhdpi/ic_media_route_on_1_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_route_on_2_holo_dark.png b/core/res/res/drawable-xxhdpi/ic_media_route_on_2_holo_dark.png
index 260bab4..17c1d99 100644
--- a/core/res/res/drawable-xxhdpi/ic_media_route_on_2_holo_dark.png
+++ b/core/res/res/drawable-xxhdpi/ic_media_route_on_2_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_route_on_2_holo_light.png b/core/res/res/drawable-xxhdpi/ic_media_route_on_2_holo_light.png
index 2c9fb1d..4fd5808 100644
--- a/core/res/res/drawable-xxhdpi/ic_media_route_on_2_holo_light.png
+++ b/core/res/res/drawable-xxhdpi/ic_media_route_on_2_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_route_on_holo_dark.png b/core/res/res/drawable-xxhdpi/ic_media_route_on_holo_dark.png
index bdbd59c..906401e 100644
--- a/core/res/res/drawable-xxhdpi/ic_media_route_on_holo_dark.png
+++ b/core/res/res/drawable-xxhdpi/ic_media_route_on_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_route_on_holo_light.png b/core/res/res/drawable-xxhdpi/ic_media_route_on_holo_light.png
index f5c33dd..d29e563 100644
--- a/core/res/res/drawable-xxhdpi/ic_media_route_on_holo_light.png
+++ b/core/res/res/drawable-xxhdpi/ic_media_route_on_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_notification_cast_0.png b/core/res/res/drawable-xxhdpi/ic_notification_cast_0.png
index f5b16ed..7ef0d3d 100644
--- a/core/res/res/drawable-xxhdpi/ic_notification_cast_0.png
+++ b/core/res/res/drawable-xxhdpi/ic_notification_cast_0.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_notification_cast_1.png b/core/res/res/drawable-xxhdpi/ic_notification_cast_1.png
index 22efeec..ed04beb 100644
--- a/core/res/res/drawable-xxhdpi/ic_notification_cast_1.png
+++ b/core/res/res/drawable-xxhdpi/ic_notification_cast_1.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_notification_cast_2.png b/core/res/res/drawable-xxhdpi/ic_notification_cast_2.png
index e24cd97..d62d27d 100644
--- a/core/res/res/drawable-xxhdpi/ic_notification_cast_2.png
+++ b/core/res/res/drawable-xxhdpi/ic_notification_cast_2.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_notification_cast_on.png b/core/res/res/drawable-xxhdpi/ic_notification_cast_on.png
index da1a627..d562602 100644
--- a/core/res/res/drawable-xxhdpi/ic_notification_cast_on.png
+++ b/core/res/res/drawable-xxhdpi/ic_notification_cast_on.png
Binary files differ
diff --git a/core/res/res/values-ja/bools.xml b/core/res/res/values-ja/bools.xml
deleted file mode 100644
index 59cf744..0000000
--- a/core/res/res/values-ja/bools.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<resources>
- <bool name="flip_controller_fallback_keys">true</bool>
-</resources>
-
diff --git a/core/res/res/values/bools.xml b/core/res/res/values/bools.xml
index 10a5d85..18e4f2f 100644
--- a/core/res/res/values/bools.xml
+++ b/core/res/res/values/bools.xml
@@ -26,5 +26,4 @@
<bool name="show_ongoing_ime_switcher">true</bool>
<bool name="action_bar_expanded_action_views_exclusive">true</bool>
<bool name="target_honeycomb_needs_options_menu">true</bool>
- <bool name="flip_controller_fallback_keys">false</bool>
</resources>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index b34c792..a3b8132 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -352,6 +352,10 @@
<!-- Wifi driver supports batched scan -->
<bool translatable="false" name="config_wifi_batched_scan_supported">false</bool>
+ <!-- Wifi driver's fallback country code; WS is ISO-Alpha2 code for Samoa which
+ has restrictions on can be scanned; which may satisfy quite a few regulatory issues. -->
+ <string translatable="false" name="config_wifi_unknown_country_code">WS</string>
+
<!-- Flag indicating whether the we should enable the automatic brightness in Settings.
Software implementation will be used if config_hardware_auto_brightness_available is not set -->
<bool name="config_automatic_brightness_available">false</bool>
@@ -1304,4 +1308,12 @@
<item>333</item>
<item>353</item>
</string-array>
+
+ <!-- Override the default detection behavior for the framework method
+ android.view.ViewConfiguration#hasPermanentMenuKey().
+ Valid settings are:
+ 0 - No change. Use the default autodetection behavior.
+ 1 - The device DOES have a permanent menu key; ignore autodetection.
+ 2 - The device DOES NOT have a permanent menu key; ignore autodetection. -->
+ <integer name="config_overrideHasPermanentMenuKey">0</integer>
</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 012fb83..538003f 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -625,9 +625,9 @@
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_processOutgoingCalls">reroute outgoing calls</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permdesc_processOutgoingCalls">Allows the app to process
- outgoing calls and change the number to be dialed. This permission allows
- the app to monitor, redirect, or prevent outgoing calls.</string>
+ <string name="permdesc_processOutgoingCalls">Allows the app to see the
+ number being dialed during an outgoing call with the option to redirect
+ the call to a different number or abort the call altogether.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_receiveSms">receive text messages (SMS)</string>
@@ -932,13 +932,13 @@
<!-- [CHAR LIMIT=NONE] Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_getAppOpsStats">Allows the app to retrieve
collected application operation statistics. Not for use by normal apps.</string>
-
+
<!-- [CHAR LIMIT=NONE] Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_updateAppOpsStats">modify app ops statistics</string>
<!-- [CHAR LIMIT=NONE] Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_updateAppOpsStats">Allows the app to modify
collected application operation statistics. Not for use by normal apps.</string>
-
+
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_backup">control system backup and restore</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
@@ -2255,6 +2255,10 @@
<!-- Other SIP address type. Same context as Other phone type. -->
<string name="sipAddressTypeOther">Other</string>
+ <!-- Error message that is displayed when the user clicks on a quick contacts badge, but
+ there is no contacts application installed that can display the quick contact -->
+ <string name="quick_contacts_not_available">No application found to view this contact.</string>
+
<!-- Instructions telling the user to enter their SIM PIN to unlock the keyguard.
Displayed in one line in a large font. -->
<string name="keyguard_password_enter_pin_code">Type PIN code</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 6d90973..1200276 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -288,7 +288,6 @@
<java-symbol type="bool" name="config_useFixedVolume" />
<java-symbol type="bool" name="config_forceDefaultOrientation" />
<java-symbol type="bool" name="config_wifi_batched_scan_supported" />
- <java-symbol type="bool" name="flip_controller_fallback_keys" />
<java-symbol type="integer" name="config_cursorWindowSize" />
<java-symbol type="integer" name="config_extraFreeKbytesAdjust" />
@@ -319,6 +318,7 @@
<java-symbol type="integer" name="config_mobile_mtu" />
<java-symbol type="integer" name="config_volte_replacement_rat"/>
<java-symbol type="integer" name="config_valid_wappush_index" />
+ <java-symbol type="integer" name="config_overrideHasPermanentMenuKey" />
<java-symbol type="color" name="tab_indicator_text_v4" />
@@ -478,6 +478,7 @@
<java-symbol type="string" name="config_ntpServer" />
<java-symbol type="string" name="config_tether_apndata" />
<java-symbol type="string" name="config_useragentprofile_url" />
+ <java-symbol type="string" name="config_wifi_unknown_country_code" />
<java-symbol type="string" name="config_wifi_p2p_device_type" />
<java-symbol type="string" name="contentServiceSync" />
<java-symbol type="string" name="contentServiceSyncNotificationTitle" />
@@ -690,6 +691,7 @@
<java-symbol type="string" name="mobile_provisioning_apn" />
<java-symbol type="string" name="mobile_provisioning_url" />
<java-symbol type="string" name="mobile_redirected_provisioning_url" />
+ <java-symbol type="string" name="quick_contacts_not_available" />
<java-symbol type="string" name="reboot_safemode_confirm" />
<java-symbol type="string" name="reboot_safemode_title" />
<java-symbol type="string" name="relationTypeAssistant" />
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/NetworkState.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/NetworkState.java
index 5a4a2d0..9d97ac5 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/NetworkState.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/NetworkState.java
@@ -101,9 +101,10 @@ public class NetworkState {
}
/*
- * Transition from CONNECTED -> DISCONNECTED:
- * CONNECTED->DISCONNECTING->DISCONNECTED
- * return false if any state transition is not valid and save a message in mReason
+ * Verifies state transition from CONNECTED->...-> DISCONNECTED.
+ *
+ * returns false if initial state or target state is not correct, or if there is
+ * any transition from DISCONNECTING/DISCONNECTED -> CONNECTED.
*/
public boolean transitToDisconnection () {
mReason = "states: " + printStates();
@@ -120,13 +121,13 @@ public class NetworkState {
for (int i = 1; i < mStateDepository.size() - 1; i++) {
State preState = mStateDepository.get(i-1);
State curState = mStateDepository.get(i);
- if ((preState == State.CONNECTED) && ((curState == State.DISCONNECTING) ||
+ if (preState == curState) {
+ continue;
+ } else if ((preState == State.CONNECTED) && ((curState == State.DISCONNECTING) ||
(curState == State.DISCONNECTED))) {
continue;
} else if ((preState == State.DISCONNECTING) && (curState == State.DISCONNECTED)) {
continue;
- } else if ((preState == State.DISCONNECTED) && (curState == State.DISCONNECTED)) {
- continue;
} else {
mReason += " Transition state from " + preState.toString() + " to " +
curState.toString() + " is not valid.";
@@ -136,7 +137,12 @@ public class NetworkState {
return true;
}
- // DISCONNECTED->CONNECTING->CONNECTED
+ /*
+ * Verifies state transition from DISCONNECTED->...-> CONNECTED.
+ *
+ * returns false if initial state or target state is not correct, or if there is
+ * any transition from CONNECED -> DISCONNECTED.
+ */
public boolean transitToConnection() {
mReason = "states: " + printStates();
if (mStateDepository.get(0) != State.DISCONNECTED) {
@@ -152,14 +158,15 @@ public class NetworkState {
for (int i = 1; i < mStateDepository.size(); i++) {
State preState = mStateDepository.get(i-1);
State curState = mStateDepository.get(i);
- if ((preState == State.DISCONNECTED) && ((curState == State.CONNECTING) ||
- (curState == State.CONNECTED) || (curState == State.DISCONNECTED))) {
+ if (preState == curState) {
continue;
- } else if ((preState == State.CONNECTING) && (curState == State.CONNECTED)) {
- continue;
- } else if ((preState == State.CONNECTED) && (curState == State.CONNECTED)) {
+ }
+ if ((preState == State.DISCONNECTED) && ((curState == State.CONNECTING) ||
+ (curState == State.CONNECTED))) {
continue;
- } else {
+ } else if ((preState == State.CONNECTING) && (curState == State.CONNECTED)) {
+ continue;
+ } else {
mReason += " Transition state from " + preState.toString() + " to " +
curState.toString() + " is not valid.";
return false;