summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Android.mk3
-rw-r--r--api/current.txt33
-rw-r--r--api/system-current.txt33
-rw-r--r--core/java/android/app/Notification.java13
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java47
-rw-r--r--core/java/android/app/admin/IDevicePolicyManager.aidl4
-rw-r--r--core/java/android/hardware/ICameraService.aidl6
-rw-r--r--core/java/android/hardware/ICameraServiceProxy.aidl30
-rw-r--r--core/java/android/hardware/fingerprint/FingerprintManager.java6
-rw-r--r--core/java/android/hardware/fingerprint/IFingerprintDaemon.aidl37
-rw-r--r--core/java/android/hardware/fingerprint/IFingerprintDaemonCallback.aidl29
-rw-r--r--core/java/android/net/NetworkAgent.java20
-rw-r--r--core/java/android/provider/ContactsContract.java21
-rw-r--r--core/java/android/view/TextureView.java158
-rw-r--r--core/java/android/view/ThreadedRenderer.java1
-rw-r--r--core/java/android/view/ViewRootImpl.java9
-rw-r--r--core/java/android/view/WindowManager.java7
-rw-r--r--core/java/android/view/WindowManagerPolicy.java17
-rw-r--r--core/java/android/widget/Editor.java127
-rw-r--r--core/java/com/android/internal/logging/MetricsConstants.java1
-rw-r--r--core/jni/android_media_AudioFormat.h20
-rw-r--r--core/jni/android_media_AudioRecord.cpp8
-rw-r--r--core/res/AndroidManifest.xml2
-rw-r--r--core/res/res/drawable-hdpi/text_select_handle_left_mtrl_alpha.pngbin368 -> 14872 bytes
-rw-r--r--core/res/res/drawable-hdpi/text_select_handle_right_mtrl_alpha.pngbin349 -> 14852 bytes
-rw-r--r--core/res/res/drawable-mdpi/text_select_handle_left_mtrl_alpha.pngbin267 -> 14716 bytes
-rw-r--r--core/res/res/drawable-mdpi/text_select_handle_right_mtrl_alpha.pngbin241 -> 14690 bytes
-rw-r--r--core/res/res/drawable-xhdpi/text_select_handle_left_mtrl_alpha.pngbin467 -> 14969 bytes
-rw-r--r--core/res/res/drawable-xhdpi/text_select_handle_right_mtrl_alpha.pngbin466 -> 14960 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/text_select_handle_left_mtrl_alpha.pngbin684 -> 15209 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/text_select_handle_right_mtrl_alpha.pngbin630 -> 15200 bytes
-rw-r--r--core/res/res/drawable-xxxhdpi/text_select_handle_left_mtrl_alpha.pngbin889 -> 15429 bytes
-rw-r--r--core/res/res/drawable-xxxhdpi/text_select_handle_right_mtrl_alpha.pngbin858 -> 15425 bytes
-rwxr-xr-xcore/res/res/values/config.xml5
-rwxr-xr-xcore/res/res/values/symbols.xml2
-rw-r--r--graphics/java/android/graphics/Bitmap.java5
-rw-r--r--libs/hwui/Caches.cpp4
-rw-r--r--libs/hwui/DeferredLayerUpdater.cpp1
-rw-r--r--libs/hwui/renderstate/RenderState.cpp3
-rw-r--r--libs/hwui/renderthread/CanvasContext.cpp15
-rw-r--r--libs/hwui/renderthread/CanvasContext.h2
-rw-r--r--libs/hwui/renderthread/EglManager.cpp38
-rw-r--r--libs/hwui/renderthread/EglManager.h10
-rw-r--r--media/java/android/media/AudioDeviceCallback.java20
-rw-r--r--media/java/android/media/AudioDeviceInfo.java2
-rw-r--r--media/java/android/media/AudioFormat.java69
-rw-r--r--media/java/android/media/AudioManager.java50
-rw-r--r--media/java/android/media/AudioRecord.java32
-rw-r--r--media/java/android/media/AudioTrack.java57
-rw-r--r--packages/Keyguard/res/values-h650dp/dimens.xml2
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java4
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java531
-rw-r--r--packages/StatementService/src/com/android/statementservice/retriever/AbstractAsset.java6
-rw-r--r--packages/StatementService/src/com/android/statementservice/retriever/AndroidAppAsset.java6
-rw-r--r--packages/StatementService/src/com/android/statementservice/retriever/DirectStatementRetriever.java10
-rw-r--r--packages/StatementService/src/com/android/statementservice/retriever/URLFetcher.java13
-rw-r--r--packages/StatementService/src/com/android/statementservice/retriever/Utils.java2
-rw-r--r--packages/StatementService/src/com/android/statementservice/retriever/WebAsset.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/ObservableScrollView.java2
-rw-r--r--services/backup/java/com/android/server/backup/BackupManagerService.java165
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java9
-rw-r--r--services/core/java/com/android/server/am/ActivityStackSupervisor.java26
-rw-r--r--services/core/java/com/android/server/am/RecentTasks.java11
-rw-r--r--services/core/java/com/android/server/am/TaskRecord.java28
-rw-r--r--services/core/java/com/android/server/audio/AudioService.java2
-rw-r--r--services/core/java/com/android/server/camera/CameraService.java33
-rw-r--r--services/core/java/com/android/server/fingerprint/FingerprintService.java456
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java8
-rw-r--r--services/core/java/com/android/server/pm/PermissionsState.java4
-rw-r--r--services/core/java/com/android/server/pm/Settings.java173
-rw-r--r--services/core/java/com/android/server/policy/PhoneWindowManager.java78
-rw-r--r--services/core/java/com/android/server/wm/AccessibilityController.java2
-rw-r--r--services/core/java/com/android/server/wm/InputConsumerImpl.java (renamed from services/core/java/com/android/server/wm/FakeWindowImpl.java)38
-rw-r--r--services/core/java/com/android/server/wm/InputMonitor.java24
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java35
-rw-r--r--services/core/jni/Android.mk1
-rw-r--r--services/core/jni/onload.cpp2
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java35
-rw-r--r--services/usage/java/com/android/server/usage/IntervalStats.java5
-rw-r--r--services/usage/java/com/android/server/usage/UsageStatsService.java57
-rw-r--r--services/usage/java/com/android/server/usage/UserUsageStatsService.java25
-rw-r--r--services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java30
-rw-r--r--tests/RenderScriptTests/FBOTest/src/com/android/fbotest/fbosync.rs3
-rw-r--r--tests/RenderScriptTests/FBOTest/src/com/android/fbotest/fbotest.rs2
-rw-r--r--tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/simplemodel.rs4
-rw-r--r--tests/RenderScriptTests/PerfTest/src/com/android/perftest/rsbench.rs4
-rw-r--r--tests/RenderScriptTests/PerfTest/src/com/android/perftest/text_test.rs1
-rw-r--r--tests/RenderScriptTests/PerfTest/src/com/android/perftest/ui_test.rs2
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/params.rsh11
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/render.rs2
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/scenegraph_objects.rsh10
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/transform.rs4
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/testapp/test_app.rs2
-rw-r--r--tests/RenderScriptTests/ShadersTest/src/com/android/shaderstest/shaderstest.rs1
-rw-r--r--tools/layoutlib/bridge/src/android/content/res/BridgeResources.java15
-rw-r--r--tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java3
-rw-r--r--tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java83
-rw-r--r--tools/layoutlib/bridge/src/android/view/View_Delegate.java13
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java116
-rw-r--r--tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java9
-rw-r--r--tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java28
-rw-r--r--tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java4
-rw-r--r--tools/layoutlib/create/src/com/android/tools/layoutlib/create/ICreateInfo.java8
-rw-r--r--tools/layoutlib/create/src/com/android/tools/layoutlib/create/InjectMethodRunnables.java4
104 files changed, 1876 insertions, 1230 deletions
diff --git a/Android.mk b/Android.mk
index 146afe0..59c1878 100644
--- a/Android.mk
+++ b/Android.mk
@@ -146,6 +146,7 @@ LOCAL_SRC_FILES += \
core/java/android/database/IContentObserver.aidl \
core/java/android/hardware/ICameraService.aidl \
core/java/android/hardware/ICameraServiceListener.aidl \
+ core/java/android/hardware/ICameraServiceProxy.aidl \
core/java/android/hardware/ICamera.aidl \
core/java/android/hardware/ICameraClient.aidl \
core/java/android/hardware/IConsumerIrService.aidl \
@@ -155,6 +156,8 @@ LOCAL_SRC_FILES += \
core/java/android/hardware/display/IDisplayManager.aidl \
core/java/android/hardware/display/IDisplayManagerCallback.aidl \
core/java/android/hardware/display/IVirtualDisplayCallback.aidl \
+ core/java/android/hardware/fingerprint/IFingerprintDaemon.aidl \
+ core/java/android/hardware/fingerprint/IFingerprintDaemonCallback.aidl \
core/java/android/hardware/fingerprint/IFingerprintService.aidl \
core/java/android/hardware/fingerprint/IFingerprintServiceReceiver.aidl \
core/java/android/hardware/hdmi/IHdmiControlCallback.aidl \
diff --git a/api/current.txt b/api/current.txt
index 97db5aa..bbdb878 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5773,7 +5773,7 @@ package android.app.admin {
method public void setPasswordMinimumSymbols(android.content.ComponentName, int);
method public void setPasswordMinimumUpperCase(android.content.ComponentName, int);
method public void setPasswordQuality(android.content.ComponentName, int);
- method public boolean setPermissionGranted(android.content.ComponentName, java.lang.String, java.lang.String, boolean);
+ method public boolean setPermissionGrantState(android.content.ComponentName, java.lang.String, java.lang.String, int);
method public void setPermissionPolicy(android.content.ComponentName, int);
method public boolean setPermittedAccessibilityServices(android.content.ComponentName, java.util.List<java.lang.String>);
method public boolean setPermittedInputMethods(android.content.ComponentName, java.util.List<java.lang.String>);
@@ -5862,6 +5862,9 @@ package android.app.admin {
field public static final int PASSWORD_QUALITY_NUMERIC_COMPLEX = 196608; // 0x30000
field public static final int PASSWORD_QUALITY_SOMETHING = 65536; // 0x10000
field public static final int PASSWORD_QUALITY_UNSPECIFIED = 0; // 0x0
+ field public static final int PERMISSION_GRANT_STATE_DEFAULT = 0; // 0x0
+ field public static final int PERMISSION_GRANT_STATE_DENIED = 2; // 0x2
+ field public static final int PERMISSION_GRANT_STATE_GRANTED = 1; // 0x1
field public static final int PERMISSION_POLICY_AUTO_DENY = 2; // 0x2
field public static final int PERMISSION_POLICY_AUTO_GRANT = 1; // 0x1
field public static final int PERMISSION_POLICY_PROMPT = 0; // 0x0
@@ -14798,8 +14801,8 @@ package android.media {
ctor public AudioFormat.Builder();
ctor public AudioFormat.Builder(android.media.AudioFormat);
method public android.media.AudioFormat build();
- method public android.media.AudioFormat.Builder setChannelIndexMask(int) throws java.lang.IllegalArgumentException;
- method public android.media.AudioFormat.Builder setChannelMask(int) throws java.lang.IllegalArgumentException;
+ method public android.media.AudioFormat.Builder setChannelIndexMask(int);
+ method public android.media.AudioFormat.Builder setChannelMask(int);
method public android.media.AudioFormat.Builder setEncoding(int) throws java.lang.IllegalArgumentException;
method public android.media.AudioFormat.Builder setSampleRate(int) throws java.lang.IllegalArgumentException;
}
@@ -14961,11 +14964,11 @@ package android.media {
method public int getAudioFormat();
method public int getAudioSessionId();
method public int getAudioSource();
+ method public int getBufferSizeInFrames();
method public int getChannelConfiguration();
method public int getChannelCount();
method public android.media.AudioFormat getFormat();
method public static int getMinBufferSize(int, int, int);
- method public int getNativeFrameCount() throws java.lang.IllegalStateException;
method public int getNotificationMarkerPosition();
method public int getPositionNotificationPeriod();
method public android.media.AudioDeviceInfo getPreferredDevice();
@@ -15034,13 +15037,14 @@ package android.media {
method public void flush();
method public int getAudioFormat();
method public int getAudioSessionId();
+ method public int getBufferSizeInFrames();
method public int getChannelConfiguration();
method public int getChannelCount();
method public android.media.AudioFormat getFormat();
method public static float getMaxVolume();
method public static int getMinBufferSize(int, int, int);
method public static float getMinVolume();
- method public int getNativeFrameCount() throws java.lang.IllegalStateException;
+ method protected deprecated int getNativeFrameCount();
method public static int getNativeOutputSampleRate(int);
method public int getNotificationMarkerPosition();
method public int getPlayState();
@@ -25176,13 +25180,6 @@ package android.provider {
field public static final int TYPE_KEEP_TOGETHER = 1; // 0x1
}
- public static final class ContactsContract.Authorization {
- ctor public ContactsContract.Authorization();
- field public static final java.lang.String AUTHORIZATION_METHOD = "authorize";
- field public static final java.lang.String KEY_AUTHORIZED_URI = "authorized_uri";
- field public static final java.lang.String KEY_URI_TO_AUTHORIZE = "uri_to_authorize";
- }
-
protected static abstract interface ContactsContract.BaseSyncColumns {
field public static final java.lang.String SYNC1 = "sync1";
field public static final java.lang.String SYNC2 = "sync2";
@@ -25589,6 +25586,8 @@ package android.provider {
}
protected static abstract interface ContactsContract.DataColumns {
+ field public static final java.lang.String CARRIER_PRESENCE = "carrier_presence";
+ field public static final int CARRIER_PRESENCE_VT_CAPABLE = 1; // 0x1
field public static final java.lang.String DATA1 = "data1";
field public static final java.lang.String DATA10 = "data10";
field public static final java.lang.String DATA11 = "data11";
@@ -25827,16 +25826,6 @@ package android.provider {
field public static final android.net.Uri CONTENT_URI;
}
- public static final class ContactsContract.ProviderStatus {
- field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/provider_status";
- field public static final android.net.Uri CONTENT_URI;
- field public static final java.lang.String STATUS = "status";
- field public static final int STATUS_CHANGING_LOCALE = 3; // 0x3
- field public static final int STATUS_NORMAL = 0; // 0x0
- field public static final int STATUS_NO_ACCOUNTS_NO_CONTACTS = 4; // 0x4
- field public static final int STATUS_UPGRADING = 1; // 0x1
- }
-
public static final class ContactsContract.QuickContact {
ctor public ContactsContract.QuickContact();
method public static void showQuickContact(android.content.Context, android.view.View, android.net.Uri, int, java.lang.String[]);
diff --git a/api/system-current.txt b/api/system-current.txt
index 10bf1ae..1a3673d 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -5882,7 +5882,7 @@ package android.app.admin {
method public void setPasswordMinimumSymbols(android.content.ComponentName, int);
method public void setPasswordMinimumUpperCase(android.content.ComponentName, int);
method public void setPasswordQuality(android.content.ComponentName, int);
- method public boolean setPermissionGranted(android.content.ComponentName, java.lang.String, java.lang.String, boolean);
+ method public boolean setPermissionGrantState(android.content.ComponentName, java.lang.String, java.lang.String, int);
method public void setPermissionPolicy(android.content.ComponentName, int);
method public boolean setPermittedAccessibilityServices(android.content.ComponentName, java.util.List<java.lang.String>);
method public boolean setPermittedInputMethods(android.content.ComponentName, java.util.List<java.lang.String>);
@@ -5976,6 +5976,9 @@ package android.app.admin {
field public static final int PASSWORD_QUALITY_NUMERIC_COMPLEX = 196608; // 0x30000
field public static final int PASSWORD_QUALITY_SOMETHING = 65536; // 0x10000
field public static final int PASSWORD_QUALITY_UNSPECIFIED = 0; // 0x0
+ field public static final int PERMISSION_GRANT_STATE_DEFAULT = 0; // 0x0
+ field public static final int PERMISSION_GRANT_STATE_DENIED = 2; // 0x2
+ field public static final int PERMISSION_GRANT_STATE_GRANTED = 1; // 0x1
field public static final int PERMISSION_POLICY_AUTO_DENY = 2; // 0x2
field public static final int PERMISSION_POLICY_AUTO_GRANT = 1; // 0x1
field public static final int PERMISSION_POLICY_PROMPT = 0; // 0x0
@@ -16024,8 +16027,8 @@ package android.media {
ctor public AudioFormat.Builder();
ctor public AudioFormat.Builder(android.media.AudioFormat);
method public android.media.AudioFormat build();
- method public android.media.AudioFormat.Builder setChannelIndexMask(int) throws java.lang.IllegalArgumentException;
- method public android.media.AudioFormat.Builder setChannelMask(int) throws java.lang.IllegalArgumentException;
+ method public android.media.AudioFormat.Builder setChannelIndexMask(int);
+ method public android.media.AudioFormat.Builder setChannelMask(int);
method public android.media.AudioFormat.Builder setEncoding(int) throws java.lang.IllegalArgumentException;
method public android.media.AudioFormat.Builder setSampleRate(int) throws java.lang.IllegalArgumentException;
}
@@ -16197,11 +16200,11 @@ package android.media {
method public int getAudioFormat();
method public int getAudioSessionId();
method public int getAudioSource();
+ method public int getBufferSizeInFrames();
method public int getChannelConfiguration();
method public int getChannelCount();
method public android.media.AudioFormat getFormat();
method public static int getMinBufferSize(int, int, int);
- method public int getNativeFrameCount() throws java.lang.IllegalStateException;
method public int getNotificationMarkerPosition();
method public int getPositionNotificationPeriod();
method public android.media.AudioDeviceInfo getPreferredDevice();
@@ -16272,13 +16275,14 @@ package android.media {
method public void flush();
method public int getAudioFormat();
method public int getAudioSessionId();
+ method public int getBufferSizeInFrames();
method public int getChannelConfiguration();
method public int getChannelCount();
method public android.media.AudioFormat getFormat();
method public static float getMaxVolume();
method public static int getMinBufferSize(int, int, int);
method public static float getMinVolume();
- method public int getNativeFrameCount() throws java.lang.IllegalStateException;
+ method protected deprecated int getNativeFrameCount();
method public static int getNativeOutputSampleRate(int);
method public int getNotificationMarkerPosition();
method public int getPlayState();
@@ -27102,13 +27106,6 @@ package android.provider {
field public static final int TYPE_KEEP_TOGETHER = 1; // 0x1
}
- public static final class ContactsContract.Authorization {
- ctor public ContactsContract.Authorization();
- field public static final java.lang.String AUTHORIZATION_METHOD = "authorize";
- field public static final java.lang.String KEY_AUTHORIZED_URI = "authorized_uri";
- field public static final java.lang.String KEY_URI_TO_AUTHORIZE = "uri_to_authorize";
- }
-
protected static abstract interface ContactsContract.BaseSyncColumns {
field public static final java.lang.String SYNC1 = "sync1";
field public static final java.lang.String SYNC2 = "sync2";
@@ -27515,6 +27512,8 @@ package android.provider {
}
protected static abstract interface ContactsContract.DataColumns {
+ field public static final java.lang.String CARRIER_PRESENCE = "carrier_presence";
+ field public static final int CARRIER_PRESENCE_VT_CAPABLE = 1; // 0x1
field public static final java.lang.String DATA1 = "data1";
field public static final java.lang.String DATA10 = "data10";
field public static final java.lang.String DATA11 = "data11";
@@ -27753,16 +27752,6 @@ package android.provider {
field public static final android.net.Uri CONTENT_URI;
}
- public static final class ContactsContract.ProviderStatus {
- field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/provider_status";
- field public static final android.net.Uri CONTENT_URI;
- field public static final java.lang.String STATUS = "status";
- field public static final int STATUS_CHANGING_LOCALE = 3; // 0x3
- field public static final int STATUS_NORMAL = 0; // 0x0
- field public static final int STATUS_NO_ACCOUNTS_NO_CONTACTS = 4; // 0x4
- field public static final int STATUS_UPGRADING = 1; // 0x1
- }
-
public static final class ContactsContract.QuickContact {
ctor public ContactsContract.QuickContact();
method public static void showQuickContact(android.content.Context, android.view.View, android.net.Uri, int, java.lang.String[]);
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 3309443..96c6878 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -1366,7 +1366,9 @@ public class Notification implements Parcelable
int version = parcel.readInt();
when = parcel.readLong();
- mSmallIcon = Icon.CREATOR.createFromParcel(parcel);
+ if (parcel.readInt() != 0) {
+ mSmallIcon = Icon.CREATOR.createFromParcel(parcel);
+ }
number = parcel.readInt();
if (parcel.readInt() != 0) {
contentIntent = PendingIntent.CREATOR.createFromParcel(parcel);
@@ -1590,7 +1592,12 @@ public class Notification implements Parcelable
parcel.writeInt(1);
parcel.writeLong(when);
- mSmallIcon.writeToParcel(parcel, 0);
+ if (mSmallIcon != null) {
+ parcel.writeInt(1);
+ mSmallIcon.writeToParcel(parcel, 0);
+ } else {
+ parcel.writeInt(0);
+ }
parcel.writeInt(number);
if (contentIntent != null) {
parcel.writeInt(1);
@@ -3241,7 +3248,7 @@ public class Notification implements Parcelable
Notification n = new Notification();
n.when = mWhen;
n.mSmallIcon = mSmallIcon;
- if (mSmallIcon.getType() == Icon.TYPE_RESOURCE) {
+ if (mSmallIcon != null && mSmallIcon.getType() == Icon.TYPE_RESOURCE) {
n.icon = mSmallIcon.getResId();
}
n.iconLevel = mSmallIconLevel;
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 55ff85a..a8f2311 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -825,6 +825,23 @@ public class DevicePolicyManager {
*/
public static final int PERMISSION_POLICY_AUTO_DENY = 2;
+ /**
+ * Runtime permission state: The user can manage the permission
+ * through the UI.
+ */
+ public static final int PERMISSION_GRANT_STATE_DEFAULT = 0;
+
+ /**
+ * Runtime permission state: The permission is granted to the app
+ * and the user cannot manage the permission through the UI.
+ */
+ public static final int PERMISSION_GRANT_STATE_GRANTED = 1;
+
+ /**
+ * Runtime permission state: The permission is denied to the app
+ * and the user cannot manage the permission through the UI.
+ */
+ public static final int PERMISSION_GRANT_STATE_DENIED = 2;
/**
* Return true if the given administrator component is currently
@@ -4401,21 +4418,31 @@ public class DevicePolicyManager {
}
/**
- * Grants or revokes a runtime permission to a specific application so that the user
- * does not have to be prompted. This might affect all permissions in a group that the
- * runtime permission belongs to. This method can only be called by a profile or device
- * owner.
+ * Sets the grant state of a runtime permission for a specific application. The state
+ * can be {@link #PERMISSION_GRANT_STATE_DEFAULT default} in which a user can manage it
+ * through the UI, {@link #PERMISSION_GRANT_STATE_DENIED denied}, in which the permission
+ * is denied and the user cannot manage it through the UI, and {@link
+ * #PERMISSION_GRANT_STATE_GRANTED granted} in which the permission is granted and the
+ * user cannot manage it through the UI. This might affect all permissions in a
+ * group that the runtime permission belongs to. This method can only be called
+ * by a profile or device owner.
+ *
* @param admin Which profile or device owner this request is associated with.
* @param packageName The application to grant or revoke a permission to.
* @param permission The permission to grant or revoke.
- * @param granted Whether or not to grant the permission. If false, all permissions in the
- * associated permission group will be denied.
- * @return whether the permission was successfully granted or revoked
+ * @param grantState The permission grant state which is one of {@link
+ * #PERMISSION_GRANT_STATE_DENIED}, {@link #PERMISSION_GRANT_STATE_DEFAULT},
+ * {@link #PERMISSION_GRANT_STATE_GRANTED},
+ * @return whether the permission was successfully granted or revoked.
+ *
+ * @see #PERMISSION_GRANT_STATE_DENIED
+ * @see #PERMISSION_GRANT_STATE_DEFAULT
+ * @see #PERMISSION_GRANT_STATE_GRANTED
*/
- public boolean setPermissionGranted(ComponentName admin, String packageName,
- String permission, boolean granted) {
+ public boolean setPermissionGrantState(ComponentName admin, String packageName,
+ String permission, int grantState) {
try {
- return mService.setPermissionGranted(admin, packageName, permission, granted);
+ return mService.setPermissionGrantState(admin, packageName, permission, grantState);
} catch (RemoteException re) {
Log.w(TAG, "Failed talking with device policy service", re);
return false;
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 24ef604..10b0941 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -234,6 +234,6 @@ interface IDevicePolicyManager {
void setPermissionPolicy(in ComponentName admin, int policy);
int getPermissionPolicy(in ComponentName admin);
- boolean setPermissionGranted(in ComponentName admin, String packageName, String permission,
- boolean granted);
+ boolean setPermissionGrantState(in ComponentName admin, String packageName,
+ String permission, int grantState);
}
diff --git a/core/java/android/hardware/ICameraService.aidl b/core/java/android/hardware/ICameraService.aidl
index 9201b61..c933f92 100644
--- a/core/java/android/hardware/ICameraService.aidl
+++ b/core/java/android/hardware/ICameraService.aidl
@@ -25,7 +25,11 @@ import android.hardware.camera2.utils.BinderHolder;
import android.hardware.ICameraServiceListener;
import android.hardware.CameraInfo;
-/** @hide */
+/**
+ * Binder interface for the native camera service running in mediaserver.
+ *
+ * @hide
+ */
interface ICameraService
{
/**
diff --git a/core/java/android/hardware/ICameraServiceProxy.aidl b/core/java/android/hardware/ICameraServiceProxy.aidl
new file mode 100644
index 0000000..0bb24bc
--- /dev/null
+++ b/core/java/android/hardware/ICameraServiceProxy.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2015 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.hardware;
+
+/**
+ * Binder interface for the camera service proxy running in system_server.
+ *
+ * @hide
+ */
+interface ICameraServiceProxy
+{
+ /**
+ * Ping the service proxy to update the valid users for the camera service.
+ */
+ oneway void pingForUserUpdate();
+}
diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java
index 338bd76..caf21d5 100644
--- a/core/java/android/hardware/fingerprint/FingerprintManager.java
+++ b/core/java/android/hardware/fingerprint/FingerprintManager.java
@@ -729,12 +729,6 @@ public class FingerprintManager {
}
}
- private void clearCallbacks() {
- mAuthenticationCallback = null;
- mEnrollmentCallback = null;
- mRemovalCallback = null;
- }
-
private void cancelEnrollment() {
if (mService != null) try {
mService.cancelEnrollment(mToken);
diff --git a/core/java/android/hardware/fingerprint/IFingerprintDaemon.aidl b/core/java/android/hardware/fingerprint/IFingerprintDaemon.aidl
new file mode 100644
index 0000000..186d36e
--- /dev/null
+++ b/core/java/android/hardware/fingerprint/IFingerprintDaemon.aidl
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2015 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.hardware.fingerprint;
+
+import android.hardware.fingerprint.IFingerprintDaemonCallback;
+
+/**
+ * Communication channel from FingerprintService to FingerprintDaemon (fingerprintd)
+ * @hide
+ */
+
+interface IFingerprintDaemon {
+ int authenticate(long sessionId, int groupId);
+ int cancelAuthentication();
+ int enroll(in byte [] token, int groupId, int timeout);
+ int cancelEnrollment();
+ long preEnroll();
+ int remove(int fingerId, int groupId);
+ long getAuthenticatorId();
+ int setActiveGroup(int groupId, in byte[] path);
+ long openHal();
+ int closeHal();
+ void init(IFingerprintDaemonCallback callback);
+}
diff --git a/core/java/android/hardware/fingerprint/IFingerprintDaemonCallback.aidl b/core/java/android/hardware/fingerprint/IFingerprintDaemonCallback.aidl
new file mode 100644
index 0000000..bd8ad6e
--- /dev/null
+++ b/core/java/android/hardware/fingerprint/IFingerprintDaemonCallback.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2014 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.hardware.fingerprint;
+
+/**
+ * Communication channel from the fingerprintd back to FingerprintService.
+ * @hide
+ */
+ interface IFingerprintDaemonCallback {
+ void onEnrollResult(long deviceId, int fingerId, int groupId, int remaining);
+ void onAcquired(long deviceId, int acquiredInfo);
+ void onAuthenticated(long deviceId, int fingerId, int groupId);
+ void onError(long deviceId, int error);
+ void onRemoved(long deviceId, int fingerId, int groupId);
+ void onEnumerate(long deviceId, in int [] fingerIds, in int [] groupIds);
+}
diff --git a/core/java/android/net/NetworkAgent.java b/core/java/android/net/NetworkAgent.java
index 9c3a623..e6fc1ea 100644
--- a/core/java/android/net/NetworkAgent.java
+++ b/core/java/android/net/NetworkAgent.java
@@ -27,6 +27,7 @@ import com.android.internal.util.AsyncChannel;
import com.android.internal.util.Protocol;
import java.util.ArrayList;
+import java.util.concurrent.atomic.AtomicBoolean;
/**
* A Utility class for handling for communicating between bearer-specific
@@ -51,6 +52,8 @@ public abstract class NetworkAgent extends Handler {
private final ArrayList<Message>mPreConnectedQueue = new ArrayList<Message>();
private volatile long mLastBwRefreshTime = 0;
private static final long BW_REFRESH_MIN_WIN_MS = 500;
+ private boolean mPollLceScheduled = false;
+ private AtomicBoolean mPollLcePending = new AtomicBoolean(false);
private static final int BASE = Protocol.BASE_NETWORK_AGENT;
@@ -207,11 +210,23 @@ public abstract class NetworkAgent extends Handler {
break;
}
case CMD_REQUEST_BANDWIDTH_UPDATE: {
+ long currentTimeMs = System.currentTimeMillis();
if (VDBG) {
log("CMD_REQUEST_BANDWIDTH_UPDATE request received.");
}
- if (System.currentTimeMillis() > (mLastBwRefreshTime + BW_REFRESH_MIN_WIN_MS)) {
- pollLceData();
+ if (currentTimeMs >= (mLastBwRefreshTime + BW_REFRESH_MIN_WIN_MS)) {
+ mPollLceScheduled = false;
+ if (mPollLcePending.getAndSet(true) == false) {
+ pollLceData();
+ }
+ } else {
+ // deliver the request at a later time rather than discard it completely.
+ if (!mPollLceScheduled) {
+ long waitTime = mLastBwRefreshTime + BW_REFRESH_MIN_WIN_MS -
+ currentTimeMs + 1;
+ mPollLceScheduled = sendEmptyMessageDelayed(
+ CMD_REQUEST_BANDWIDTH_UPDATE, waitTime);
+ }
}
break;
}
@@ -260,6 +275,7 @@ public abstract class NetworkAgent extends Handler {
* Called by the bearer code when it has new NetworkCapabilities data.
*/
public void sendNetworkCapabilities(NetworkCapabilities networkCapabilities) {
+ mPollLcePending.set(false);
mLastBwRefreshTime = System.currentTimeMillis();
queueOrSendMessage(EVENT_NETWORK_CAPABILITIES_CHANGED,
new NetworkCapabilities(networkCapabilities));
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index e07e846..76a5f967 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -230,6 +230,8 @@ public final class ContactsContract {
* }
* </pre>
* </p>
+ *
+ * @hide
*/
public static final class Authorization {
/**
@@ -4067,6 +4069,21 @@ public final class ContactsContract {
public static final String SYNC3 = "data_sync3";
/** Generic column for use by sync adapters. */
public static final String SYNC4 = "data_sync4";
+
+ /**
+ * Carrier presence information.
+ * <P>
+ * Type: INTEGER (A bitmask of CARRIER_PRESENCE_* fields)
+ * </P>
+ */
+ public static final String CARRIER_PRESENCE = "carrier_presence";
+
+ /**
+ * Bitmask flags for CARRIER_PRESENCE column. Each value represents
+ * a bit (or a set of bits) which may be set independently of each
+ * other.
+ */
+ public static final int CARRIER_PRESENCE_VT_CAPABLE = 0x01;
}
/**
@@ -7913,6 +7930,8 @@ public final class ContactsContract {
/**
* API for inquiring about the general status of the provider.
+ *
+ * @hide
*/
public static final class ProviderStatus {
@@ -8261,7 +8280,7 @@ public final class ContactsContract {
/**
* Constructs a QuickContacts intent based on an incoming intent for DevicePolicyManager
* to strip off anything not necessary.
- *
+ *
* @hide
*/
public static Intent rebuildManagedQuickContactsIntent(String lookupKey, long contactId,
diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java
index d70712a..cdc196e 100644
--- a/core/java/android/view/TextureView.java
+++ b/core/java/android/view/TextureView.java
@@ -30,21 +30,21 @@ import android.util.Log;
* <p>A TextureView can be used to display a content stream. Such a content
* stream can for instance be a video or an OpenGL scene. The content stream
* can come from the application's process as well as a remote process.</p>
- *
+ *
* <p>TextureView can only be used in a hardware accelerated window. When
* rendered in software, TextureView will draw nothing.</p>
- *
+ *
* <p>Unlike {@link SurfaceView}, TextureView does not create a separate
* window but behaves as a regular View. This key difference allows a
* TextureView to be moved, transformed, animated, etc. For instance, you
* can make a TextureView semi-translucent by calling
* <code>myView.setAlpha(0.5f)</code>.</p>
- *
+ *
* <p>Using a TextureView is simple: all you need to do is get its
* {@link SurfaceTexture}. The {@link SurfaceTexture} can then be used to
- * render content. The following example demonstrates how to render the
+ * render content. The following example demonstrates how to render the
* camera preview into a TextureView:</p>
- *
+ *
* <pre>
* public class LiveCameraActivity extends Activity implements TextureView.SurfaceTextureListener {
* private Camera mCamera;
@@ -85,19 +85,19 @@ import android.util.Log;
* }
* }
* </pre>
- *
+ *
* <p>A TextureView's SurfaceTexture can be obtained either by invoking
* {@link #getSurfaceTexture()} or by using a {@link SurfaceTextureListener}.
* It is important to know that a SurfaceTexture is available only after the
* TextureView is attached to a window (and {@link #onAttachedToWindow()} has
* been invoked.) It is therefore highly recommended you use a listener to
* be notified when the SurfaceTexture becomes available.</p>
- *
+ *
* <p>It is important to note that only one producer can use the TextureView.
* For instance, if you use a TextureView to display the camera preview, you
* cannot use {@link #lockCanvas()} to draw onto the TextureView at the same
* time.</p>
- *
+ *
* @see SurfaceView
* @see SurfaceTexture
*/
@@ -127,7 +127,7 @@ public class TextureView extends View {
/**
* Creates a new TextureView.
- *
+ *
* @param context The context to associate this view with.
*/
public TextureView(Context context) {
@@ -137,7 +137,7 @@ public class TextureView extends View {
/**
* Creates a new TextureView.
- *
+ *
* @param context The context to associate this view with.
* @param attrs The attributes of the XML tag that is inflating the view.
*/
@@ -148,7 +148,7 @@ public class TextureView extends View {
/**
* Creates a new TextureView.
- *
+ *
* @param context The context to associate this view with.
* @param attrs The attributes of the XML tag that is inflating the view.
* @param defStyleAttr An attribute in the current theme that contains a
@@ -193,7 +193,7 @@ public class TextureView extends View {
/**
* Indicates whether the content of this TextureView is opaque. The
* content is assumed to be opaque by default.
- *
+ *
* @param opaque True if the content of this TextureView is opaque,
* false otherwise
*/
@@ -258,7 +258,7 @@ public class TextureView extends View {
* considered to act as a hardware layer. The optional paint supplied to this
* method will however be taken into account when rendering the content of
* this TextureView.
- *
+ *
* @param layerType The ype of layer to use with this view, must be one of
* {@link #LAYER_TYPE_NONE}, {@link #LAYER_TYPE_SOFTWARE} or
* {@link #LAYER_TYPE_HARDWARE}
@@ -297,7 +297,7 @@ public class TextureView extends View {
/**
* Subclasses of TextureView cannot do their own rendering
* with the {@link Canvas} object.
- *
+ *
* @param canvas The Canvas to which the View is rendered.
*/
@Override
@@ -312,7 +312,7 @@ public class TextureView extends View {
/**
* Subclasses of TextureView cannot do their own rendering
* with the {@link Canvas} object.
- *
+ *
* @param canvas The Canvas to which the View is rendered.
*/
@Override
@@ -435,7 +435,7 @@ public class TextureView extends View {
return;
}
}
-
+
mLayer.prepare(getWidth(), getHeight(), mOpaque);
mLayer.updateSurfaceTexture();
@@ -449,17 +449,17 @@ public class TextureView extends View {
* The specified transform applies to the underlying surface
* texture and does not affect the size or position of the view
* itself, only of its content.</p>
- *
+ *
* <p>Some transforms might prevent the content from drawing
* all the pixels contained within this view's bounds. In such
* situations, make sure this texture view is not marked opaque.</p>
- *
+ *
* @param transform The transform to apply to the content of
* this view.
- *
- * @see #getTransform(android.graphics.Matrix)
- * @see #isOpaque()
- * @see #setOpaque(boolean)
+ *
+ * @see #getTransform(android.graphics.Matrix)
+ * @see #isOpaque()
+ * @see #setOpaque(boolean)
*/
public void setTransform(Matrix transform) {
mMatrix.set(transform);
@@ -469,14 +469,14 @@ public class TextureView extends View {
/**
* Returns the transform associated with this texture view.
- *
+ *
* @param transform The {@link Matrix} in which to copy the current
* transform. Can be null.
- *
+ *
* @return The specified matrix if not null or a new {@link Matrix}
* instance otherwise.
- *
- * @see #setTransform(android.graphics.Matrix)
+ *
+ * @see #setTransform(android.graphics.Matrix)
*/
public Matrix getTransform(Matrix transform) {
if (transform == null) {
@@ -499,21 +499,21 @@ public class TextureView extends View {
* <p>Returns a {@link android.graphics.Bitmap} representation of the content
* of the associated surface texture. If the surface texture is not available,
* this method returns null.</p>
- *
+ *
* <p>The bitmap returned by this method uses the {@link Bitmap.Config#ARGB_8888}
* pixel format and its dimensions are the same as this view's.</p>
- *
+ *
* <p><strong>Do not</strong> invoke this method from a drawing method
* ({@link #onDraw(android.graphics.Canvas)} for instance).</p>
- *
+ *
* <p>If an error occurs during the copy, an empty bitmap will be returned.</p>
- *
+ *
* @return A valid {@link Bitmap.Config#ARGB_8888} bitmap, or null if the surface
* texture is not available or the width &lt;= 0 or the height &lt;= 0
- *
- * @see #isAvailable()
- * @see #getBitmap(android.graphics.Bitmap)
- * @see #getBitmap(int, int)
+ *
+ * @see #isAvailable()
+ * @see #getBitmap(android.graphics.Bitmap)
+ * @see #getBitmap(int, int)
*/
public Bitmap getBitmap() {
return getBitmap(getWidth(), getHeight());
@@ -523,24 +523,24 @@ public class TextureView extends View {
* <p>Returns a {@link android.graphics.Bitmap} representation of the content
* of the associated surface texture. If the surface texture is not available,
* this method returns null.</p>
- *
+ *
* <p>The bitmap returned by this method uses the {@link Bitmap.Config#ARGB_8888}
* pixel format.</p>
- *
+ *
* <p><strong>Do not</strong> invoke this method from a drawing method
* ({@link #onDraw(android.graphics.Canvas)} for instance).</p>
- *
+ *
* <p>If an error occurs during the copy, an empty bitmap will be returned.</p>
- *
+ *
* @param width The width of the bitmap to create
* @param height The height of the bitmap to create
- *
+ *
* @return A valid {@link Bitmap.Config#ARGB_8888} bitmap, or null if the surface
* texture is not available or width is &lt;= 0 or height is &lt;= 0
- *
- * @see #isAvailable()
- * @see #getBitmap(android.graphics.Bitmap)
- * @see #getBitmap()
+ *
+ * @see #isAvailable()
+ * @see #getBitmap(android.graphics.Bitmap)
+ * @see #getBitmap()
*/
public Bitmap getBitmap(int width, int height) {
if (isAvailable() && width > 0 && height > 0) {
@@ -555,21 +555,21 @@ public class TextureView extends View {
* bitmap. If the surface texture is not available, the copy is not executed.
* The content of the surface texture will be scaled to fit exactly inside
* the specified bitmap.</p>
- *
+ *
* <p><strong>Do not</strong> invoke this method from a drawing method
* ({@link #onDraw(android.graphics.Canvas)} for instance).</p>
- *
+ *
* <p>If an error occurs, the bitmap is left unchanged.</p>
- *
+ *
* @param bitmap The bitmap to copy the content of the surface texture into,
* cannot be null, all configurations are supported
- *
+ *
* @return The bitmap specified as a parameter
- *
- * @see #isAvailable()
- * @see #getBitmap(int, int)
- * @see #getBitmap()
- *
+ *
+ * @see #isAvailable()
+ * @see #getBitmap(int, int)
+ * @see #getBitmap()
+ *
* @throws IllegalStateException if the hardware rendering context cannot be
* acquired to capture the bitmap
*/
@@ -609,21 +609,21 @@ public class TextureView extends View {
* to implement
* {@link SurfaceTextureListener#onSurfaceTextureAvailable(android.graphics.SurfaceTexture, int, int)}
* to find out when the Surface is available for use.</p>
- *
+ *
* <p>The content of the Surface is never preserved between unlockCanvas()
* and lockCanvas(), for this reason, every pixel within the Surface area
* must be written. The only exception to this rule is when a dirty
* rectangle is specified, in which case, non-dirty pixels will be
* preserved.</p>
- *
+ *
* <p>This method can only be used if the underlying surface is not already
* owned by another producer. For instance, if the TextureView is being used
* to render the camera's preview you cannot invoke this method.</p>
- *
+ *
* @return A Canvas used to draw into the surface.
- *
- * @see #lockCanvas(android.graphics.Rect)
- * @see #unlockCanvasAndPost(android.graphics.Canvas)
+ *
+ * @see #lockCanvas(android.graphics.Rect)
+ * @see #unlockCanvasAndPost(android.graphics.Canvas)
*/
public Canvas lockCanvas() {
return lockCanvas(null);
@@ -639,12 +639,12 @@ public class TextureView extends View {
* available (see {@link #isAvailable()} or if the surface texture is
* already connected to an image producer (for instance: the camera,
* OpenGL, a media player, etc.)
- *
+ *
* @param dirty Area of the surface that will be modified.
* @return A Canvas used to draw into the surface.
- *
- * @see #lockCanvas()
+ *
+ * @see #lockCanvas()
* @see #unlockCanvasAndPost(android.graphics.Canvas)
* @see #isAvailable()
*/
@@ -670,11 +670,11 @@ public class TextureView extends View {
* current pixels will be shown on the screen, but its content is lost,
* in particular there is no guarantee that the content of the Surface
* will remain unchanged when lockCanvas() is called again.
- *
+ *
* @param canvas The Canvas previously returned by lockCanvas()
- *
+ *
* @see #lockCanvas()
- * @see #lockCanvas(android.graphics.Rect)
+ * @see #lockCanvas(android.graphics.Rect)
*/
public void unlockCanvasAndPost(Canvas canvas) {
if (mCanvas != null && canvas == mCanvas) {
@@ -691,8 +691,8 @@ public class TextureView extends View {
* Returns the {@link SurfaceTexture} used by this view. This method
* may return null if the view is not attached to a window or if the surface
* texture has not been initialized yet.
- *
- * @see #isAvailable()
+ *
+ * @see #isAvailable()
*/
public SurfaceTexture getSurfaceTexture() {
return mSurface;
@@ -730,9 +730,13 @@ public class TextureView extends View {
}
mSurface = surfaceTexture;
- // If the view is visible, update the listener in the new surface to use
- // the existing listener in the view.
- if (((mViewFlags & VISIBILITY_MASK) == VISIBLE)) {
+ /*
+ * If the view is visible and we already made a layer, update the
+ * listener in the new surface to use the existing listener in the view.
+ * Otherwise this will be called when the view becomes visible or the
+ * layer is created
+ */
+ if (((mViewFlags & VISIBILITY_MASK) == VISIBLE) && mLayer != null) {
mSurface.setOnFrameAvailableListener(mUpdateListener, mAttachInfo.mHandler);
}
mUpdateSurface = true;
@@ -742,8 +746,8 @@ public class TextureView extends View {
/**
* Returns the {@link SurfaceTextureListener} currently associated with this
* texture view.
- *
- * @see #setSurfaceTextureListener(android.view.TextureView.SurfaceTextureListener)
+ *
+ * @see #setSurfaceTextureListener(android.view.TextureView.SurfaceTextureListener)
* @see SurfaceTextureListener
*/
public SurfaceTextureListener getSurfaceTextureListener() {
@@ -753,8 +757,8 @@ public class TextureView extends View {
/**
* Sets the {@link SurfaceTextureListener} used to listen to surface
* texture events.
- *
- * @see #getSurfaceTextureListener()
+ *
+ * @see #getSurfaceTextureListener()
* @see SurfaceTextureListener
*/
public void setSurfaceTextureListener(SurfaceTextureListener listener) {
@@ -777,7 +781,7 @@ public class TextureView extends View {
public static interface SurfaceTextureListener {
/**
* Invoked when a {@link TextureView}'s SurfaceTexture is ready for use.
- *
+ *
* @param surface The surface returned by
* {@link android.view.TextureView#getSurfaceTexture()}
* @param width The width of the surface
@@ -787,7 +791,7 @@ public class TextureView extends View {
/**
* Invoked when the {@link SurfaceTexture}'s buffers size changed.
- *
+ *
* @param surface The surface returned by
* {@link android.view.TextureView#getSurfaceTexture()}
* @param width The new width of the surface
@@ -800,7 +804,7 @@ public class TextureView extends View {
* If returns true, no rendering should happen inside the surface texture after this method
* is invoked. If returns false, the client needs to call {@link SurfaceTexture#release()}.
* Most applications should return true.
- *
+ *
* @param surface The surface about to be destroyed
*/
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface);
@@ -808,7 +812,7 @@ public class TextureView extends View {
/**
* Invoked when the specified {@link SurfaceTexture} is updated through
* {@link SurfaceTexture#updateTexImage()}.
- *
+ *
* @param surface The surface just updated
*/
public void onSurfaceTextureUpdated(SurfaceTexture surface);
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index 7f243d3..e044f1e 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -148,7 +148,6 @@ public class ThreadedRenderer extends HardwareRenderer {
mInitialized = true;
updateEnabledState(surface);
boolean status = nInitialize(mNativeProxy, surface);
- surface.allocateBuffers();
return status;
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index c4f9209..41f906a 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1705,10 +1705,19 @@ public final class ViewRootImpl implements ViewParent,
mFullRedrawNeeded = true;
mPreviousTransparentRegion.setEmpty();
+ // Only initialize up-front if transparent regions are not
+ // requested, otherwise defer to see if the entire window
+ // will be transparent
if (mAttachInfo.mHardwareRenderer != null) {
try {
hwInitialized = mAttachInfo.mHardwareRenderer.initialize(
mSurface);
+ if (hwInitialized && (host.mPrivateFlags
+ & View.PFLAG_REQUEST_TRANSPARENT_REGIONS) == 0) {
+ // Don't pre-allocate if transparent regions
+ // are requested as they may not be needed
+ mSurface.allocateBuffers();
+ }
} catch (OutOfResourcesException e) {
handleOutOfResourcesException(e);
return;
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 7976ca4..f0c86e5 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -218,7 +218,7 @@ public interface WindowManager extends ViewManager {
@ViewDebug.IntToString(from = TYPE_NAVIGATION_BAR, to = "TYPE_NAVIGATION_BAR"),
@ViewDebug.IntToString(from = TYPE_VOLUME_OVERLAY, to = "TYPE_VOLUME_OVERLAY"),
@ViewDebug.IntToString(from = TYPE_BOOT_PROGRESS, to = "TYPE_BOOT_PROGRESS"),
- @ViewDebug.IntToString(from = TYPE_HIDDEN_NAV_CONSUMER, to = "TYPE_HIDDEN_NAV_CONSUMER"),
+ @ViewDebug.IntToString(from = TYPE_INPUT_CONSUMER, to = "TYPE_INPUT_CONSUMER"),
@ViewDebug.IntToString(from = TYPE_DREAM, to = "TYPE_DREAM"),
@ViewDebug.IntToString(from = TYPE_NAVIGATION_BAR_PANEL, to = "TYPE_NAVIGATION_BAR_PANEL"),
@ViewDebug.IntToString(from = TYPE_DISPLAY_OVERLAY, to = "TYPE_DISPLAY_OVERLAY"),
@@ -490,12 +490,11 @@ public interface WindowManager extends ViewManager {
public static final int TYPE_BOOT_PROGRESS = FIRST_SYSTEM_WINDOW+21;
/**
- * Window type: Fake window to consume touch events when the navigation
- * bar is hidden.
+ * Window type to consume input events when the systemUI bars are hidden.
* In multiuser systems shows on all users' windows.
* @hide
*/
- public static final int TYPE_HIDDEN_NAV_CONSUMER = FIRST_SYSTEM_WINDOW+22;
+ public static final int TYPE_INPUT_CONSUMER = FIRST_SYSTEM_WINDOW+22;
/**
* Window type: Dreams (screen saver) window, just above keyguard.
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 9199af1..1b759a3 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -373,12 +373,12 @@ public interface WindowManagerPolicy {
}
/**
- * Representation of a "fake window" that the policy has added to the
- * window manager to consume events.
+ * Representation of a input consumer that the policy has added to the
+ * window manager to consume input events going to windows below it.
*/
- public interface FakeWindow {
+ public interface InputConsumer {
/**
- * Remove the fake window from the window manager.
+ * Remove the input consumer from the window manager.
*/
void dismiss();
}
@@ -402,13 +402,10 @@ public interface WindowManagerPolicy {
public void reevaluateStatusBarVisibility();
/**
- * Add a fake window to the window manager. This window sits
- * at the top of the other windows and consumes events.
+ * Add a input consumer which will consume all input events going to any window below it.
*/
- public FakeWindow addFakeWindow(Looper looper,
- InputEventReceiver.Factory inputEventReceiverFactory,
- String name, int windowType, int layoutParamsFlags, int layoutParamsPrivateFlags,
- boolean canReceiveKeys, boolean hasFocus, boolean touchFullscreen);
+ public InputConsumer addInputConsumer(Looper looper,
+ InputEventReceiver.Factory inputEventReceiverFactory);
/**
* Returns a code that describes the current state of the lid switch.
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index f5a99d1..19184d6 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -3495,6 +3495,10 @@ public class Editor {
mIdealVerticalOffset = 0.7f * handleHeight;
}
+ public float getIdealVerticalOffset() {
+ return mIdealVerticalOffset;
+ }
+
protected void updateDrawable() {
final int offset = getCurrentCursorOffset();
final boolean isRtlCharAtOffset = mTextView.getLayout().isRtlCharAt(offset);
@@ -3966,7 +3970,11 @@ public class Editor {
@Override
protected int getHotspotX(Drawable drawable, boolean isRtlRun) {
- return isRtlRun ? 0 : drawable.getIntrinsicWidth();
+ if (isRtlRun) {
+ return drawable.getIntrinsicWidth() / 4;
+ } else {
+ return (drawable.getIntrinsicWidth() * 3) / 4;
+ }
}
@Override
@@ -4084,7 +4092,11 @@ public class Editor {
@Override
protected int getHotspotX(Drawable drawable, boolean isRtlRun) {
- return isRtlRun ? drawable.getIntrinsicWidth() : 0;
+ if (isRtlRun) {
+ return (drawable.getIntrinsicWidth() * 3) / 4;
+ } else {
+ return drawable.getIntrinsicWidth() / 4;
+ }
}
@Override
@@ -4271,6 +4283,7 @@ public class Editor {
private int mStartOffset = -1;
// Indicates whether the user is selecting text and using the drag accelerator.
private boolean mDragAcceleratorActive;
+ private boolean mHaventMovedEnoughToStartDrag;
SelectionModifierCursorController() {
resetTouchOffsets();
@@ -4335,19 +4348,20 @@ public class Editor {
public void onTouchEvent(MotionEvent event) {
// This is done even when the View does not have focus, so that long presses can start
// selection and tap can move cursor from this tap position.
+ final float eventX = event.getX();
+ final float eventY = event.getY();
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
- final float x = event.getX();
- final float y = event.getY();
// Remember finger down position, to be able to start selection from there.
- mMinTouchOffset = mMaxTouchOffset = mTextView.getOffsetForPosition(x, y);
+ mMinTouchOffset = mMaxTouchOffset = mTextView.getOffsetForPosition(
+ eventX, eventY);
// Double tap detection
if (mGestureStayedInTapRegion) {
if (mDoubleTap) {
- final float deltaX = x - mDownPositionX;
- final float deltaY = y - mDownPositionY;
+ final float deltaX = eventX - mDownPositionX;
+ final float deltaY = eventY - mDownPositionY;
final float distanceSquared = deltaX * deltaX + deltaY * deltaY;
ViewConfiguration viewConfiguration = ViewConfiguration.get(
@@ -4355,16 +4369,17 @@ public class Editor {
int doubleTapSlop = viewConfiguration.getScaledDoubleTapSlop();
boolean stayedInArea = distanceSquared < doubleTapSlop * doubleTapSlop;
- if (stayedInArea && isPositionOnText(x, y)) {
+ if (stayedInArea && isPositionOnText(eventX, eventY)) {
startSelectionActionModeWithSelectionAndStartDrag();
mDiscardNextActionUp = true;
}
}
}
- mDownPositionX = x;
- mDownPositionY = y;
+ mDownPositionX = eventX;
+ mDownPositionY = eventY;
mGestureStayedInTapRegion = true;
+ mHaventMovedEnoughToStartDrag = true;
break;
case MotionEvent.ACTION_POINTER_DOWN:
@@ -4378,18 +4393,24 @@ public class Editor {
break;
case MotionEvent.ACTION_MOVE:
- final ViewConfiguration viewConfiguration = ViewConfiguration.get(
+ final ViewConfiguration viewConfig = ViewConfiguration.get(
mTextView.getContext());
+ final int touchSlop = viewConfig.getScaledTouchSlop();
- if (mGestureStayedInTapRegion) {
- final float deltaX = event.getX() - mDownPositionX;
- final float deltaY = event.getY() - mDownPositionY;
+ if (mGestureStayedInTapRegion || mHaventMovedEnoughToStartDrag) {
+ final float deltaX = eventX - mDownPositionX;
+ final float deltaY = eventY - mDownPositionY;
final float distanceSquared = deltaX * deltaX + deltaY * deltaY;
- int doubleTapTouchSlop = viewConfiguration.getScaledDoubleTapTouchSlop();
-
- if (distanceSquared > doubleTapTouchSlop * doubleTapTouchSlop) {
- mGestureStayedInTapRegion = false;
+ if (mGestureStayedInTapRegion) {
+ int doubleTapTouchSlop = viewConfig.getScaledDoubleTapTouchSlop();
+ mGestureStayedInTapRegion =
+ distanceSquared <= doubleTapTouchSlop * doubleTapTouchSlop;
+ }
+ if (mHaventMovedEnoughToStartDrag) {
+ // We don't start dragging until the user has moved enough.
+ mHaventMovedEnoughToStartDrag =
+ distanceSquared <= touchSlop * touchSlop;
}
}
@@ -4399,56 +4420,28 @@ public class Editor {
}
if (mStartOffset != -1) {
- final int rawOffset = mTextView.getOffsetForPosition(event.getX(),
- event.getY());
- int offset = rawOffset;
-
- // We don't start "dragging" until the user is past the initial word that
- // gets selected on long press.
- int firstWordStart = getWordStart(mStartOffset);
- int firstWordEnd = getWordEnd(mStartOffset);
- if (offset > firstWordEnd || offset < firstWordStart) {
-
- // Basically the goal in the below code is to have the highlight be
- // offset so that your finger isn't covering the end point.
- int fingerOffset = viewConfiguration.getScaledTouchSlop();
- float mx = event.getX();
- float my = event.getY();
- if (mx > fingerOffset) mx -= fingerOffset;
- if (my > fingerOffset) my -= fingerOffset;
- offset = mTextView.getOffsetForPosition(mx, my);
-
- // Perform the check for closeness at edge of view, if we're very close
- // don't adjust the offset to be in front of the finger - otherwise the
- // user can't select words at the edge.
- if (mTextView.getWidth() - fingerOffset > mx) {
- // We're going by word, so we need to make sure that the offset
- // that we get is within this, so we'll get the previous boundary.
- final WordIterator wordIterator = getWordIteratorWithText();
-
- final int precedingOffset = wordIterator.preceding(offset);
- if (mStartOffset < offset) {
- // Expanding with bottom handle, in this case the selection end
- // is before the finger.
- offset = Math.max(precedingOffset - 1, 0);
- } else {
- // Expand with the start handle, in this case the selection
- // start is before the finger.
- if (precedingOffset == WordIterator.DONE) {
- offset = 0;
- } else {
- offset = wordIterator.preceding(precedingOffset);
- }
- }
+ if (!mHaventMovedEnoughToStartDrag) {
+ // Offset the finger by the same vertical offset as the handles. This
+ // improves visibility of the content being selected by shifting
+ // the finger below the content.
+ final float fingerOffset = (mStartHandle != null)
+ ? mStartHandle.getIdealVerticalOffset()
+ : touchSlop;
+ int offset =
+ mTextView.getOffsetForPosition(eventX, eventY - fingerOffset);
+ int startOffset;
+ // Snap to word boundaries.
+ if (mStartOffset < offset) {
+ // Expanding with end handle.
+ offset = getWordEnd(offset);
+ startOffset = getWordStart(mStartOffset);
+ } else {
+ // Expanding with start handle.
+ offset = getWordStart(offset);
+ startOffset = getWordEnd(mStartOffset);
}
- if (offset == WordIterator.DONE)
- offset = rawOffset;
-
- // Need to adjust start offset based on direction of movement.
- int newStart = mStartOffset < offset ? getWordStart(mStartOffset)
- : getWordEnd(mStartOffset);
- Selection.setSelection((Spannable) mTextView.getText(), newStart,
- offset);
+ Selection.setSelection((Spannable) mTextView.getText(),
+ startOffset, offset);
}
}
break;
diff --git a/core/java/com/android/internal/logging/MetricsConstants.java b/core/java/com/android/internal/logging/MetricsConstants.java
index b9a75d3..65dc743 100644
--- a/core/java/com/android/internal/logging/MetricsConstants.java
+++ b/core/java/com/android/internal/logging/MetricsConstants.java
@@ -208,7 +208,6 @@ public interface MetricsConstants {
public static final int APPLICATIONS_USAGE_ACCESS_DETAIL = 183;
public static final int APPLICATIONS_HIGH_POWER_APPS = 184;
public static final int FUELGAUGE_HIGH_POWER_DETAILS = 185;
- public static final int APPLICATIONS_MANAGE_ASSIST = 186;
//aliases
public static final int DEVICEINFO_STORAGE = DEVICEINFO_MEMORY;
diff --git a/core/jni/android_media_AudioFormat.h b/core/jni/android_media_AudioFormat.h
index 32b5b02..5144457 100644
--- a/core/jni/android_media_AudioFormat.h
+++ b/core/jni/android_media_AudioFormat.h
@@ -27,6 +27,10 @@
#define ENCODING_E_AC3 6
#define ENCODING_DTS 7
#define ENCODING_DTS_HD 8
+#define ENCODING_MP3 9
+#define ENCODING_AAC_LC 10
+#define ENCODING_AAC_HE_V1 11
+#define ENCODING_AAC_HE_V2 12
#define ENCODING_INVALID 0
#define ENCODING_DEFAULT 1
@@ -52,6 +56,14 @@ static inline audio_format_t audioFormatToNative(int audioFormat)
return AUDIO_FORMAT_DTS;
case ENCODING_DTS_HD:
return AUDIO_FORMAT_DTS_HD;
+ case ENCODING_MP3:
+ return AUDIO_FORMAT_MP3;
+ case ENCODING_AAC_LC:
+ return AUDIO_FORMAT_AAC_LC;
+ case ENCODING_AAC_HE_V1:
+ return AUDIO_FORMAT_AAC_HE_V1;
+ case ENCODING_AAC_HE_V2:
+ return AUDIO_FORMAT_AAC_HE_V2;
case ENCODING_DEFAULT:
return AUDIO_FORMAT_DEFAULT;
default:
@@ -76,6 +88,14 @@ static inline int audioFormatFromNative(audio_format_t nativeFormat)
return ENCODING_DTS;
case AUDIO_FORMAT_DTS_HD:
return ENCODING_DTS_HD;
+ case AUDIO_FORMAT_MP3:
+ return ENCODING_MP3;
+ case AUDIO_FORMAT_AAC_LC:
+ return ENCODING_AAC_LC;
+ case AUDIO_FORMAT_AAC_HE_V1:
+ return ENCODING_AAC_HE_V1;
+ case AUDIO_FORMAT_AAC_HE_V2:
+ return ENCODING_AAC_HE_V2;
case AUDIO_FORMAT_DEFAULT:
return ENCODING_DEFAULT;
default:
diff --git a/core/jni/android_media_AudioRecord.cpp b/core/jni/android_media_AudioRecord.cpp
index 87b81d5..e5c4ba9 100644
--- a/core/jni/android_media_AudioRecord.cpp
+++ b/core/jni/android_media_AudioRecord.cpp
@@ -521,11 +521,11 @@ static jint android_media_AudioRecord_readInDirectBuffer(JNIEnv *env, jobject t
}
// ----------------------------------------------------------------------------
-static jint android_media_AudioRecord_get_native_frame_count(JNIEnv *env, jobject thiz) {
+static jint android_media_AudioRecord_get_buffer_size_in_frames(JNIEnv *env, jobject thiz) {
sp<AudioRecord> lpRecorder = getAudioRecord(env, thiz);
if (lpRecorder == NULL) {
jniThrowException(env, "java/lang/IllegalStateException",
- "Unable to retrieve AudioRecord pointer for getNativeFrameCount()");
+ "Unable to retrieve AudioRecord pointer for frameCount()");
return (jint)AUDIO_JAVA_ERROR;
}
return lpRecorder->frameCount();
@@ -700,8 +700,8 @@ static JNINativeMethod gMethods[] = {
(void *)android_media_AudioRecord_readInArray<jfloatArray>},
{"native_read_in_direct_buffer","(Ljava/lang/Object;IZ)I",
(void *)android_media_AudioRecord_readInDirectBuffer},
- {"native_get_native_frame_count",
- "()I", (void *)android_media_AudioRecord_get_native_frame_count},
+ {"native_get_buffer_size_in_frames",
+ "()I", (void *)android_media_AudioRecord_get_buffer_size_in_frames},
{"native_set_marker_pos","(I)I", (void *)android_media_AudioRecord_set_marker_pos},
{"native_get_marker_pos","()I", (void *)android_media_AudioRecord_get_marker_pos},
{"native_set_pos_update_period",
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 595f9f0..4f451c7 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -681,7 +681,7 @@
android:permissionGroup="android.permission-group.SENSORS"
android:label="@string/permlab_useFingerprint"
android:description="@string/permdesc_useFingerprint"
- android:protectionLevel="dangerous" />
+ android:protectionLevel="normal" />
<!-- ====================================================================== -->
<!-- INSTALLTIME PERMISSIONS -->
diff --git a/core/res/res/drawable-hdpi/text_select_handle_left_mtrl_alpha.png b/core/res/res/drawable-hdpi/text_select_handle_left_mtrl_alpha.png
index 1550b44..7ccb70a 100644
--- a/core/res/res/drawable-hdpi/text_select_handle_left_mtrl_alpha.png
+++ b/core/res/res/drawable-hdpi/text_select_handle_left_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/text_select_handle_right_mtrl_alpha.png b/core/res/res/drawable-hdpi/text_select_handle_right_mtrl_alpha.png
index b309dfd..e65b89d 100644
--- a/core/res/res/drawable-hdpi/text_select_handle_right_mtrl_alpha.png
+++ b/core/res/res/drawable-hdpi/text_select_handle_right_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/text_select_handle_left_mtrl_alpha.png b/core/res/res/drawable-mdpi/text_select_handle_left_mtrl_alpha.png
index b36a413..775f1bb 100644
--- a/core/res/res/drawable-mdpi/text_select_handle_left_mtrl_alpha.png
+++ b/core/res/res/drawable-mdpi/text_select_handle_left_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/text_select_handle_right_mtrl_alpha.png b/core/res/res/drawable-mdpi/text_select_handle_right_mtrl_alpha.png
index afd0bd2..68fd053 100644
--- a/core/res/res/drawable-mdpi/text_select_handle_right_mtrl_alpha.png
+++ b/core/res/res/drawable-mdpi/text_select_handle_right_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/text_select_handle_left_mtrl_alpha.png b/core/res/res/drawable-xhdpi/text_select_handle_left_mtrl_alpha.png
index 58f8c43..b5c2a91 100644
--- a/core/res/res/drawable-xhdpi/text_select_handle_left_mtrl_alpha.png
+++ b/core/res/res/drawable-xhdpi/text_select_handle_left_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/text_select_handle_right_mtrl_alpha.png b/core/res/res/drawable-xhdpi/text_select_handle_right_mtrl_alpha.png
index 42a893d..6c6185c 100644
--- a/core/res/res/drawable-xhdpi/text_select_handle_right_mtrl_alpha.png
+++ b/core/res/res/drawable-xhdpi/text_select_handle_right_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/text_select_handle_left_mtrl_alpha.png b/core/res/res/drawable-xxhdpi/text_select_handle_left_mtrl_alpha.png
index d0f274a..f0e32af 100644
--- a/core/res/res/drawable-xxhdpi/text_select_handle_left_mtrl_alpha.png
+++ b/core/res/res/drawable-xxhdpi/text_select_handle_left_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/text_select_handle_right_mtrl_alpha.png b/core/res/res/drawable-xxhdpi/text_select_handle_right_mtrl_alpha.png
index f1f637a..260e090 100644
--- a/core/res/res/drawable-xxhdpi/text_select_handle_right_mtrl_alpha.png
+++ b/core/res/res/drawable-xxhdpi/text_select_handle_right_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/text_select_handle_left_mtrl_alpha.png b/core/res/res/drawable-xxxhdpi/text_select_handle_left_mtrl_alpha.png
index 643168f..a7a48b8 100644
--- a/core/res/res/drawable-xxxhdpi/text_select_handle_left_mtrl_alpha.png
+++ b/core/res/res/drawable-xxxhdpi/text_select_handle_left_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/text_select_handle_right_mtrl_alpha.png b/core/res/res/drawable-xxxhdpi/text_select_handle_right_mtrl_alpha.png
index e8f3aad..2c72f4f 100644
--- a/core/res/res/drawable-xxxhdpi/text_select_handle_right_mtrl_alpha.png
+++ b/core/res/res/drawable-xxxhdpi/text_select_handle_right_mtrl_alpha.png
Binary files differ
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index f790d74..c715652 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2142,8 +2142,9 @@
<!-- Keyguard component -->
<string name="config_keyguardComponent" translatable="false">com.android.systemui/com.android.systemui.keyguard.KeyguardService</string>
- <!-- This config is used to force VoiceInteractionService to start on certain low ram devices. -->
- <bool name="config_forceEnableVoiceInteractionService">false</bool>
+ <!-- This config is used to force VoiceInteractionService to start on certain low ram devices.
+ It declares the package name of VoiceInteractionService that should be started. -->
+ <string translatable="false" name="config_forceVoiceInteractionServicePackage"></string>
<!-- This config is ued to determine whether animations are allowed in low power mode. -->
<bool name="config_allowAnimationsInLowPowerMode">false</bool>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 6124b5b..4b57a47 100755
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -280,7 +280,6 @@
<java-symbol type="bool" name="config_enableScreenshotChord" />
<java-symbol type="bool" name="config_bluetooth_default_profiles" />
<java-symbol type="bool" name="config_enableWifiDisplay" />
- <java-symbol type="bool" name="config_forceEnableVoiceInteractionService" />
<java-symbol type="bool" name="config_allowAnimationsInLowPowerMode" />
<java-symbol type="bool" name="config_useDevInputEventForAudioJack" />
<java-symbol type="bool" name="config_safe_media_volume_enabled" />
@@ -560,6 +559,7 @@
<java-symbol type="string" name="chooseActivity" />
<java-symbol type="string" name="config_default_dns_server" />
<java-symbol type="string" name="config_ethernet_iface_regex" />
+ <java-symbol type="string" name="config_forceVoiceInteractionServicePackage" />
<java-symbol type="string" name="config_mms_user_agent" />
<java-symbol type="string" name="config_mms_user_agent_profile_url" />
<java-symbol type="string" name="config_ntpServer" />
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index a999b71..8ad7c12 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -1575,11 +1575,12 @@ public final class Bitmap implements Parcelable {
*/
public boolean sameAs(Bitmap other) {
checkRecycled("Can't call sameAs on a recycled bitmap!");
+ if (this == other) return true;
+ if (other == null) return false;
if (other.isRecycled()) {
throw new IllegalArgumentException("Can't compare to a recycled bitmap!");
}
- return this == other || (other != null
- && nativeSameAs(mFinalizer.mNativeBitmap, other.mFinalizer.mNativeBitmap));
+ return nativeSameAs(mFinalizer.mNativeBitmap, other.mFinalizer.mNativeBitmap);
}
/**
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index f75d6a0..1030451 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -23,6 +23,7 @@
#include "Properties.h"
#include "renderstate/RenderState.h"
#include "ShadowTessellator.h"
+#include "utils/GLUtils.h"
#include <utils/Log.h>
#include <utils/String8.h>
@@ -276,6 +277,9 @@ void Caches::flush(FlushMode mode) {
clearGarbage();
glFinish();
+ // Errors during cleanup should be considered non-fatal, dump them and
+ // and move on. TODO: All errors or just errors like bad surface?
+ GLUtils::dumpGLErrors();
}
///////////////////////////////////////////////////////////////////////////////
diff --git a/libs/hwui/DeferredLayerUpdater.cpp b/libs/hwui/DeferredLayerUpdater.cpp
index 6b8c780..a17904e 100644
--- a/libs/hwui/DeferredLayerUpdater.cpp
+++ b/libs/hwui/DeferredLayerUpdater.cpp
@@ -119,7 +119,6 @@ void DeferredLayerUpdater::doUpdateTexImage() {
void DeferredLayerUpdater::detachSurfaceTexture() {
if (mSurfaceTexture.get()) {
- mRenderThread.eglManager().requireGlContext();
status_t err = mSurfaceTexture->detachFromContext();
if (err != 0) {
// TODO: Elevate to fatal exception
diff --git a/libs/hwui/renderstate/RenderState.cpp b/libs/hwui/renderstate/RenderState.cpp
index e54fa5a..d7c8316 100644
--- a/libs/hwui/renderstate/RenderState.cpp
+++ b/libs/hwui/renderstate/RenderState.cpp
@@ -169,7 +169,8 @@ void RenderState::debugOverdraw(bool enable, bool clear) {
void RenderState::requireGLContext() {
assertOnGLThread();
- mRenderThread.eglManager().requireGlContext();
+ LOG_ALWAYS_FATAL_IF(!mRenderThread.eglManager().hasEglContext(),
+ "No GL context!");
}
void RenderState::assertOnGLThread() {
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 8329cd4..706e14e 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -262,8 +262,6 @@ void CanvasContext::draw() {
if (drew) {
swapBuffers(dirty, width, height);
- } else {
- mEglManager.cancelFrame();
}
// TODO: Use a fence for real completion?
@@ -297,7 +295,6 @@ void CanvasContext::invokeFunctor(RenderThread& thread, Functor* functor) {
ATRACE_CALL();
DrawGlInfo::Mode mode = DrawGlInfo::kModeProcessNoContext;
if (thread.eglManager().hasEglContext()) {
- thread.eglManager().requireGlContext();
mode = DrawGlInfo::kModeProcess;
}
@@ -318,7 +315,6 @@ static void destroyPrefetechedNode(RenderNode* node) {
void CanvasContext::freePrefetechedLayers() {
if (mPrefetechedLayers.size()) {
- requireGlContext();
std::for_each(mPrefetechedLayers.begin(), mPrefetechedLayers.end(), destroyPrefetechedNode);
mPrefetechedLayers.clear();
}
@@ -329,7 +325,6 @@ void CanvasContext::buildLayer(RenderNode* node) {
if (!mEglManager.hasEglContext() || !mCanvas) {
return;
}
- requireGlContext();
// buildLayer() will leave the tree in an unknown state, so we must stop drawing
stopDrawing();
@@ -352,7 +347,6 @@ void CanvasContext::buildLayer(RenderNode* node) {
}
bool CanvasContext::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) {
- requireGlContext();
layer->apply();
return LayerRenderer::copyLayer(mRenderThread.renderState(), layer->backingLayer(), bitmap);
}
@@ -360,7 +354,6 @@ bool CanvasContext::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap)
void CanvasContext::destroyHardwareResources() {
stopDrawing();
if (mEglManager.hasEglContext()) {
- requireGlContext();
freePrefetechedLayers();
mRootRenderNode->destroyHardwareResources();
Caches::getInstance().flush(Caches::kFlushMode_Layers);
@@ -372,7 +365,6 @@ void CanvasContext::trimMemory(RenderThread& thread, int level) {
if (!thread.eglManager().hasEglContext()) return;
ATRACE_CALL();
- thread.eglManager().requireGlContext();
if (level >= TRIM_MEMORY_COMPLETE) {
Caches::getInstance().flush(Caches::kFlushMode_Full);
thread.eglManager().destroy();
@@ -382,7 +374,8 @@ void CanvasContext::trimMemory(RenderThread& thread, int level) {
}
void CanvasContext::runWithGlContext(RenderTask* task) {
- requireGlContext();
+ LOG_ALWAYS_FATAL_IF(!mEglManager.hasEglContext(),
+ "GL context not initialized!");
task->run();
}
@@ -391,10 +384,6 @@ Layer* CanvasContext::createTextureLayer() {
return LayerRenderer::createTextureLayer(mRenderThread.renderState());
}
-void CanvasContext::requireGlContext() {
- mEglManager.requireGlContext();
-}
-
void CanvasContext::setTextureAtlas(RenderThread& thread,
const sp<GraphicBuffer>& buffer, int64_t* map, size_t mapSize) {
thread.eglManager().setTextureAtlas(buffer, map, mapSize);
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index 17917af..10e66e9 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -122,8 +122,6 @@ private:
void swapBuffers(const SkRect& dirty, EGLint width, EGLint height);
void requireSurface();
- void requireGlContext();
-
void freePrefetechedLayers();
RenderThread& mRenderThread;
diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp
index 6255f5e..c0e7c73 100644
--- a/libs/hwui/renderthread/EglManager.cpp
+++ b/libs/hwui/renderthread/EglManager.cpp
@@ -78,8 +78,7 @@ EglManager::EglManager(RenderThread& thread)
, mAllowPreserveBuffer(load_dirty_regions_property())
, mCurrentSurface(EGL_NO_SURFACE)
, mAtlasMap(nullptr)
- , mAtlasMapSize(0)
- , mInFrame(false) {
+ , mAtlasMapSize(0) {
mCanSetPreserveBuffer = mAllowPreserveBuffer;
ALOGD("Use EGL_SWAP_BEHAVIOR_PRESERVED: %s", mAllowPreserveBuffer ? "true" : "false");
}
@@ -101,7 +100,8 @@ void EglManager::initialize() {
loadConfig();
createContext();
- usePBufferSurface();
+ createPBufferSurface();
+ makeCurrent(mPBufferSurface);
mRenderThread.renderState().onGLContextCreated();
initAtlas();
}
@@ -110,17 +110,6 @@ bool EglManager::hasEglContext() {
return mEglDisplay != EGL_NO_DISPLAY;
}
-void EglManager::requireGlContext() {
- LOG_ALWAYS_FATAL_IF(mEglDisplay == EGL_NO_DISPLAY, "No EGL context");
-
- if (!mInFrame) {
- // We can't be certain about the state of the current surface (whether
- // or not it is destroyed, for example), so err on the side of using
- // the pbuffer surface which we fully control
- usePBufferSurface();
- }
-}
-
void EglManager::loadConfig() {
EGLint swapBehavior = mCanSetPreserveBuffer ? EGL_SWAP_BEHAVIOR_PRESERVED_BIT : 0;
EGLint attribs[] = {
@@ -173,7 +162,6 @@ void EglManager::setTextureAtlas(const sp<GraphicBuffer>& buffer,
mAtlasMapSize = mapSize;
if (hasEglContext()) {
- usePBufferSurface();
initAtlas();
}
}
@@ -185,7 +173,7 @@ void EglManager::initAtlas() {
}
}
-void EglManager::usePBufferSurface() {
+void EglManager::createPBufferSurface() {
LOG_ALWAYS_FATAL_IF(mEglDisplay == EGL_NO_DISPLAY,
"usePBufferSurface() called on uninitialized GlobalContext!");
@@ -193,7 +181,6 @@ void EglManager::usePBufferSurface() {
EGLint attribs[] = { EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE };
mPBufferSurface = eglCreatePbufferSurface(mEglDisplay, mEglConfig, attribs);
}
- makeCurrent(mPBufferSurface);
}
EGLSurface EglManager::createSurface(EGLNativeWindowType window) {
@@ -217,8 +204,6 @@ void EglManager::destroySurface(EGLSurface surface) {
void EglManager::destroy() {
if (mEglDisplay == EGL_NO_DISPLAY) return;
- usePBufferSurface();
-
mRenderThread.renderState().onGLContextDestroyed();
eglDestroyContext(mEglDisplay, mEglContext);
eglDestroySurface(mEglDisplay, mPBufferSurface);
@@ -236,11 +221,10 @@ bool EglManager::makeCurrent(EGLSurface surface) {
if (isCurrent(surface)) return false;
if (surface == EGL_NO_SURFACE) {
- // If we are setting EGL_NO_SURFACE we don't care about any of the potential
- // return errors, which would only happen if mEglDisplay had already been
- // destroyed in which case the current context is already NO_CONTEXT
- eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
- } else if (!eglMakeCurrent(mEglDisplay, surface, surface, mEglContext)) {
+ // Ensure we always have a valid surface & context
+ surface = mPBufferSurface;
+ }
+ if (!eglMakeCurrent(mEglDisplay, surface, surface, mEglContext)) {
LOG_ALWAYS_FATAL("Failed to make current on surface %p, error=%s",
(void*)surface, egl_error_str());
}
@@ -259,12 +243,10 @@ void EglManager::beginFrame(EGLSurface surface, EGLint* width, EGLint* height) {
eglQuerySurface(mEglDisplay, surface, EGL_HEIGHT, height);
}
eglBeginFrame(mEglDisplay, surface);
- mInFrame = true;
}
bool EglManager::swapBuffers(EGLSurface surface, const SkRect& dirty,
EGLint width, EGLint height) {
- mInFrame = false;
#if WAIT_FOR_GPU_COMPLETION
{
@@ -328,10 +310,6 @@ void EglManager::fence() {
eglDestroySyncKHR(mEglDisplay, fence);
}
-void EglManager::cancelFrame() {
- mInFrame = false;
-}
-
bool EglManager::setPreserveBuffer(EGLSurface surface, bool preserve) {
if (CC_UNLIKELY(!mAllowPreserveBuffer)) return false;
diff --git a/libs/hwui/renderthread/EglManager.h b/libs/hwui/renderthread/EglManager.h
index 0855516..8881de6 100644
--- a/libs/hwui/renderthread/EglManager.h
+++ b/libs/hwui/renderthread/EglManager.h
@@ -36,9 +36,7 @@ public:
void initialize();
bool hasEglContext();
- void requireGlContext();
- void usePBufferSurface();
EGLSurface createSurface(EGLNativeWindowType window);
void destroySurface(EGLSurface surface);
@@ -49,7 +47,6 @@ public:
bool makeCurrent(EGLSurface surface);
void beginFrame(EGLSurface surface, EGLint* width, EGLint* height);
bool swapBuffers(EGLSurface surface, const SkRect& dirty, EGLint width, EGLint height);
- void cancelFrame();
// Returns true iff the surface is now preserving buffers.
bool setPreserveBuffer(EGLSurface surface, bool preserve);
@@ -65,6 +62,7 @@ private:
// EglContext is never destroyed, method is purposely not implemented
~EglManager();
+ void createPBufferSurface();
void loadConfig();
void createContext();
void initAtlas();
@@ -84,12 +82,6 @@ private:
sp<GraphicBuffer> mAtlasBuffer;
int64_t* mAtlasMap;
size_t mAtlasMapSize;
-
- // Whether or not we are in the middle of drawing a frame. This is used
- // to avoid switching surfaces mid-frame if requireGlContext() is called
- // TODO: Need to be better about surface/context management so that this isn't
- // necessary
- bool mInFrame;
};
} /* namespace renderthread */
diff --git a/media/java/android/media/AudioDeviceCallback.java b/media/java/android/media/AudioDeviceCallback.java
index d7fa492..d9f0037 100644
--- a/media/java/android/media/AudioDeviceCallback.java
+++ b/media/java/android/media/AudioDeviceCallback.java
@@ -17,16 +17,24 @@
package android.media;
/**
- * OnAudioDeviceConnectionListener defines the interface for notification listeners in the
- * {@link AudioManager}
+ * AudioDeviceCallback defines the mechanism by which applications can receive notifications
+ * of audio device connection and disconnection events.
+ * @see AudioManager#registerAudioDeviceCallback.
*/
public abstract class AudioDeviceCallback {
/**
- * Called by the {@link AudioManager} to indicate that an audio device has been
- * connected or disconnected. A listener will probably call the
- * {@link AudioManager#getDevices} method to retrieve the current list of audio
- * devices.
+ * Called by the {@link AudioManager} to indicate that one or more audio devices have been
+ * connected.
+ * @param addedDevices An array of {@link AudioDeviceInfo} objects corresponding to any
+ * newly added audio devices.
*/
public void onAudioDevicesAdded(AudioDeviceInfo[] addedDevices) {}
+
+ /**
+ * Called by the {@link AudioManager} to indicate that one or more audio devices have been
+ * disconnected.
+ * @param removedDevices An array of {@link AudioDeviceInfo} objects corresponding to any
+ * newly removed audio devices.
+ */
public void onAudioDevicesRemoved(AudioDeviceInfo[] removedDevices) {}
}
diff --git a/media/java/android/media/AudioDeviceInfo.java b/media/java/android/media/AudioDeviceInfo.java
index 2099bd0..431d37e 100644
--- a/media/java/android/media/AudioDeviceInfo.java
+++ b/media/java/android/media/AudioDeviceInfo.java
@@ -204,7 +204,7 @@ public final class AudioDeviceInfo {
* @see AudioFormat
*/
public @NonNull int[] getEncodings() {
- return mPort.formats();
+ return AudioFormat.filterPublicFormats(mPort.formats());
}
/**
diff --git a/media/java/android/media/AudioFormat.java b/media/java/android/media/AudioFormat.java
index a7e092f..16ae58c 100644
--- a/media/java/android/media/AudioFormat.java
+++ b/media/java/android/media/AudioFormat.java
@@ -20,6 +20,7 @@ import android.annotation.IntDef;
import android.annotation.NonNull;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.Arrays;
/**
* The AudioFormat class is used to access a number of audio format and
@@ -53,6 +54,22 @@ public class AudioFormat {
public static final int ENCODING_DTS = 7;
/** Audio data format: DTS HD compressed */
public static final int ENCODING_DTS_HD = 8;
+ /** Audio data format: MP3 compressed
+ * @hide
+ * */
+ public static final int ENCODING_MP3 = 9;
+ /** Audio data format: AAC LC compressed
+ * @hide
+ * */
+ public static final int ENCODING_AAC_LC = 10;
+ /** Audio data format: AAC HE V1 compressed
+ * @hide
+ * */
+ public static final int ENCODING_AAC_HE_V1 = 11;
+ /** Audio data format: AAC HE V2 compressed
+ * @hide
+ * */
+ public static final int ENCODING_AAC_HE_V2 = 12;
/** Invalid audio channel configuration */
/** @deprecated Use {@link #CHANNEL_INVALID} instead. */
@@ -241,6 +258,27 @@ public class AudioFormat {
case ENCODING_E_AC3:
case ENCODING_DTS:
case ENCODING_DTS_HD:
+ case ENCODING_MP3:
+ case ENCODING_AAC_LC:
+ case ENCODING_AAC_HE_V1:
+ case ENCODING_AAC_HE_V2:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ /** @hide */
+ public static boolean isPublicEncoding(int audioFormat)
+ {
+ switch (audioFormat) {
+ case ENCODING_PCM_8BIT:
+ case ENCODING_PCM_16BIT:
+ case ENCODING_PCM_FLOAT:
+ case ENCODING_AC3:
+ case ENCODING_E_AC3:
+ case ENCODING_DTS:
+ case ENCODING_DTS_HD:
return true;
default:
return false;
@@ -260,6 +298,10 @@ public class AudioFormat {
case ENCODING_E_AC3:
case ENCODING_DTS:
case ENCODING_DTS_HD:
+ case ENCODING_MP3:
+ case ENCODING_AAC_LC:
+ case ENCODING_AAC_HE_V1:
+ case ENCODING_AAC_HE_V2:
return false;
case ENCODING_INVALID:
default:
@@ -267,6 +309,28 @@ public class AudioFormat {
}
}
+ /**
+ * Returns an array of public encoding values extracted from an array of
+ * encoding values.
+ * @hide
+ */
+ public static int[] filterPublicFormats(int[] formats) {
+ if (formats == null) {
+ return null;
+ }
+ int[] myCopy = Arrays.copyOf(formats, formats.length);
+ int size = 0;
+ for (int i = 0; i < myCopy.length; i++) {
+ if (isPublicEncoding(myCopy[i])) {
+ if (size != i) {
+ myCopy[size] = myCopy[i];
+ }
+ size++;
+ }
+ }
+ return Arrays.copyOf(myCopy, size);
+ }
+
/** @removed */
public AudioFormat()
{
@@ -503,7 +567,7 @@ public class AudioFormat {
* if both channel index mask and channel position mask
* are specified but do not have the same channel count.
*/
- public @NonNull Builder setChannelMask(int channelMask) throws IllegalArgumentException {
+ public @NonNull Builder setChannelMask(int channelMask) {
if (channelMask == 0) {
throw new IllegalArgumentException("Invalid zero channel mask");
} else if (/* channelMask != 0 && */ mChannelIndexMask != 0 &&
@@ -555,8 +619,7 @@ public class AudioFormat {
* if both channel index mask and channel position mask
* are specified but do not have the same channel count.
*/
- public @NonNull Builder setChannelIndexMask(int channelIndexMask)
- throws IllegalArgumentException {
+ public @NonNull Builder setChannelIndexMask(int channelIndexMask) {
if (channelIndexMask == 0) {
throw new IllegalArgumentException("Invalid zero channel index mask");
} else if (/* channelIndexMask != 0 && */ mChannelMask != 0 &&
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index e7013a5..316ccf6 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -3713,11 +3713,18 @@ public class AudioManager {
private final static int MSG_DEVICES_DEVICES_ADDED = 0;
private final static int MSG_DEVICES_DEVICES_REMOVED = 1;
+ /**
+ * The list of {@link AudioDeviceCallback} objects to receive add/remove notifications.
+ */
private ArrayMap<AudioDeviceCallback, NativeEventHandlerDelegate>
mDeviceCallbacks =
new ArrayMap<AudioDeviceCallback, NativeEventHandlerDelegate>();
/**
+ * The following are flags to allow users of {@link AudioManager#getDevices(int)} to filter
+ * the results list to only those device types they are interested in.
+ */
+ /**
* Specifies to the {@link AudioManager#getDevices(int)} method to include
* source (i.e. input) audio devices.
*/
@@ -3747,21 +3754,25 @@ public class AudioManager {
}
/**
- * Generates a list of AudioDeviceInfo objects corresponding to the audio devices currently
- * connected to the system and meeting the criteria specified in the <code>flags</code>
- * parameter.
+ * Returns an array of {@link AudioDeviceInfo} objects corresponding to the audio devices
+ * currently connected to the system and meeting the criteria specified in the
+ * <code>flags</code> parameter.
* @param flags A set of bitflags specifying the criteria to test.
- * @see {@link GET_DEVICES_OUTPUTS}, {@link GET_DEVICES_INPUTS} and {@lGET_DEVICES_CES_ALL}.
+ * @see {@link GET_DEVICES_OUTPUTS}, {@link GET_DEVICES_INPUTS} and {@link GET_DEVICES_ALL}.
* @return A (possibly zero-length) array of AudioDeviceInfo objects.
*/
public AudioDeviceInfo[] getDevices(int flags) {
return getDevicesStatic(flags);
}
+ /**
+ * Does the actual computation to generate an array of (externally-visible) AudioDeviceInfo
+ * objects from the current (internal) AudioDevicePort list.
+ */
private static AudioDeviceInfo[]
infoListFromPortList(ArrayList<AudioDevicePort> ports, int flags) {
- // figure out how many AudioDeviceInfo we need space for
+ // figure out how many AudioDeviceInfo we need space for...
int numRecs = 0;
for (AudioDevicePort port : ports) {
if (checkFlags(port, flags)) {
@@ -3769,7 +3780,7 @@ public class AudioManager {
}
}
- // Now load them up
+ // Now load them up...
AudioDeviceInfo[] deviceList = new AudioDeviceInfo[numRecs];
int slot = 0;
for (AudioDevicePort port : ports) {
@@ -3782,7 +3793,12 @@ public class AudioManager {
}
/*
- * Calculate the list of ports that are in ports_B, but not in ports_A
+ * Calculate the list of ports that are in ports_B, but not in ports_A. This is used by
+ * the add/remove callback mechanism to provide a list of the newly added or removed devices
+ * rather than the whole list and make the app figure it out.
+ * Note that calling this method with:
+ * ports_A == PREVIOUS_ports and ports_B == CURRENT_ports will calculated ADDED ports.
+ * ports_A == CURRENT_ports and ports_B == PREVIOUS_ports will calculated REMOVED ports.
*/
private static AudioDeviceInfo[] calcListDeltas(
ArrayList<AudioDevicePort> ports_A, ArrayList<AudioDevicePort> ports_B, int flags) {
@@ -3811,6 +3827,7 @@ public class AudioManager {
* Generates a list of AudioDeviceInfo objects corresponding to the audio devices currently
* connected to the system and meeting the criteria specified in the <code>flags</code>
* parameter.
+ * This is an internal function. The public API front is getDevices(int).
* @param flags A set of bitflags specifying the criteria to test.
* @see {@link GET_DEVICES_OUTPUTS}, {@link GET_DEVICES_INPUTS} and {@link GET_DEVICES_ALL}.
* @return A (possibly zero-length) array of AudioDeviceInfo objects.
@@ -3821,15 +3838,20 @@ public class AudioManager {
int status = AudioManager.listAudioDevicePorts(ports);
if (status != AudioManager.SUCCESS) {
// fail and bail!
- return new AudioDeviceInfo[0];
+ return new AudioDeviceInfo[0]; // Always return an array.
}
return infoListFromPortList(ports, flags);
}
/**
- * Adds an {@link AudioDeviceCallback} to receive notifications of changes
+ * Registers an {@link AudioDeviceCallback} object to receive notifications of changes
* to the set of connected audio devices.
+ * @param callback The {@link AudioDeviceCallback} object to receive connect/disconnect
+ * notifications.
+ * @param handler Specifies the {@link Handler} object for the thread on which to execute
+ * the callback. If <code>null</code>, the {@link Handler} associated with the main
+ * {@link Looper} will be used.
*/
public void registerAudioDeviceCallback(AudioDeviceCallback callback,
android.os.Handler handler) {
@@ -3842,8 +3864,10 @@ public class AudioManager {
}
/**
- * Removes an {@link AudioDeviceCallback} which has been previously registered
+ * Unregisters an {@link AudioDeviceCallback} object which has been previously registered
* to receive notifications of changes to the set of connected audio devices.
+ * @param callback The {@link AudioDeviceCallback} object that was previously registered
+ * with {@link AudioManager#registerAudioDeviceCallback) to be unregistered.
*/
public void unregisterAudioDeviceCallback(AudioDeviceCallback callback) {
synchronized (mDeviceCallbacks) {
@@ -3854,7 +3878,8 @@ public class AudioManager {
}
/**
- * Sends device list change notification to all listeners.
+ * Internal method to compute and generate add/remove messages and then send to any
+ * registered callbacks.
*/
private void broadcastDeviceListChange() {
int status;
@@ -3908,7 +3933,8 @@ public class AudioManager {
/**
* Callback method called upon audio patch list update.
- * @param patchList the updated list of audio patches
+ * Note: We don't do anything with Patches at this time, so ignore this notification.
+ * @param patchList the updated list of audio patches.
*/
public void onAudioPatchListUpdate(AudioPatch[] patchList) {}
diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java
index c0bc6d6..7eb1357 100644
--- a/media/java/android/media/AudioRecord.java
+++ b/media/java/android/media/AudioRecord.java
@@ -494,7 +494,7 @@ public class AudioRecord
* than this size. See {@link #getMinBufferSize(int, int, int)} to determine the minimum
* required buffer size for the successful creation of an AudioRecord instance.
* Since bufferSizeInBytes may be internally increased to accommodate the source
- * requirements, use {@link #getNativeFrameCount()} to determine the actual buffer size
+ * requirements, use {@link #getBufferSizeInFrames()} to determine the actual buffer size
* in frames.
* @param bufferSizeInBytes a value strictly greater than 0
* @return the same Builder instance.
@@ -777,7 +777,7 @@ public class AudioRecord
}
/**
- * Returns the "native frame count" of the <code>AudioRecord</code> buffer.
+ * Returns the frame count of the native <code>AudioRecord</code> buffer.
* This is greater than or equal to the bufferSizeInBytes converted to frame units
* specified in the <code>AudioRecord</code> constructor or Builder.
* The native frame count may be enlarged to accommodate the requirements of the
@@ -786,8 +786,8 @@ public class AudioRecord
* @return current size in frames of the <code>AudioRecord</code> buffer.
* @throws IllegalStateException
*/
- public int getNativeFrameCount() throws IllegalStateException {
- return native_get_native_frame_count();
+ public int getBufferSizeInFrames() {
+ return native_get_buffer_size_in_frames();
}
/**
@@ -1218,16 +1218,23 @@ public class AudioRecord
//--------------------------------------------------------------------------
// (Re)Routing Info
//--------------------
+ /**
+ * Defines the interface by which applications can receive notifications of routing
+ * changes for the associated {@link AudioRecord}.
+ */
public interface OnRoutingChangedListener {
/**
* Called when the routing of an AudioRecord changes from either and explicit or
- * policy rerouting.
+ * policy rerouting. Use {@link #getRoutedDevice()} to retrieve the newly routed-from
+ * device.
*/
public void onRoutingChanged(AudioRecord audioRecord);
}
/**
* Returns an {@link AudioDeviceInfo} identifying the current routing of this AudioRecord.
+ * Note: The query is only valid if the AudioRecord is currently recording. If it is not,
+ * <code>getRoutedDevice()</code> will return null.
*/
public AudioDeviceInfo getRoutedDevice() {
int deviceId = native_getRoutedDeviceId();
@@ -1245,8 +1252,9 @@ public class AudioRecord
}
/**
- * The message sent to apps when the routing of this AudioRecord changes if they provide
- * a {#link Handler} object to addOnRoutingChangeListener().
+ * The list of AudioRecord.OnRoutingChangedListener interface added (with
+ * {@link AudioRecord#addOnRoutingChangedListener(OnRoutingChangedListener,android.os.Handler)}
+ * by an app to receive (re)routing notifications.
*/
private ArrayMap<OnRoutingChangedListener, NativeRoutingEventHandlerDelegate>
mRoutingChangeListeners =
@@ -1255,6 +1263,11 @@ public class AudioRecord
/**
* Adds an {@link OnRoutingChangedListener} to receive notifications of routing changes
* on this AudioRecord.
+ * @param listener The {@link OnRoutingChangedListener} interface to receive notifications
+ * of rerouting events.
+ * @param handler Specifies the {@link Handler} object for the thread on which to execute
+ * the callback. If <code>null</code>, the {@link Handler} associated with the main
+ * {@link Looper} will be used.
*/
public void addOnRoutingChangedListener(OnRoutingChangedListener listener,
android.os.Handler handler) {
@@ -1271,7 +1284,8 @@ public class AudioRecord
/**
* Removes an {@link OnRoutingChangedListener} which has been previously added
- * to receive notifications of changes to the set of connected audio devices.
+ * to receive rerouting notifications.
+ * @param listener The previously added {@link OnRoutingChangedListener} interface to remove.
*/
public void removeOnRoutingChangedListener(OnRoutingChangedListener listener) {
synchronized (mRoutingChangeListeners) {
@@ -1528,7 +1542,7 @@ public class AudioRecord
private native final int native_read_in_direct_buffer(Object jBuffer,
int sizeInBytes, boolean isBlocking);
- private native final int native_get_native_frame_count();
+ private native final int native_get_buffer_size_in_frames();
private native final int native_set_marker_pos(int marker);
private native final int native_get_marker_pos();
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index d21762b..bd7a247 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -229,7 +229,7 @@ public class AudioTrack
/**
* Sizes of the native audio buffer.
* These values are set during construction and can be stale.
- * To obtain the current native audio buffer frame count use {@link #getNativeFrameCount()}.
+ * To obtain the current native audio buffer frame count use {@link #getBufferSizeInFrames()}.
*/
private int mNativeBufferSizeInBytes = 0;
private int mNativeBufferSizeInFrames = 0;
@@ -346,7 +346,7 @@ public class AudioTrack
* If <code>bufferSizeInBytes</code> is less than the
* minimum buffer size for the output sink, it is automatically increased to the minimum
* buffer size.
- * The method {@link #getNativeFrameCount()} returns the
+ * The method {@link #getBufferSizeInFrames()} returns the
* actual size in frames of the native buffer created, which
* determines the frequency to write
* to the streaming <code>AudioTrack</code> to avoid underrun.
@@ -775,7 +775,7 @@ public class AudioTrack
audioFormat = AudioFormat.ENCODING_PCM_16BIT;
}
- if (!AudioFormat.isValidEncoding(audioFormat)) {
+ if (!AudioFormat.isPublicEncoding(audioFormat)) {
throw new IllegalArgumentException("Unsupported audio encoding.");
}
mAudioFormat = audioFormat;
@@ -1009,7 +1009,7 @@ public class AudioTrack
}
/**
- * Returns the "native frame count" of the <code>AudioTrack</code> buffer.
+ * Returns the frame count of the native <code>AudioTrack</code> buffer.
* <p> If the track's creation mode is {@link #MODE_STATIC},
* it is equal to the specified bufferSizeInBytes on construction, converted to frame units.
* A static track's native frame count will not change.
@@ -1019,12 +1019,26 @@ public class AudioTrack
* the target output sink, and
* if the track is subsequently routed to a different output sink, the native
* frame count may enlarge to accommodate.
- * See also {@link AudioManager#getProperty(String)} for key
+ * <p> If the <code>AudioTrack</code> encoding indicates compressed data,
+ * e.g. {@link AudioFormat#ENCODING_AC3}, then the frame count returned is
+ * the size of the native <code>AudioTrack</code> buffer in bytes.
+ * <p> See also {@link AudioManager#getProperty(String)} for key
* {@link AudioManager#PROPERTY_OUTPUT_FRAMES_PER_BUFFER}.
- * @return current size in frames of the audio track buffer.
+ * @return current size in frames of the <code>AudioTrack</code> buffer.
* @throws IllegalStateException
*/
- public int getNativeFrameCount() throws IllegalStateException {
+ public int getBufferSizeInFrames() {
+ return native_get_native_frame_count();
+ }
+
+ /**
+ * Returns the frame count of the native <code>AudioTrack</code> buffer.
+ * @return current size in frames of the <code>AudioTrack</code> buffer.
+ * @throws IllegalStateException
+ * @deprecated Use the identical public method {@link #getBufferSizeInFrames()} instead.
+ */
+ @Deprecated
+ protected int getNativeFrameCount() {
return native_get_native_frame_count();
}
@@ -1119,7 +1133,7 @@ public class AudioTrack
}
}
- if (!AudioFormat.isValidEncoding(audioFormat)) {
+ if (!AudioFormat.isPublicEncoding(audioFormat)) {
loge("getMinBufferSize(): Invalid audio format.");
return ERROR_BAD_VALUE;
}
@@ -1305,6 +1319,9 @@ public class AudioTrack
* The valid sample rate range is from 1 Hz to twice the value returned by
* {@link #getNativeOutputSampleRate(int)}.
* Use {@link #setPlaybackParams(PlaybackParams)} for speed control.
+ * <p> This method may also be used to repurpose an existing <code>AudioTrack</code>
+ * for playback of content of differing sample rate,
+ * but with identical encoding and channel mask.
* @param sampleRateInHz the sample rate expressed in Hz
* @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE},
* {@link #ERROR_INVALID_OPERATION}
@@ -1474,7 +1491,7 @@ public class AudioTrack
* <p>
* If the mode is {@link #MODE_STREAM}, you can optionally prime the data path prior to
* calling play(), by writing up to <code>bufferSizeInBytes</code> (from constructor).
- * If you don’t call write() first, or if you call write() but with an insufficient amount of
+ * If you don't call write() first, or if you call write() but with an insufficient amount of
* data, then the track will be in underrun state at play(). In this case,
* playback will not actually start playing until the data path is filled to a
* device-specific minimum level. This requirement for the path to be filled
@@ -2153,16 +2170,23 @@ public class AudioTrack
//--------------------------------------------------------------------------
// (Re)Routing Info
//--------------------
+ /**
+ * Defines the interface by which applications can receive notifications of routing
+ * changes for the associated {@link AudioTrack}.
+ */
public interface OnRoutingChangedListener {
/**
* Called when the routing of an AudioTrack changes from either and explicit or
- * policy rerouting.
+ * policy rerouting. Use {@link #getRoutedDevice()} to retrieve the newly routed-to
+ * device.
*/
public void onRoutingChanged(AudioTrack audioTrack);
}
/**
* Returns an {@link AudioDeviceInfo} identifying the current routing of this AudioTrack.
+ * Note: The query is only valid if the AudioTrack is currently playing. If it is not,
+ * <code>getRoutedDevice()</code> will return null.
*/
public AudioDeviceInfo getRoutedDevice() {
int deviceId = native_getRoutedDeviceId();
@@ -2180,8 +2204,9 @@ public class AudioTrack
}
/**
- * The message sent to apps when the routing of this AudioTrack changes if they provide
- * a {#link Handler} object to addOnRoutingChangedListener().
+ * The list of AudioTrack.OnRoutingChangedListener interfaces added (with
+ * {@link AudioTrack#addOnRoutingChangedListener(OnRoutingChangedListener, android.os.Handler)}
+ * by an app to receive (re)routing notifications.
*/
private ArrayMap<OnRoutingChangedListener, NativeRoutingEventHandlerDelegate>
mRoutingChangeListeners =
@@ -2190,6 +2215,11 @@ public class AudioTrack
/**
* Adds an {@link OnRoutingChangedListener} to receive notifications of routing changes
* on this AudioTrack.
+ * @param listener The {@link OnRoutingChangedListener} interface to receive notifications
+ * of rerouting events.
+ * @param handler Specifies the {@link Handler} object for the thread on which to execute
+ * the callback. If <code>null</code>, the {@link Handler} associated with the main
+ * {@link Looper} will be used.
*/
public void addOnRoutingChangedListener(OnRoutingChangedListener listener,
android.os.Handler handler) {
@@ -2206,7 +2236,8 @@ public class AudioTrack
/**
* Removes an {@link OnRoutingChangedListener} which has been previously added
- * to receive notifications of changes to the set of connected audio devices.
+ * to receive rerouting notifications.
+ * @param listener The previously added {@link OnRoutingChangedListener} interface to remove.
*/
public void removeOnRoutingChangedListener(OnRoutingChangedListener listener) {
synchronized (mRoutingChangeListeners) {
diff --git a/packages/Keyguard/res/values-h650dp/dimens.xml b/packages/Keyguard/res/values-h650dp/dimens.xml
index 92035bb..1cd2162 100644
--- a/packages/Keyguard/res/values-h650dp/dimens.xml
+++ b/packages/Keyguard/res/values-h650dp/dimens.xml
@@ -16,5 +16,5 @@
-->
<resources>
- <dimen name="widget_big_font_size">104dp</dimen>
+ <dimen name="widget_big_font_size">100dp</dimen>
</resources> \ No newline at end of file
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 5fece8d..5360645 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -361,9 +361,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
Log.d(TAG, "Fingerprint disabled by DPM for userId: " + userId);
return;
}
- if (groupId == userId) {
- onFingerprintAuthenticated(groupId);
- }
+ onFingerprintAuthenticated(userId);
} finally {
setFingerprintRunningDetectionRunning(false);
}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index ad710a6..1dba942 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -201,14 +201,14 @@ public class SettingsProvider extends ContentProvider {
@GuardedBy("mLock")
private SettingsRegistry mSettingsRegistry;
- @GuardedBy("mLock")
- private UserManager mUserManager;
+ // We have to call in the user manager with no lock held,
+ private volatile UserManager mUserManager;
- @GuardedBy("mLock")
- private AppOpsManager mAppOpsManager;
+ // We have to call in the app ops manager with no lock held,
+ private volatile AppOpsManager mAppOpsManager;
- @GuardedBy("mLock")
- private PackageManager mPackageManager;
+ // We have to call in the package manager with no lock held,
+ private volatile PackageManager mPackageManager;
@Override
public boolean onCreate() {
@@ -224,44 +224,46 @@ public class SettingsProvider extends ContentProvider {
@Override
public Bundle call(String method, String name, Bundle args) {
- synchronized (mLock) {
- final int requestingUserId = getRequestingUserId(args);
- switch (method) {
- case Settings.CALL_METHOD_GET_GLOBAL: {
- Setting setting = getGlobalSettingLocked(name);
- return packageValueForCallResult(setting);
- }
-
- case Settings.CALL_METHOD_GET_SECURE: {
- Setting setting = getSecureSettingLocked(name, requestingUserId);
- return packageValueForCallResult(setting);
- }
+ final int requestingUserId = getRequestingUserId(args);
+ switch (method) {
+ case Settings.CALL_METHOD_GET_GLOBAL: {
+ Setting setting = getGlobalSetting(name);
+ return packageValueForCallResult(setting);
+ }
- case Settings.CALL_METHOD_GET_SYSTEM: {
- Setting setting = getSystemSettingLocked(name, requestingUserId);
- return packageValueForCallResult(setting);
- }
+ case Settings.CALL_METHOD_GET_SECURE: {
+ Setting setting = getSecureSetting(name, requestingUserId);
+ return packageValueForCallResult(setting);
+ }
- case Settings.CALL_METHOD_PUT_GLOBAL: {
- String value = getSettingValue(args);
- insertGlobalSettingLocked(name, value, requestingUserId);
- } break;
+ case Settings.CALL_METHOD_GET_SYSTEM: {
+ Setting setting = getSystemSetting(name, requestingUserId);
+ return packageValueForCallResult(setting);
+ }
- case Settings.CALL_METHOD_PUT_SECURE: {
- String value = getSettingValue(args);
- insertSecureSettingLocked(name, value, requestingUserId);
- } break;
+ case Settings.CALL_METHOD_PUT_GLOBAL: {
+ String value = getSettingValue(args);
+ insertGlobalSetting(name, value, requestingUserId);
+ break;
+ }
- case Settings.CALL_METHOD_PUT_SYSTEM: {
- String value = getSettingValue(args);
- insertSystemSettingLocked(name, value, requestingUserId);
- } break;
+ case Settings.CALL_METHOD_PUT_SECURE: {
+ String value = getSettingValue(args);
+ insertSecureSetting(name, value, requestingUserId);
+ break;
+ }
- default: {
- Slog.w(LOG_TAG, "call() with invalid method: " + method);
- } break;
+ case Settings.CALL_METHOD_PUT_SYSTEM: {
+ String value = getSettingValue(args);
+ insertSystemSetting(name, value, requestingUserId);
+ break;
}
+
+ default: {
+ Slog.w(LOG_TAG, "call() with invalid method: " + method);
+ } break;
}
+
return null;
}
@@ -271,7 +273,7 @@ public class SettingsProvider extends ContentProvider {
if (TextUtils.isEmpty(args.name)) {
return "vnd.android.cursor.dir/" + args.table;
} else {
- return "vnd.android.cursor.item/" + args.table;
+ return "vnd.android.cursor.item/" + args.table;
}
}
@@ -290,40 +292,38 @@ public class SettingsProvider extends ContentProvider {
return new MatrixCursor(normalizedProjection, 0);
}
- synchronized (mLock) {
- switch (args.table) {
- case TABLE_GLOBAL: {
- if (args.name != null) {
- Setting setting = getGlobalSettingLocked(args.name);
- return packageSettingForQuery(setting, normalizedProjection);
- } else {
- return getAllGlobalSettingsLocked(projection);
- }
+ switch (args.table) {
+ case TABLE_GLOBAL: {
+ if (args.name != null) {
+ Setting setting = getGlobalSetting(args.name);
+ return packageSettingForQuery(setting, normalizedProjection);
+ } else {
+ return getAllGlobalSettings(projection);
}
+ }
- case TABLE_SECURE: {
- final int userId = UserHandle.getCallingUserId();
- if (args.name != null) {
- Setting setting = getSecureSettingLocked(args.name, userId);
- return packageSettingForQuery(setting, normalizedProjection);
- } else {
- return getAllSecureSettingsLocked(userId, projection);
- }
+ case TABLE_SECURE: {
+ final int userId = UserHandle.getCallingUserId();
+ if (args.name != null) {
+ Setting setting = getSecureSetting(args.name, userId);
+ return packageSettingForQuery(setting, normalizedProjection);
+ } else {
+ return getAllSecureSettings(userId, projection);
}
+ }
- case TABLE_SYSTEM: {
- final int userId = UserHandle.getCallingUserId();
- if (args.name != null) {
- Setting setting = getSystemSettingLocked(args.name, userId);
- return packageSettingForQuery(setting, normalizedProjection);
- } else {
- return getAllSystemSettingsLocked(userId, projection);
- }
+ case TABLE_SYSTEM: {
+ final int userId = UserHandle.getCallingUserId();
+ if (args.name != null) {
+ Setting setting = getSystemSetting(args.name, userId);
+ return packageSettingForQuery(setting, normalizedProjection);
+ } else {
+ return getAllSystemSettings(userId, projection);
}
+ }
- default: {
- throw new IllegalArgumentException("Invalid Uri path:" + uri);
- }
+ default: {
+ throw new IllegalArgumentException("Invalid Uri path:" + uri);
}
}
}
@@ -348,29 +348,27 @@ public class SettingsProvider extends ContentProvider {
String value = values.getAsString(Settings.Secure.VALUE);
- synchronized (mLock) {
- switch (table) {
- case TABLE_GLOBAL: {
- if (insertGlobalSettingLocked(name, value, UserHandle.getCallingUserId())) {
- return Uri.withAppendedPath(Settings.Global.CONTENT_URI, name);
- }
- } break;
-
- case TABLE_SECURE: {
- if (insertSecureSettingLocked(name, value, UserHandle.getCallingUserId())) {
- return Uri.withAppendedPath(Settings.Secure.CONTENT_URI, name);
- }
- } break;
+ switch (table) {
+ case TABLE_GLOBAL: {
+ if (insertGlobalSetting(name, value, UserHandle.getCallingUserId())) {
+ return Uri.withAppendedPath(Settings.Global.CONTENT_URI, name);
+ }
+ } break;
- case TABLE_SYSTEM: {
- if (insertSystemSettingLocked(name, value, UserHandle.getCallingUserId())) {
- return Uri.withAppendedPath(Settings.System.CONTENT_URI, name);
- }
- } break;
+ case TABLE_SECURE: {
+ if (insertSecureSetting(name, value, UserHandle.getCallingUserId())) {
+ return Uri.withAppendedPath(Settings.Secure.CONTENT_URI, name);
+ }
+ } break;
- default: {
- throw new IllegalArgumentException("Bad Uri path:" + uri);
+ case TABLE_SYSTEM: {
+ if (insertSystemSetting(name, value, UserHandle.getCallingUserId())) {
+ return Uri.withAppendedPath(Settings.System.CONTENT_URI, name);
}
+ } break;
+
+ default: {
+ throw new IllegalArgumentException("Bad Uri path:" + uri);
}
}
@@ -412,26 +410,25 @@ public class SettingsProvider extends ContentProvider {
return 0;
}
- synchronized (mLock) {
- switch (args.table) {
- case TABLE_GLOBAL: {
- final int userId = UserHandle.getCallingUserId();
- return deleteGlobalSettingLocked(args.name, userId) ? 1 : 0;
- }
- case TABLE_SECURE: {
- final int userId = UserHandle.getCallingUserId();
- return deleteSecureSettingLocked(args.name, userId) ? 1 : 0;
- }
+ switch (args.table) {
+ case TABLE_GLOBAL: {
+ final int userId = UserHandle.getCallingUserId();
+ return deleteGlobalSetting(args.name, userId) ? 1 : 0;
+ }
- case TABLE_SYSTEM: {
- final int userId = UserHandle.getCallingUserId();
- return deleteSystemSettingLocked(args.name, userId) ? 1 : 0;
- }
+ case TABLE_SECURE: {
+ final int userId = UserHandle.getCallingUserId();
+ return deleteSecureSetting(args.name, userId) ? 1 : 0;
+ }
- default: {
- throw new IllegalArgumentException("Bad Uri path:" + uri);
- }
+ case TABLE_SYSTEM: {
+ final int userId = UserHandle.getCallingUserId();
+ return deleteSystemSetting(args.name, userId) ? 1 : 0;
+ }
+
+ default: {
+ throw new IllegalArgumentException("Bad Uri path:" + uri);
}
}
}
@@ -454,26 +451,24 @@ public class SettingsProvider extends ContentProvider {
return 0;
}
- synchronized (mLock) {
- switch (args.table) {
- case TABLE_GLOBAL: {
- final int userId = UserHandle.getCallingUserId();
- return updateGlobalSettingLocked(args.name, value, userId) ? 1 : 0;
- }
+ switch (args.table) {
+ case TABLE_GLOBAL: {
+ final int userId = UserHandle.getCallingUserId();
+ return updateGlobalSetting(args.name, value, userId) ? 1 : 0;
+ }
- case TABLE_SECURE: {
- final int userId = UserHandle.getCallingUserId();
- return updateSecureSettingLocked(args.name, value, userId) ? 1 : 0;
- }
+ case TABLE_SECURE: {
+ final int userId = UserHandle.getCallingUserId();
+ return updateSecureSetting(args.name, value, userId) ? 1 : 0;
+ }
- case TABLE_SYSTEM: {
- final int userId = UserHandle.getCallingUserId();
- return updateSystemSettingLocked(args.name, value, userId) ? 1 : 0;
- }
+ case TABLE_SYSTEM: {
+ final int userId = UserHandle.getCallingUserId();
+ return updateSystemSetting(args.name, value, userId) ? 1 : 0;
+ }
- default: {
- throw new IllegalArgumentException("Invalid Uri path:" + uri);
- }
+ default: {
+ throw new IllegalArgumentException("Invalid Uri path:" + uri);
}
}
}
@@ -504,18 +499,18 @@ public class SettingsProvider extends ContentProvider {
private void dumpForUser(int userId, PrintWriter pw) {
if (userId == UserHandle.USER_OWNER) {
pw.println("GLOBAL SETTINGS (user " + userId + ")");
- Cursor globalCursor = getAllGlobalSettingsLocked(ALL_COLUMNS);
+ Cursor globalCursor = getAllGlobalSettings(ALL_COLUMNS);
dumpSettings(globalCursor, pw);
pw.println();
}
pw.println("SECURE SETTINGS (user " + userId + ")");
- Cursor secureCursor = getAllSecureSettingsLocked(userId, ALL_COLUMNS);
+ Cursor secureCursor = getAllSecureSettings(userId, ALL_COLUMNS);
dumpSettings(secureCursor, pw);
pw.println();
pw.println("SYSTEM SETTINGS (user " + userId + ")");
- Cursor systemCursor = getAllSystemSettingsLocked(userId, ALL_COLUMNS);
+ Cursor systemCursor = getAllSystemSettings(userId, ALL_COLUMNS);
dumpSettings(systemCursor, pw);
pw.println();
}
@@ -575,64 +570,68 @@ public class SettingsProvider extends ContentProvider {
UserHandle.ALL, true);
}
- private Cursor getAllGlobalSettingsLocked(String[] projection) {
+ private Cursor getAllGlobalSettings(String[] projection) {
if (DEBUG) {
- Slog.v(LOG_TAG, "getAllGlobalSettingsLocked()");
+ Slog.v(LOG_TAG, "getAllGlobalSettings()");
}
- // Get the settings.
- SettingsState settingsState = mSettingsRegistry.getSettingsLocked(
- SettingsRegistry.SETTINGS_TYPE_GLOBAL, UserHandle.USER_OWNER);
+ synchronized (mLock) {
+ // Get the settings.
+ SettingsState settingsState = mSettingsRegistry.getSettingsLocked(
+ SettingsRegistry.SETTINGS_TYPE_GLOBAL, UserHandle.USER_OWNER);
- List<String> names = settingsState.getSettingNamesLocked();
+ List<String> names = settingsState.getSettingNamesLocked();
- final int nameCount = names.size();
+ final int nameCount = names.size();
- String[] normalizedProjection = normalizeProjection(projection);
- MatrixCursor result = new MatrixCursor(normalizedProjection, nameCount);
+ String[] normalizedProjection = normalizeProjection(projection);
+ MatrixCursor result = new MatrixCursor(normalizedProjection, nameCount);
- // Anyone can get the global settings, so no security checks.
- for (int i = 0; i < nameCount; i++) {
- String name = names.get(i);
- Setting setting = settingsState.getSettingLocked(name);
- appendSettingToCursor(result, setting);
- }
+ // Anyone can get the global settings, so no security checks.
+ for (int i = 0; i < nameCount; i++) {
+ String name = names.get(i);
+ Setting setting = settingsState.getSettingLocked(name);
+ appendSettingToCursor(result, setting);
+ }
- return result;
+ return result;
+ }
}
- private Setting getGlobalSettingLocked(String name) {
+ private Setting getGlobalSetting(String name) {
if (DEBUG) {
Slog.v(LOG_TAG, "getGlobalSetting(" + name + ")");
}
// Get the value.
- return mSettingsRegistry.getSettingLocked(SettingsRegistry.SETTINGS_TYPE_GLOBAL,
- UserHandle.USER_OWNER, name);
+ synchronized (mLock) {
+ return mSettingsRegistry.getSettingLocked(SettingsRegistry.SETTINGS_TYPE_GLOBAL,
+ UserHandle.USER_OWNER, name);
+ }
}
- private boolean updateGlobalSettingLocked(String name, String value, int requestingUserId) {
+ private boolean updateGlobalSetting(String name, String value, int requestingUserId) {
if (DEBUG) {
- Slog.v(LOG_TAG, "updateGlobalSettingLocked(" + name + ", " + value + ")");
+ Slog.v(LOG_TAG, "updateGlobalSetting(" + name + ", " + value + ")");
}
- return mutateGlobalSettingLocked(name, value, requestingUserId, MUTATION_OPERATION_UPDATE);
+ return mutateGlobalSetting(name, value, requestingUserId, MUTATION_OPERATION_UPDATE);
}
- private boolean insertGlobalSettingLocked(String name, String value, int requestingUserId) {
+ private boolean insertGlobalSetting(String name, String value, int requestingUserId) {
if (DEBUG) {
- Slog.v(LOG_TAG, "insertGlobalSettingLocked(" + name + ", " + value + ")");
+ Slog.v(LOG_TAG, "insertGlobalSetting(" + name + ", " + value + ")");
}
- return mutateGlobalSettingLocked(name, value, requestingUserId, MUTATION_OPERATION_INSERT);
+ return mutateGlobalSetting(name, value, requestingUserId, MUTATION_OPERATION_INSERT);
}
- private boolean deleteGlobalSettingLocked(String name, int requestingUserId) {
+ private boolean deleteGlobalSetting(String name, int requestingUserId) {
if (DEBUG) {
Slog.v(LOG_TAG, "deleteGlobalSettingLocked(" + name + ")");
}
- return mutateGlobalSettingLocked(name, null, requestingUserId, MUTATION_OPERATION_DELETE);
+ return mutateGlobalSetting(name, null, requestingUserId, MUTATION_OPERATION_DELETE);
}
- private boolean mutateGlobalSettingLocked(String name, String value, int requestingUserId,
+ private boolean mutateGlobalSetting(String name, String value, int requestingUserId,
int operation) {
// Make sure the caller can change the settings - treated as secure.
enforceWritePermission(Manifest.permission.WRITE_SECURE_SETTINGS);
@@ -651,28 +650,32 @@ public class SettingsProvider extends ContentProvider {
}
// Perform the mutation.
- switch (operation) {
- case MUTATION_OPERATION_INSERT: {
- return mSettingsRegistry.insertSettingLocked(SettingsRegistry.SETTINGS_TYPE_GLOBAL,
- UserHandle.USER_OWNER, name, value, getCallingPackage());
- }
+ synchronized (mLock) {
+ switch (operation) {
+ case MUTATION_OPERATION_INSERT: {
+ return mSettingsRegistry
+ .insertSettingLocked(SettingsRegistry.SETTINGS_TYPE_GLOBAL,
+ UserHandle.USER_OWNER, name, value, getCallingPackage());
+ }
- case MUTATION_OPERATION_DELETE: {
- return mSettingsRegistry.deleteSettingLocked(
- SettingsRegistry.SETTINGS_TYPE_GLOBAL,
- UserHandle.USER_OWNER, name);
- }
+ case MUTATION_OPERATION_DELETE: {
+ return mSettingsRegistry.deleteSettingLocked(
+ SettingsRegistry.SETTINGS_TYPE_GLOBAL,
+ UserHandle.USER_OWNER, name);
+ }
- case MUTATION_OPERATION_UPDATE: {
- return mSettingsRegistry.updateSettingLocked(SettingsRegistry.SETTINGS_TYPE_GLOBAL,
- UserHandle.USER_OWNER, name, value, getCallingPackage());
+ case MUTATION_OPERATION_UPDATE: {
+ return mSettingsRegistry
+ .updateSettingLocked(SettingsRegistry.SETTINGS_TYPE_GLOBAL,
+ UserHandle.USER_OWNER, name, value, getCallingPackage());
+ }
}
}
return false;
}
- private Cursor getAllSecureSettingsLocked(int userId, String[] projection) {
+ private Cursor getAllSecureSettings(int userId, String[] projection) {
if (DEBUG) {
Slog.v(LOG_TAG, "getAllSecureSettings(" + userId + ")");
}
@@ -680,34 +683,36 @@ public class SettingsProvider extends ContentProvider {
// Resolve the userId on whose behalf the call is made.
final int callingUserId = resolveCallingUserIdEnforcingPermissionsLocked(userId);
- List<String> names = mSettingsRegistry.getSettingsNamesLocked(
- SettingsRegistry.SETTINGS_TYPE_SECURE, callingUserId);
+ synchronized (mLock) {
+ List<String> names = mSettingsRegistry.getSettingsNamesLocked(
+ SettingsRegistry.SETTINGS_TYPE_SECURE, callingUserId);
- final int nameCount = names.size();
+ final int nameCount = names.size();
- String[] normalizedProjection = normalizeProjection(projection);
- MatrixCursor result = new MatrixCursor(normalizedProjection, nameCount);
+ String[] normalizedProjection = normalizeProjection(projection);
+ MatrixCursor result = new MatrixCursor(normalizedProjection, nameCount);
- for (int i = 0; i < nameCount; i++) {
- String name = names.get(i);
+ for (int i = 0; i < nameCount; i++) {
+ String name = names.get(i);
+ // Determine the owning user as some profile settings are cloned from the parent.
+ final int owningUserId = resolveOwningUserIdForSecureSettingLocked(callingUserId,
+ name);
- // Determine the owning user as some profile settings are cloned from the parent.
- final int owningUserId = resolveOwningUserIdForSecureSettingLocked(callingUserId, name);
+ // Special case for location (sigh).
+ if (isLocationProvidersAllowedRestricted(name, callingUserId, owningUserId)) {
+ return null;
+ }
- // Special case for location (sigh).
- if (isLocationProvidersAllowedRestricted(name, callingUserId, owningUserId)) {
- return null;
+ Setting setting = mSettingsRegistry.getSettingLocked(
+ SettingsRegistry.SETTINGS_TYPE_SECURE, owningUserId, name);
+ appendSettingToCursor(result, setting);
}
- Setting setting = mSettingsRegistry.getSettingLocked(
- SettingsRegistry.SETTINGS_TYPE_SECURE, owningUserId, name);
- appendSettingToCursor(result, setting);
+ return result;
}
-
- return result;
}
- private Setting getSecureSettingLocked(String name, int requestingUserId) {
+ private Setting getSecureSetting(String name, int requestingUserId) {
if (DEBUG) {
Slog.v(LOG_TAG, "getSecureSetting(" + name + ", " + requestingUserId + ")");
}
@@ -724,37 +729,39 @@ public class SettingsProvider extends ContentProvider {
}
// Get the value.
- return mSettingsRegistry.getSettingLocked(SettingsRegistry.SETTINGS_TYPE_SECURE,
- owningUserId, name);
+ synchronized (mLock) {
+ return mSettingsRegistry.getSettingLocked(SettingsRegistry.SETTINGS_TYPE_SECURE,
+ owningUserId, name);
+ }
}
- private boolean insertSecureSettingLocked(String name, String value, int requestingUserId) {
+ private boolean insertSecureSetting(String name, String value, int requestingUserId) {
if (DEBUG) {
- Slog.v(LOG_TAG, "insertSecureSettingLocked(" + name + ", " + value + ", "
+ Slog.v(LOG_TAG, "insertSecureSetting(" + name + ", " + value + ", "
+ requestingUserId + ")");
}
- return mutateSecureSettingLocked(name, value, requestingUserId, MUTATION_OPERATION_INSERT);
+ return mutateSecureSetting(name, value, requestingUserId, MUTATION_OPERATION_INSERT);
}
- private boolean deleteSecureSettingLocked(String name, int requestingUserId) {
+ private boolean deleteSecureSetting(String name, int requestingUserId) {
if (DEBUG) {
- Slog.v(LOG_TAG, "deleteSecureSettingLocked(" + name + ", " + requestingUserId + ")");
+ Slog.v(LOG_TAG, "deleteSecureSetting(" + name + ", " + requestingUserId + ")");
}
- return mutateSecureSettingLocked(name, null, requestingUserId, MUTATION_OPERATION_DELETE);
+ return mutateSecureSetting(name, null, requestingUserId, MUTATION_OPERATION_DELETE);
}
- private boolean updateSecureSettingLocked(String name, String value, int requestingUserId) {
+ private boolean updateSecureSetting(String name, String value, int requestingUserId) {
if (DEBUG) {
- Slog.v(LOG_TAG, "updateSecureSettingLocked(" + name + ", " + value + ", "
+ Slog.v(LOG_TAG, "updateSecureSetting(" + name + ", " + value + ", "
+ requestingUserId + ")");
}
- return mutateSecureSettingLocked(name, value, requestingUserId, MUTATION_OPERATION_UPDATE);
+ return mutateSecureSetting(name, value, requestingUserId, MUTATION_OPERATION_UPDATE);
}
- private boolean mutateSecureSettingLocked(String name, String value, int requestingUserId,
+ private boolean mutateSecureSetting(String name, String value, int requestingUserId,
int operation) {
// Make sure the caller can change the settings.
enforceWritePermission(Manifest.permission.WRITE_SECURE_SETTINGS);
@@ -786,58 +793,65 @@ public class SettingsProvider extends ContentProvider {
}
// Mutate the value.
- switch(operation) {
- case MUTATION_OPERATION_INSERT: {
- return mSettingsRegistry.insertSettingLocked(SettingsRegistry.SETTINGS_TYPE_SECURE,
- owningUserId, name, value, getCallingPackage());
- }
+ synchronized (mLock) {
+ switch (operation) {
+ case MUTATION_OPERATION_INSERT: {
+ return mSettingsRegistry
+ .insertSettingLocked(SettingsRegistry.SETTINGS_TYPE_SECURE,
+ owningUserId, name, value, getCallingPackage());
+ }
- case MUTATION_OPERATION_DELETE: {
- return mSettingsRegistry.deleteSettingLocked(
- SettingsRegistry.SETTINGS_TYPE_SECURE,
- owningUserId, name);
- }
+ case MUTATION_OPERATION_DELETE: {
+ return mSettingsRegistry.deleteSettingLocked(
+ SettingsRegistry.SETTINGS_TYPE_SECURE,
+ owningUserId, name);
+ }
- case MUTATION_OPERATION_UPDATE: {
- return mSettingsRegistry.updateSettingLocked(SettingsRegistry.SETTINGS_TYPE_SECURE,
- owningUserId, name, value, getCallingPackage());
+ case MUTATION_OPERATION_UPDATE: {
+ return mSettingsRegistry
+ .updateSettingLocked(SettingsRegistry.SETTINGS_TYPE_SECURE,
+ owningUserId, name, value, getCallingPackage());
+ }
}
}
return false;
}
- private Cursor getAllSystemSettingsLocked(int userId, String[] projection) {
+ private Cursor getAllSystemSettings(int userId, String[] projection) {
if (DEBUG) {
- Slog.v(LOG_TAG, "getAllSecureSystemLocked(" + userId + ")");
+ Slog.v(LOG_TAG, "getAllSecureSystem(" + userId + ")");
}
// Resolve the userId on whose behalf the call is made.
final int callingUserId = resolveCallingUserIdEnforcingPermissionsLocked(userId);
- List<String> names = mSettingsRegistry.getSettingsNamesLocked(
- SettingsRegistry.SETTINGS_TYPE_SYSTEM, callingUserId);
+ synchronized (mLock) {
+ List<String> names = mSettingsRegistry.getSettingsNamesLocked(
+ SettingsRegistry.SETTINGS_TYPE_SYSTEM, callingUserId);
- final int nameCount = names.size();
+ final int nameCount = names.size();
- String[] normalizedProjection = normalizeProjection(projection);
- MatrixCursor result = new MatrixCursor(normalizedProjection, nameCount);
+ String[] normalizedProjection = normalizeProjection(projection);
+ MatrixCursor result = new MatrixCursor(normalizedProjection, nameCount);
- for (int i = 0; i < nameCount; i++) {
- String name = names.get(i);
+ for (int i = 0; i < nameCount; i++) {
+ String name = names.get(i);
- // Determine the owning user as some profile settings are cloned from the parent.
- final int owningUserId = resolveOwningUserIdForSystemSettingLocked(callingUserId, name);
+ // Determine the owning user as some profile settings are cloned from the parent.
+ final int owningUserId = resolveOwningUserIdForSystemSettingLocked(callingUserId,
+ name);
- Setting setting = mSettingsRegistry.getSettingLocked(
- SettingsRegistry.SETTINGS_TYPE_SYSTEM, owningUserId, name);
- appendSettingToCursor(result, setting);
- }
+ Setting setting = mSettingsRegistry.getSettingLocked(
+ SettingsRegistry.SETTINGS_TYPE_SYSTEM, owningUserId, name);
+ appendSettingToCursor(result, setting);
+ }
- return result;
+ return result;
+ }
}
- private Setting getSystemSettingLocked(String name, int requestingUserId) {
+ private Setting getSystemSetting(String name, int requestingUserId) {
if (DEBUG) {
Slog.v(LOG_TAG, "getSystemSetting(" + name + ", " + requestingUserId + ")");
}
@@ -849,37 +863,39 @@ public class SettingsProvider extends ContentProvider {
final int owningUserId = resolveOwningUserIdForSystemSettingLocked(callingUserId, name);
// Get the value.
- return mSettingsRegistry.getSettingLocked(SettingsRegistry.SETTINGS_TYPE_SYSTEM,
- owningUserId, name);
+ synchronized (mLock) {
+ return mSettingsRegistry.getSettingLocked(SettingsRegistry.SETTINGS_TYPE_SYSTEM,
+ owningUserId, name);
+ }
}
- private boolean insertSystemSettingLocked(String name, String value, int requestingUserId) {
+ private boolean insertSystemSetting(String name, String value, int requestingUserId) {
if (DEBUG) {
- Slog.v(LOG_TAG, "insertSystemSettingLocked(" + name + ", " + value + ", "
+ Slog.v(LOG_TAG, "insertSystemSetting(" + name + ", " + value + ", "
+ requestingUserId + ")");
}
- return mutateSystemSettingLocked(name, value, requestingUserId, MUTATION_OPERATION_INSERT);
+ return mutateSystemSetting(name, value, requestingUserId, MUTATION_OPERATION_INSERT);
}
- private boolean deleteSystemSettingLocked(String name, int requestingUserId) {
+ private boolean deleteSystemSetting(String name, int requestingUserId) {
if (DEBUG) {
- Slog.v(LOG_TAG, "deleteSystemSettingLocked(" + name + ", " + requestingUserId + ")");
+ Slog.v(LOG_TAG, "deleteSystemSetting(" + name + ", " + requestingUserId + ")");
}
- return mutateSystemSettingLocked(name, null, requestingUserId, MUTATION_OPERATION_DELETE);
+ return mutateSystemSetting(name, null, requestingUserId, MUTATION_OPERATION_DELETE);
}
- private boolean updateSystemSettingLocked(String name, String value, int requestingUserId) {
+ private boolean updateSystemSetting(String name, String value, int requestingUserId) {
if (DEBUG) {
- Slog.v(LOG_TAG, "updateSystemSettingLocked(" + name + ", " + value + ", "
+ Slog.v(LOG_TAG, "updateSystemSetting(" + name + ", " + value + ", "
+ requestingUserId + ")");
}
- return mutateSystemSettingLocked(name, value, requestingUserId, MUTATION_OPERATION_UPDATE);
+ return mutateSystemSetting(name, value, requestingUserId, MUTATION_OPERATION_UPDATE);
}
- private boolean mutateSystemSettingLocked(String name, String value, int runAsUserId,
+ private boolean mutateSystemSetting(String name, String value, int runAsUserId,
int operation) {
// Make sure the caller can change the settings.
enforceWritePermission(Manifest.permission.WRITE_SETTINGS);
@@ -904,27 +920,31 @@ public class SettingsProvider extends ContentProvider {
}
// Mutate the value.
- switch (operation) {
- case MUTATION_OPERATION_INSERT: {
- validateSystemSettingValue(name, value);
- return mSettingsRegistry.insertSettingLocked(SettingsRegistry.SETTINGS_TYPE_SYSTEM,
- owningUserId, name, value, getCallingPackage());
- }
+ synchronized (mLock) {
+ switch (operation) {
+ case MUTATION_OPERATION_INSERT: {
+ validateSystemSettingValue(name, value);
+ return mSettingsRegistry
+ .insertSettingLocked(SettingsRegistry.SETTINGS_TYPE_SYSTEM,
+ owningUserId, name, value, getCallingPackage());
+ }
- case MUTATION_OPERATION_DELETE: {
- return mSettingsRegistry.deleteSettingLocked(
- SettingsRegistry.SETTINGS_TYPE_SYSTEM,
- owningUserId, name);
- }
+ case MUTATION_OPERATION_DELETE: {
+ return mSettingsRegistry.deleteSettingLocked(
+ SettingsRegistry.SETTINGS_TYPE_SYSTEM,
+ owningUserId, name);
+ }
- case MUTATION_OPERATION_UPDATE: {
- validateSystemSettingValue(name, value);
- return mSettingsRegistry.updateSettingLocked(SettingsRegistry.SETTINGS_TYPE_SYSTEM,
- owningUserId, name, value, getCallingPackage());
+ case MUTATION_OPERATION_UPDATE: {
+ validateSystemSettingValue(name, value);
+ return mSettingsRegistry
+ .updateSettingLocked(SettingsRegistry.SETTINGS_TYPE_SYSTEM,
+ owningUserId, name, value, getCallingPackage());
+ }
}
- }
- return false;
+ return false;
+ }
}
private void validateSystemSettingValue(String name, String value) {
@@ -1043,6 +1063,7 @@ public class SettingsProvider extends ContentProvider {
// user info is a cached instance, so just look up instead of cache.
final long identity = Binder.clearCallingIdentity();
try {
+ // Just a lookup and not reentrant, so holding a lock is fine.
UserInfo userInfo = mUserManager.getProfileParent(userId);
return (userInfo != null) ? userInfo.id : userId;
} finally {
@@ -1088,7 +1109,7 @@ public class SettingsProvider extends ContentProvider {
// skip prefix
value = value.substring(1);
- Setting settingValue = getSecureSettingLocked(
+ Setting settingValue = getSecureSetting(
Settings.Secure.LOCATION_PROVIDERS_ALLOWED, owningUserId);
String oldProviders = (settingValue != null) ? settingValue.getValue() : "";
diff --git a/packages/StatementService/src/com/android/statementservice/retriever/AbstractAsset.java b/packages/StatementService/src/com/android/statementservice/retriever/AbstractAsset.java
index e71cf54..bb6bdbb 100644
--- a/packages/StatementService/src/com/android/statementservice/retriever/AbstractAsset.java
+++ b/packages/StatementService/src/com/android/statementservice/retriever/AbstractAsset.java
@@ -63,4 +63,10 @@ public abstract class AbstractAsset {
throws AssociationServiceException {
return AssetFactory.create(assetJson);
}
+
+ /**
+ * If this is the source asset of a statement file, should the retriever follow
+ * any insecure (non-HTTPS) include statements made by the asset.
+ */
+ public abstract boolean followInsecureInclude();
}
diff --git a/packages/StatementService/src/com/android/statementservice/retriever/AndroidAppAsset.java b/packages/StatementService/src/com/android/statementservice/retriever/AndroidAppAsset.java
index 0c96038..8ead90b 100644
--- a/packages/StatementService/src/com/android/statementservice/retriever/AndroidAppAsset.java
+++ b/packages/StatementService/src/com/android/statementservice/retriever/AndroidAppAsset.java
@@ -99,6 +99,12 @@ import java.util.Locale;
return getPackageName().hashCode();
}
+ @Override
+ public boolean followInsecureInclude() {
+ // Non-HTTPS includes are not allowed in Android App assets.
+ return false;
+ }
+
/**
* Checks that the input is a valid Android app asset.
*
diff --git a/packages/StatementService/src/com/android/statementservice/retriever/DirectStatementRetriever.java b/packages/StatementService/src/com/android/statementservice/retriever/DirectStatementRetriever.java
index 6516516..548149e 100644
--- a/packages/StatementService/src/com/android/statementservice/retriever/DirectStatementRetriever.java
+++ b/packages/StatementService/src/com/android/statementservice/retriever/DirectStatementRetriever.java
@@ -136,7 +136,8 @@ import java.util.List;
}
}
- private Result retrieveStatementFromUrl(String url, int maxIncludeLevel, AbstractAsset source)
+ private Result retrieveStatementFromUrl(String urlString, int maxIncludeLevel,
+ AbstractAsset source)
throws AssociationServiceException {
List<Statement> statements = new ArrayList<Statement>();
if (maxIncludeLevel < 0) {
@@ -145,7 +146,12 @@ import java.util.List;
WebContent webContent;
try {
- webContent = mUrlFetcher.getWebContentFromUrl(new URL(url),
+ URL url = new URL(urlString);
+ if (!source.followInsecureInclude()
+ && !url.getProtocol().toLowerCase().equals("https")) {
+ return Result.create(statements, DO_NOT_CACHE_RESULT);
+ }
+ webContent = mUrlFetcher.getWebContentFromUrl(url,
HTTP_CONTENT_SIZE_LIMIT_IN_BYTES, HTTP_CONNECTION_TIMEOUT_MILLIS);
} catch (IOException e) {
return Result.create(statements, DO_NOT_CACHE_RESULT);
diff --git a/packages/StatementService/src/com/android/statementservice/retriever/URLFetcher.java b/packages/StatementService/src/com/android/statementservice/retriever/URLFetcher.java
index 4828ff9..969aa88 100644
--- a/packages/StatementService/src/com/android/statementservice/retriever/URLFetcher.java
+++ b/packages/StatementService/src/com/android/statementservice/retriever/URLFetcher.java
@@ -16,6 +16,8 @@
package com.android.statementservice.retriever;
+import android.util.Log;
+
import com.android.volley.Cache;
import com.android.volley.NetworkResponse;
import com.android.volley.toolbox.HttpHeaderParser;
@@ -39,6 +41,7 @@ import java.util.Map;
* @hide
*/
public class URLFetcher {
+ private static final String TAG = URLFetcher.class.getSimpleName();
private static final long DO_NOT_CACHE_RESULT = 0L;
private static final int INPUT_BUFFER_SIZE_IN_BYTES = 1024;
@@ -63,11 +66,17 @@ public class URLFetcher {
connection.setConnectTimeout(connectionTimeoutMillis);
connection.setReadTimeout(connectionTimeoutMillis);
connection.setUseCaches(true);
+ connection.setInstanceFollowRedirects(false);
connection.addRequestProperty("Cache-Control", "max-stale=60");
+ if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
+ Log.e(TAG, "The responses code is not 200 but " + connection.getResponseCode());
+ return new WebContent("", DO_NOT_CACHE_RESULT);
+ }
+
if (connection.getContentLength() > fileSizeLimit) {
- throw new AssociationServiceException("The content size of the url is larger than "
- + fileSizeLimit);
+ Log.e(TAG, "The content size of the url is larger than " + fileSizeLimit);
+ return new WebContent("", DO_NOT_CACHE_RESULT);
}
Long expireTimeMillis = getExpirationTimeMillisFromHTTPHeader(connection.getHeaderFields());
diff --git a/packages/StatementService/src/com/android/statementservice/retriever/Utils.java b/packages/StatementService/src/com/android/statementservice/retriever/Utils.java
index 44af864..afb4c75 100644
--- a/packages/StatementService/src/com/android/statementservice/retriever/Utils.java
+++ b/packages/StatementService/src/com/android/statementservice/retriever/Utils.java
@@ -61,7 +61,7 @@ public final class Utils {
*/
public static final String ASSET_DESCRIPTOR_FIELD_RELATION = "relation";
public static final String ASSET_DESCRIPTOR_FIELD_TARGET = "target";
- public static final String DELEGATE_FIELD_DELEGATE = "delegate";
+ public static final String DELEGATE_FIELD_DELEGATE = "include";
private static final char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'A', 'B', 'C', 'D', 'E', 'F' };
diff --git a/packages/StatementService/src/com/android/statementservice/retriever/WebAsset.java b/packages/StatementService/src/com/android/statementservice/retriever/WebAsset.java
index ca9e62d..947087a 100644
--- a/packages/StatementService/src/com/android/statementservice/retriever/WebAsset.java
+++ b/packages/StatementService/src/com/android/statementservice/retriever/WebAsset.java
@@ -39,6 +39,7 @@ import java.util.Locale;
/* package private */ final class WebAsset extends AbstractAsset {
private static final String MISSING_FIELD_FORMAT_STRING = "Expected %s to be set.";
+ private static final String SCHEME_HTTP = "http";
private final URL mUrl;
@@ -105,6 +106,12 @@ import java.util.Locale;
return toJson().hashCode();
}
+ @Override
+ public boolean followInsecureInclude() {
+ // Only allow insecure include file if the asset scheme is http.
+ return SCHEME_HTTP.equals(getScheme());
+ }
+
/**
* Checks that the input is a valid web asset.
*
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ObservableScrollView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ObservableScrollView.java
index 1186a33..9e5cefd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ObservableScrollView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ObservableScrollView.java
@@ -99,7 +99,7 @@ public class ObservableScrollView extends ScrollView {
} else if (!mTouchEnabled) {
MotionEvent cancel = MotionEvent.obtain(ev);
cancel.setAction(MotionEvent.ACTION_CANCEL);
- super.dispatchTouchEvent(ev);
+ super.dispatchTouchEvent(cancel);
cancel.recycle();
mTouchCancelled = true;
return false;
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index 01cc2ca..ff8fb83 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -88,13 +88,13 @@ import android.util.Slog;
import android.util.SparseArray;
import android.util.StringBuilderPrinter;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.backup.IBackupTransport;
import com.android.internal.backup.IObbBackupService;
import com.android.server.AppWidgetBackupBridge;
import com.android.server.EventLogTags;
import com.android.server.SystemService;
import com.android.server.backup.PackageManagerBackupAgent.Metadata;
-import com.android.server.pm.PackageManagerService;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
@@ -589,8 +589,12 @@ public class BackupManagerService {
File mFullBackupScheduleFile;
// If we're running a schedule-driven full backup, this is the task instance doing it
- PerformFullTransportBackupTask mRunningFullBackupTask; // inside mQueueLock
- ArrayList<FullBackupEntry> mFullBackupQueue; // inside mQueueLock
+
+ @GuardedBy("mQueueLock")
+ PerformFullTransportBackupTask mRunningFullBackupTask;
+
+ @GuardedBy("mQueueLock")
+ ArrayList<FullBackupEntry> mFullBackupQueue;
// Utility: build a new random integer token
int generateToken() {
@@ -1229,8 +1233,10 @@ public class BackupManagerService {
}
}
- // Resume the full-data backup queue
- mFullBackupQueue = readFullBackupSchedule();
+ synchronized (mQueueLock) {
+ // Resume the full-data backup queue
+ mFullBackupQueue = readFullBackupSchedule();
+ }
// Register for broadcasts about package install, etc., so we can
// update the provider list.
@@ -1248,74 +1254,98 @@ public class BackupManagerService {
}
private ArrayList<FullBackupEntry> readFullBackupSchedule() {
+ boolean changed = false;
ArrayList<FullBackupEntry> schedule = null;
- synchronized (mQueueLock) {
- if (mFullBackupScheduleFile.exists()) {
- FileInputStream fstream = null;
- BufferedInputStream bufStream = null;
- DataInputStream in = null;
- try {
- fstream = new FileInputStream(mFullBackupScheduleFile);
- bufStream = new BufferedInputStream(fstream);
- in = new DataInputStream(bufStream);
+ List<PackageInfo> apps =
+ PackageManagerBackupAgent.getStorableApplications(mPackageManager);
- int version = in.readInt();
- if (version != SCHEDULE_FILE_VERSION) {
- Slog.e(TAG, "Unknown backup schedule version " + version);
- return null;
- }
+ if (mFullBackupScheduleFile.exists()) {
+ FileInputStream fstream = null;
+ BufferedInputStream bufStream = null;
+ DataInputStream in = null;
+ try {
+ fstream = new FileInputStream(mFullBackupScheduleFile);
+ bufStream = new BufferedInputStream(fstream);
+ in = new DataInputStream(bufStream);
- int N = in.readInt();
- schedule = new ArrayList<FullBackupEntry>(N);
- for (int i = 0; i < N; i++) {
- String pkgName = in.readUTF();
- long lastBackup = in.readLong();
- try {
- PackageInfo pkg = mPackageManager.getPackageInfo(pkgName, 0);
- if (appGetsFullBackup(pkg)
- && appIsEligibleForBackup(pkg.applicationInfo)) {
- schedule.add(new FullBackupEntry(pkgName, lastBackup));
- } else {
- if (DEBUG) {
- Slog.i(TAG, "Package " + pkgName
- + " no longer eligible for full backup");
- }
- }
- } catch (NameNotFoundException e) {
+ int version = in.readInt();
+ if (version != SCHEDULE_FILE_VERSION) {
+ Slog.e(TAG, "Unknown backup schedule version " + version);
+ return null;
+ }
+
+ final int N = in.readInt();
+ schedule = new ArrayList<FullBackupEntry>(N);
+
+ // HashSet instead of ArraySet specifically because we want the eventual
+ // lookups against O(hundreds) of entries to be as fast as possible, and
+ // we discard the set immediately after the scan so the extra memory
+ // overhead is transient.
+ HashSet<String> foundApps = new HashSet<String>(N);
+
+ for (int i = 0; i < N; i++) {
+ String pkgName = in.readUTF();
+ long lastBackup = in.readLong();
+ foundApps.add(pkgName); // all apps that we've addressed already
+ try {
+ PackageInfo pkg = mPackageManager.getPackageInfo(pkgName, 0);
+ if (appGetsFullBackup(pkg) && appIsEligibleForBackup(pkg.applicationInfo)) {
+ schedule.add(new FullBackupEntry(pkgName, lastBackup));
+ } else {
if (DEBUG) {
Slog.i(TAG, "Package " + pkgName
- + " not installed; dropping from full backup");
+ + " no longer eligible for full backup");
}
}
+ } catch (NameNotFoundException e) {
+ if (DEBUG) {
+ Slog.i(TAG, "Package " + pkgName
+ + " not installed; dropping from full backup");
+ }
}
- Collections.sort(schedule);
- } catch (Exception e) {
- Slog.e(TAG, "Unable to read backup schedule", e);
- mFullBackupScheduleFile.delete();
- schedule = null;
- } finally {
- IoUtils.closeQuietly(in);
- IoUtils.closeQuietly(bufStream);
- IoUtils.closeQuietly(fstream);
}
- }
- if (schedule == null) {
- // no prior queue record, or unable to read it. Set up the queue
- // from scratch.
- List<PackageInfo> apps =
- PackageManagerBackupAgent.getStorableApplications(mPackageManager);
- final int N = apps.size();
- schedule = new ArrayList<FullBackupEntry>(N);
- for (int i = 0; i < N; i++) {
- PackageInfo info = apps.get(i);
- if (appGetsFullBackup(info) && appIsEligibleForBackup(info.applicationInfo)) {
- schedule.add(new FullBackupEntry(info.packageName, 0));
+ // New apps can arrive "out of band" via OTA and similar, so we also need to
+ // scan to make sure that we're tracking all full-backup candidates properly
+ for (PackageInfo app : apps) {
+ if (appGetsFullBackup(app) && appIsEligibleForBackup(app.applicationInfo)) {
+ if (!foundApps.contains(app.packageName)) {
+ if (DEBUG) {
+ Slog.i(TAG, "New full backup app " + app.packageName + " found");
+ }
+ schedule.add(new FullBackupEntry(app.packageName, 0));
+ changed = true;
+ }
}
}
- writeFullBackupScheduleAsync();
+
+ Collections.sort(schedule);
+ } catch (Exception e) {
+ Slog.e(TAG, "Unable to read backup schedule", e);
+ mFullBackupScheduleFile.delete();
+ schedule = null;
+ } finally {
+ IoUtils.closeQuietly(in);
+ IoUtils.closeQuietly(bufStream);
+ IoUtils.closeQuietly(fstream);
+ }
+ }
+
+ if (schedule == null) {
+ // no prior queue record, or unable to read it. Set up the queue
+ // from scratch.
+ changed = true;
+ schedule = new ArrayList<FullBackupEntry>(apps.size());
+ for (PackageInfo info : apps) {
+ if (appGetsFullBackup(info) && appIsEligibleForBackup(info.applicationInfo)) {
+ schedule.add(new FullBackupEntry(info.packageName, 0));
+ }
}
}
+
+ if (changed) {
+ writeFullBackupScheduleAsync();
+ }
return schedule;
}
@@ -4313,13 +4343,16 @@ public class BackupManagerService {
// This is also slow but easy for modest numbers of apps: work backwards
// from the end of the queue until we find an item whose last backup
- // time was before this one, then insert this new entry after it.
- int which;
- for (which = mFullBackupQueue.size() - 1; which >= 0; which--) {
- final FullBackupEntry entry = mFullBackupQueue.get(which);
- if (entry.lastBackup <= lastBackedUp) {
- mFullBackupQueue.add(which + 1, newEntry);
- break;
+ // time was before this one, then insert this new entry after it. If we're
+ // adding something new we don't bother scanning, and just prepend.
+ int which = -1;
+ if (lastBackedUp > 0) {
+ for (which = mFullBackupQueue.size() - 1; which >= 0; which--) {
+ final FullBackupEntry entry = mFullBackupQueue.get(which);
+ if (entry.lastBackup <= lastBackedUp) {
+ mFullBackupQueue.add(which + 1, newEntry);
+ break;
+ }
}
}
if (which < 0) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 6842304..5a9b5b2 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -8884,7 +8884,8 @@ public final class ActivityManagerService extends ActivityManagerNative
throw new SecurityException("updateLockTaskPackage called from non-system process");
}
synchronized (this) {
- if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" + packages);
+ if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
+ Arrays.toString(packages));
mLockTaskPackages.put(userId, packages);
mStackSupervisor.onLockTaskPackagesUpdatedLocked();
}
@@ -8927,7 +8928,7 @@ public final class ActivityManagerService extends ActivityManagerNative
mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
ActivityManager.LOCK_TASK_MODE_PINNED :
ActivityManager.LOCK_TASK_MODE_LOCKED,
- "startLockTask");
+ "startLockTask", true);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -8992,7 +8993,7 @@ public final class ActivityManagerService extends ActivityManagerNative
// Stop lock task
synchronized (this) {
mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
- "stopLockTask");
+ "stopLockTask", true);
}
} finally {
Binder.restoreCallingIdentity(ident);
@@ -19433,7 +19434,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
- "startUser");
+ "startUser", false);
final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
if (userInfo == null) {
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index f304828..5eee34f 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -1185,7 +1185,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
final TaskRecord task = r.task;
if (task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) {
- setLockTaskModeLocked(task, LOCK_TASK_MODE_LOCKED, "mLockTaskAuth==LAUNCHABLE");
+ setLockTaskModeLocked(task, LOCK_TASK_MODE_LOCKED, "mLockTaskAuth==LAUNCHABLE", false);
}
final ActivityStack stack = task.stack;
@@ -3675,7 +3675,11 @@ public final class ActivityStackSupervisor implements DisplayListener {
}
void removeLockedTaskLocked(final TaskRecord task) {
- if (mLockTaskModeTasks.remove(task) && mLockTaskModeTasks.isEmpty()) {
+ if (!mLockTaskModeTasks.remove(task)) {
+ return;
+ }
+ if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "removeLockedTaskLocked: removed " + task);
+ if (mLockTaskModeTasks.isEmpty()) {
// Last one.
if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "removeLockedTask: task=" + task +
" last task, reverting locktask mode. Callers=" + Debug.getCallers(3));
@@ -3696,7 +3700,8 @@ public final class ActivityStackSupervisor implements DisplayListener {
}
}
- void setLockTaskModeLocked(TaskRecord task, int lockTaskModeState, String reason) {
+ void setLockTaskModeLocked(TaskRecord task, int lockTaskModeState, String reason,
+ boolean andResume) {
if (task == null) {
// Take out of lock task mode if necessary
final TaskRecord lockedTask = getLockedTaskLocked();
@@ -3745,8 +3750,11 @@ public final class ActivityStackSupervisor implements DisplayListener {
if (task.mLockTaskUid == -1) {
task.mLockTaskUid = task.mCallingUid;
}
- findTaskToMoveToFrontLocked(task, 0, null, reason);
- resumeTopActivitiesLocked();
+
+ if (andResume) {
+ findTaskToMoveToFrontLocked(task, 0, null, reason);
+ resumeTopActivitiesLocked();
+ }
}
boolean isLockTaskModeViolation(TaskRecord task) {
@@ -3780,6 +3788,8 @@ public final class ActivityStackSupervisor implements DisplayListener {
lockedTask.setLockTaskAuth();
if (wasLaunchable && lockedTask.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE) {
// Lost whitelisting authorization. End it now.
+ if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "onLockTaskPackagesUpdated: removing " +
+ lockedTask + " mLockTaskAuth=" + lockedTask.lockTaskAuthToString());
removeLockedTaskLocked(lockedTask);
lockedTask.performClearTaskLocked();
didSomething = true;
@@ -3797,7 +3807,11 @@ public final class ActivityStackSupervisor implements DisplayListener {
if (mLockTaskModeTasks.isEmpty() && task != null
&& task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) {
// This task must have just been authorized.
- setLockTaskModeLocked(task, ActivityManager.LOCK_TASK_MODE_LOCKED, "package updated");
+ if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK,
+ "onLockTaskPackagesUpdated: starting new locktask task=" + task);
+ setLockTaskModeLocked(task, ActivityManager.LOCK_TASK_MODE_LOCKED, "package updated",
+ false);
+ didSomething = true;
}
if (didSomething) {
resumeTopActivitiesLocked();
diff --git a/services/core/java/com/android/server/am/RecentTasks.java b/services/core/java/com/android/server/am/RecentTasks.java
index 3a20ded..9f11def 100644
--- a/services/core/java/com/android/server/am/RecentTasks.java
+++ b/services/core/java/com/android/server/am/RecentTasks.java
@@ -435,9 +435,7 @@ class RecentTasks extends ArrayList<TaskRecord> {
*/
int trimForTaskLocked(TaskRecord task, boolean doTrim) {
int recentsCount = size();
- final Intent intent = task.intent;
- final boolean document = intent != null && intent.isDocument();
-
+ final boolean document = task.intent != null && task.intent.isDocument();
int maxRecents = task.maxRecents - 1;
for (int i = 0; i < recentsCount; i++) {
final TaskRecord tr = get(i);
@@ -448,12 +446,11 @@ class RecentTasks extends ArrayList<TaskRecord> {
if (i > MAX_RECENT_BITMAPS) {
tr.freeLastThumbnail();
}
- final Intent trIntent = tr.intent;
- if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
- (intent == null || !intent.filterEquals(trIntent))) {
+ if (task.realActivity == null || tr.realActivity == null ||
+ !task.realActivity.equals(tr.realActivity)) {
continue;
}
- final boolean trIsDocument = trIntent != null && trIntent.isDocument();
+ final boolean trIsDocument = tr.intent != null && tr.intent.isDocument();
if (document && trIsDocument) {
// These are the same document activity (not necessarily the same doc).
if (maxRecents > 0) {
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index 417c7c3..d56a024 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -739,38 +739,40 @@ final class TaskRecord {
performClearTaskAtIndexLocked(0);
}
+ String lockTaskAuthToString() {
+ switch (mLockTaskAuth) {
+ case LOCK_TASK_AUTH_DONT_LOCK: return "LOCK_TASK_AUTH_DONT_LOCK";
+ case LOCK_TASK_AUTH_PINNABLE: return "LOCK_TASK_AUTH_PINNABLE";
+ case LOCK_TASK_AUTH_LAUNCHABLE: return "LOCK_TASK_AUTH_LAUNCHABLE";
+ case LOCK_TASK_AUTH_WHITELISTED: return "LOCK_TASK_AUTH_WHITELISTED";
+ default: return "unknown=" + mLockTaskAuth;
+ }
+ }
+
void setLockTaskAuth() {
switch (mLockTaskMode) {
case LOCK_TASK_LAUNCH_MODE_DEFAULT:
- if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "setLockTaskAuth: task=" + this +
- " mLockTaskAuth=" + (isLockTaskWhitelistedLocked() ?
- "WHITELISTED" : "PINNABLE"));
mLockTaskAuth = isLockTaskWhitelistedLocked() ?
LOCK_TASK_AUTH_WHITELISTED : LOCK_TASK_AUTH_PINNABLE;
break;
case LOCK_TASK_LAUNCH_MODE_NEVER:
- if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "setLockTaskAuth: task=" + this +
- " mLockTaskAuth=" + (mPrivileged ? "DONT_LOCK" : "PINNABLE"));
mLockTaskAuth = mPrivileged ?
LOCK_TASK_AUTH_DONT_LOCK : LOCK_TASK_AUTH_PINNABLE;
break;
case LOCK_TASK_LAUNCH_MODE_ALWAYS:
- if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "setLockTaskAuth: task=" + this +
- " mLockTaskAuth=" + (mPrivileged ? "LAUNCHABLE" : "PINNABLE"));
mLockTaskAuth = mPrivileged ?
LOCK_TASK_AUTH_LAUNCHABLE: LOCK_TASK_AUTH_PINNABLE;
break;
case LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED:
- if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "setLockTaskAuth: task=" + this +
- " mLockTaskAuth=" + (isLockTaskWhitelistedLocked() ?
- "LAUNCHABLE" : "PINNABLE"));
mLockTaskAuth = isLockTaskWhitelistedLocked() ?
LOCK_TASK_AUTH_LAUNCHABLE : LOCK_TASK_AUTH_PINNABLE;
break;
}
+ if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "setLockTaskAuth: task=" + this +
+ " mLockTaskAuth=" + lockTaskAuthToString());
}
boolean isLockTaskWhitelistedLocked() {
@@ -1173,10 +1175,12 @@ final class TaskRecord {
pw.print(" taskType="); pw.print(taskType);
pw.print(" mTaskToReturnTo="); pw.println(mTaskToReturnTo);
}
- if (rootWasReset || mNeverRelinquishIdentity || mReuseTask) {
+ if (rootWasReset || mNeverRelinquishIdentity || mReuseTask
+ || mLockTaskAuth != LOCK_TASK_AUTH_PINNABLE) {
pw.print(prefix); pw.print("rootWasReset="); pw.print(rootWasReset);
pw.print(" mNeverRelinquishIdentity="); pw.print(mNeverRelinquishIdentity);
- pw.print(" mReuseTask="); pw.println(mReuseTask);
+ pw.print(" mReuseTask="); pw.print(mReuseTask);
+ pw.print(" mLockTaskAuth="); pw.println(lockTaskAuthToString());
}
if (mAffiliatedTaskId != taskId || mPrevAffiliateTaskId != INVALID_TASK_ID
|| mPrevAffiliate != null || mNextAffiliateTaskId != INVALID_TASK_ID
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 9f35843..352c499 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -4787,7 +4787,7 @@ public class AudioService extends IAudioService.Stub {
if (devicePort.type() == AudioManager.DEVICE_OUT_HDMI ||
devicePort.type() == AudioManager.DEVICE_OUT_HDMI_ARC) {
// format the list of supported encodings
- int[] formats = devicePort.formats();
+ int[] formats = AudioFormat.filterPublicFormats(devicePort.formats());
if (formats.length > 0) {
ArrayList<Integer> encodingList = new ArrayList(1);
for (int format : formats) {
diff --git a/services/core/java/com/android/server/camera/CameraService.java b/services/core/java/com/android/server/camera/CameraService.java
index 1d77bc2..777a9dd 100644
--- a/services/core/java/com/android/server/camera/CameraService.java
+++ b/services/core/java/com/android/server/camera/CameraService.java
@@ -19,6 +19,7 @@ import android.app.ActivityManager;
import android.content.Context;
import android.content.pm.UserInfo;
import android.hardware.ICameraService;
+import android.hardware.ICameraServiceProxy;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.UserManager;
@@ -42,14 +43,30 @@ public class CameraService extends SystemService {
*/
private static final String CAMERA_SERVICE_BINDER_NAME = "media.camera";
+ public static final String CAMERA_SERVICE_PROXY_BINDER_NAME = "media.camera.proxy";
+
// Event arguments to use with the camera service notifySystemEvent call:
public static final int NO_EVENT = 0; // NOOP
public static final int USER_SWITCHED = 1; // User changed, argument is the new user handle
private final Context mContext;
private UserManager mUserManager;
+
+ private final Object mLock = new Object();
private Set<Integer> mEnabledCameraUsers;
+ private final ICameraServiceProxy.Stub mCameraServiceProxy = new ICameraServiceProxy.Stub() {
+ @Override
+ public void pingForUserUpdate() {
+ // Binder call
+ synchronized(mLock) {
+ if (mEnabledCameraUsers != null) {
+ notifyMediaserver(USER_SWITCHED, mEnabledCameraUsers);
+ }
+ }
+ }
+ };
+
public CameraService(Context context) {
super(context);
mContext = context;
@@ -62,18 +79,27 @@ public class CameraService extends SystemService {
// Should never see this unless someone messes up the SystemServer service boot order.
throw new IllegalStateException("UserManagerService must start before CameraService!");
}
+ publishBinderService(CAMERA_SERVICE_PROXY_BINDER_NAME, mCameraServiceProxy);
}
@Override
public void onStartUser(int userHandle) {
- if (mEnabledCameraUsers == null) {
- // Initialize mediaserver, or update mediaserver if we are recovering from a crash.
- onSwitchUser(userHandle);
+ synchronized(mLock) {
+ if (mEnabledCameraUsers == null) {
+ // Initialize mediaserver, or update mediaserver if we are recovering from a crash.
+ switchUserLocked(userHandle);
+ }
}
}
@Override
public void onSwitchUser(int userHandle) {
+ synchronized(mLock) {
+ switchUserLocked(userHandle);
+ }
+ }
+
+ private void switchUserLocked(int userHandle) {
Set<Integer> currentUserHandles = getEnabledUserHandles(userHandle);
if (mEnabledCameraUsers == null || !mEnabledCameraUsers.equals(currentUserHandles)) {
// Some user handles have been added or removed, update mediaserver.
@@ -82,7 +108,6 @@ public class CameraService extends SystemService {
}
}
-
private Set<Integer> getEnabledUserHandles(int currentUserHandle) {
List<UserInfo> userProfiles = mUserManager.getEnabledProfiles(currentUserHandle);
Set<Integer> handles = new HashSet<>(userProfiles.size());
diff --git a/services/core/java/com/android/server/fingerprint/FingerprintService.java b/services/core/java/com/android/server/fingerprint/FingerprintService.java
index d725d94..1057ce3 100644
--- a/services/core/java/com/android/server/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/fingerprint/FingerprintService.java
@@ -30,6 +30,7 @@ import android.os.IRemoteCallback;
import android.os.Looper;
import android.os.MessageQueue;
import android.os.RemoteException;
+import android.os.ServiceManager;
import android.util.Slog;
import com.android.server.SystemService;
@@ -37,6 +38,8 @@ import com.android.server.SystemService;
import android.hardware.fingerprint.Fingerprint;
import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.IFingerprintService;
+import android.hardware.fingerprint.IFingerprintDaemon;
+import android.hardware.fingerprint.IFingerprintDaemonCallback;
import android.hardware.fingerprint.IFingerprintServiceReceiver;
import static android.Manifest.permission.MANAGE_FINGERPRINT;
@@ -55,20 +58,19 @@ import java.util.List;
*
* @hide
*/
-public class FingerprintService extends SystemService {
+public class FingerprintService extends SystemService implements IBinder.DeathRecipient {
private static final String TAG = "FingerprintService";
private static final boolean DEBUG = true;
+ private static final String FP_DATA_DIR = "fpdata";
+ private static final String FINGERPRINTD = "android.hardware.fingerprint.IFingerprintDaemon";
+ private static final int MSG_USER_SWITCHING = 10;
+ private static final int ENROLLMENT_TIMEOUT_MS = 60 * 1000; // 1 minute
+
private ClientMonitor mAuthClient = null;
private ClientMonitor mEnrollClient = null;
private ClientMonitor mRemoveClient = null;
-
private final AppOpsManager mAppOps;
- private static final int MSG_NOTIFY = 10;
- private static final int MSG_USER_SWITCHING = 11;
-
- private static final int ENROLLMENT_TIMEOUT_MS = 60 * 1000; // 1 minute
-
// Message types. Used internally to dispatch messages to the correct callback.
// Must agree with the list in fingerprint.h
private static final int FINGERPRINT_ERROR = -1;
@@ -83,11 +85,6 @@ public class FingerprintService extends SystemService {
Handler mHandler = new Handler() {
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
- case MSG_NOTIFY:
- FpHalMsg m = (FpHalMsg) msg.obj;
- handleNotify(m.type, m.arg1, m.arg2, m.arg3);
- break;
-
case MSG_USER_SWITCHING:
handleUserSwitching(msg.arg1);
break;
@@ -97,10 +94,13 @@ public class FingerprintService extends SystemService {
}
}
};
+
+ private final FingerprintUtils mFingerprintUtils = FingerprintUtils.getInstance();
private Context mContext;
- private int mHalDeviceId;
+ private long mHalDeviceId;
private int mFailedAttempts;
- private final FingerprintUtils mFingerprintUtils = FingerprintUtils.getInstance();
+ private IFingerprintDaemon mDaemon;
+
private final Runnable mLockoutReset = new Runnable() {
@Override
public void run() {
@@ -112,127 +112,115 @@ public class FingerprintService extends SystemService {
super(context);
mContext = context;
mAppOps = context.getSystemService(AppOpsManager.class);
- nativeInit(Looper.getMainLooper().getQueue(), this);
- }
-
- // TODO: Move these into separate process
- // JNI methods to communicate from FingerprintService to HAL
- static native int nativeEnroll(byte [] token, int groupId, int timeout);
- static native long nativePreEnroll();
- static native int nativeStopEnrollment();
- static native int nativeAuthenticate(long sessionId, int groupId);
- static native int nativeStopAuthentication();
- static native int nativeRemove(int fingerId, int groupId);
- static native int nativeOpenHal();
- static native int nativeCloseHal();
- static native void nativeInit(MessageQueue queue, FingerprintService service);
- static native long nativeGetAuthenticatorId();
- static native int nativeSetActiveGroup(int gid, byte[] storePath);
-
- static final class FpHalMsg {
- int type; // Type of the message. One of the constants in fingerprint.h
- int arg1; // optional arguments
- int arg2;
- int arg3;
-
- FpHalMsg(int type, int arg1, int arg2, int arg3) {
- this.type = type;
- this.arg1 = arg1;
- this.arg2 = arg2;
- this.arg3 = arg3;
- }
- }
-
- /**
- * Called from JNI to communicate messages from fingerprint HAL.
- */
- void notify(int type, int arg1, int arg2, int arg3) {
- mHandler.obtainMessage(MSG_NOTIFY, new FpHalMsg(type, arg1, arg2, arg3)).sendToTarget();
- }
-
- void handleNotify(int type, int arg1, int arg2, int arg3) {
- Slog.v(TAG, "handleNotify(type=" + type + ", arg1=" + arg1 + ", arg2=" + arg2 + ")"
- + ", mAuthClients = " + mAuthClient + ", mEnrollClient = " + mEnrollClient);
+ }
+
+ @Override
+ public void binderDied() {
+ Slog.v(TAG, "fingerprintd died");
+ mDaemon = null;
+ }
+
+ public IFingerprintDaemon getFingerprintDaemon() {
+ if (mDaemon == null) {
+ mDaemon = IFingerprintDaemon.Stub.asInterface(ServiceManager.getService(FINGERPRINTD));
+ if (mDaemon == null) {
+ Slog.w(TAG, "fingerprind service not available");
+ } else {
+ try {
+ mDaemon.asBinder().linkToDeath(this, 0);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "caught remote exception in linkToDeath: ", e);
+ mDaemon = null; // try again!
+ }
+ }
+ }
+ return mDaemon;
+ }
+
+ protected void dispatchEnumerate(long deviceId, int[] fingerIds, int[] groupIds) {
+ if (fingerIds.length != groupIds.length) {
+ Slog.w(TAG, "fingerIds and groupIds differ in length: f[]="
+ + fingerIds + ", g[]=" + groupIds);
+ return;
+ }
+ if (DEBUG) Slog.w(TAG, "Enumerate: f[]=" + fingerIds + ", g[]=" + groupIds);
+ // TODO: update fingerprint/name pairs
+ }
+
+ protected void dispatchRemoved(long deviceId, int fingerId, int groupId) {
+ final ClientMonitor client = mRemoveClient;
+ if (fingerId != 0) {
+ ContentResolver res = mContext.getContentResolver();
+ removeTemplateForUser(mRemoveClient, fingerId);
+ }
+ if (client != null && client.sendRemoved(fingerId, groupId)) {
+ removeClient(mRemoveClient);
+ }
+ }
+
+ protected void dispatchError(long deviceId, int error) {
if (mEnrollClient != null) {
final IBinder token = mEnrollClient.token;
- if (dispatchNotify(mEnrollClient, type, arg1, arg2, arg3)) {
+ if (mEnrollClient.sendError(error)) {
stopEnrollment(token, false);
- removeClient(mEnrollClient);
}
+ } else if (mAuthClient != null) {
+ final IBinder token = mAuthClient.token;
+ if (mAuthClient.sendError(error)) {
+ stopAuthentication(token, false);
+ }
+ } else if (mRemoveClient != null) {
+ if (mRemoveClient.sendError(error)) removeClient(mRemoveClient);
}
+ }
+
+ protected void dispatchAuthenticated(long deviceId, int fingerId, int groupId) {
if (mAuthClient != null) {
final IBinder token = mAuthClient.token;
- if (dispatchNotify(mAuthClient, type, arg1, arg2, arg3)) {
+ if (mAuthClient.sendAuthenticated(fingerId, groupId)) {
stopAuthentication(token, false);
removeClient(mAuthClient);
}
}
- if (mRemoveClient != null) {
- if (dispatchNotify(mRemoveClient, type, arg1, arg2, arg3)) {
- removeClient(mRemoveClient);
+ }
+
+ protected void dispatchAcquired(long deviceId, int acquiredInfo) {
+ if (mEnrollClient != null) {
+ if (mEnrollClient.sendAcquired(acquiredInfo)) {
+ removeClient(mEnrollClient);
+ }
+ } else if (mAuthClient != null) {
+ if (mAuthClient.sendAcquired(acquiredInfo)) {
+ removeClient(mAuthClient);
}
}
+
}
void handleUserSwitching(int userId) {
updateActiveGroup(userId);
}
- /*
- * Dispatch notify events to clients.
- *
- * @return true if the operation is done, i.e. authentication completed
- */
- boolean dispatchNotify(ClientMonitor clientMonitor, int type, int arg1, int arg2, int arg3) {
- boolean operationCompleted = false;
- int fpId;
- int groupId;
- int remaining;
- int acquireInfo;
- switch (type) {
- case FINGERPRINT_ERROR:
- fpId = arg1;
- operationCompleted = clientMonitor.sendError(fpId);
- break;
- case FINGERPRINT_ACQUIRED:
- acquireInfo = arg1;
- operationCompleted = clientMonitor.sendAcquired(acquireInfo);
- break;
- case FINGERPRINT_AUTHENTICATED:
- fpId = arg1;
- groupId = arg2;
- operationCompleted = clientMonitor.sendAuthenticated(fpId, groupId);
- break;
- case FINGERPRINT_TEMPLATE_ENROLLING:
- fpId = arg1;
- groupId = arg2;
- remaining = arg3;
- operationCompleted = clientMonitor.sendEnrollResult(fpId, groupId, remaining);
+ protected void dispatchEnrollResult(long deviceId, int fingerId, int groupId, int remaining) {
+ if (mEnrollClient != null) {
+ if (mEnrollClient.sendEnrollResult(fingerId, groupId, remaining)) {
if (remaining == 0) {
- addTemplateForUser(clientMonitor, fpId);
- operationCompleted = true; // enroll completed
- }
- break;
- case FINGERPRINT_TEMPLATE_REMOVED:
- fpId = arg1;
- groupId = arg2;
- operationCompleted = clientMonitor.sendRemoved(fpId, groupId);
- if (fpId != 0) {
- removeTemplateForUser(clientMonitor, fpId);
+ ContentResolver res = mContext.getContentResolver();
+ addTemplateForUser(mEnrollClient, fingerId);
+ removeClient(mEnrollClient);
}
- break;
+ }
}
- return operationCompleted;
}
- private void removeClient(ClientMonitor clientMonitor) {
- if (clientMonitor == null) return;
- clientMonitor.destroy();
- if (clientMonitor == mAuthClient) {
+ private void removeClient(ClientMonitor client) {
+ if (client == null) return;
+ client.destroy();
+ if (client == mAuthClient) {
mAuthClient = null;
- } else if (clientMonitor == mEnrollClient) {
+ } else if (client == mEnrollClient) {
mEnrollClient = null;
- } else if (clientMonitor == mRemoveClient) {
+ } else if (client == mRemoveClient) {
mRemoveClient = null;
}
}
@@ -273,17 +261,36 @@ public class FingerprintService extends SystemService {
void startEnrollment(IBinder token, byte[] cryptoToken, int groupId,
IFingerprintServiceReceiver receiver, int flags) {
+ IFingerprintDaemon daemon = getFingerprintDaemon();
+ if (daemon == null) {
+ Slog.w(TAG, "enroll: no fingeprintd!");
+ return;
+ }
stopPendingOperations();
mEnrollClient = new ClientMonitor(token, receiver, groupId);
final int timeout = (int) (ENROLLMENT_TIMEOUT_MS / MS_PER_SEC);
- final int result = nativeEnroll(cryptoToken, groupId, timeout);
- if (result != 0) {
- Slog.w(TAG, "startEnroll failed, result=" + result);
+ try {
+ final int result = daemon.enroll(cryptoToken, groupId, timeout);
+ if (result != 0) {
+ Slog.w(TAG, "startEnroll failed, result=" + result);
+ }
+ } catch (RemoteException e) {
+ Slog.e(TAG, "startEnroll failed", e);
}
}
public long startPreEnroll(IBinder token) {
- return nativePreEnroll();
+ IFingerprintDaemon daemon = getFingerprintDaemon();
+ if (daemon == null) {
+ Slog.w(TAG, "startPreEnroll: no fingeprintd!");
+ return 0;
+ }
+ try {
+ return daemon.preEnroll();
+ } catch (RemoteException e) {
+ Slog.e(TAG, "startPreEnroll failed", e);
+ }
+ return 0;
}
private void stopPendingOperations() {
@@ -297,20 +304,34 @@ public class FingerprintService extends SystemService {
}
void stopEnrollment(IBinder token, boolean notify) {
+ IFingerprintDaemon daemon = getFingerprintDaemon();
+ if (daemon == null) {
+ Slog.w(TAG, "stopEnrollment: no fingeprintd!");
+ return;
+ }
final ClientMonitor client = mEnrollClient;
if (client == null || client.token != token) return;
- int result = nativeStopEnrollment();
+ try {
+ int result = daemon.cancelEnrollment();
+ if (result != 0) {
+ Slog.w(TAG, "startEnrollCancel failed, result = " + result);
+ }
+ } catch (RemoteException e) {
+ Slog.e(TAG, "stopEnrollment failed", e);
+ }
if (notify) {
client.sendError(FingerprintManager.FINGERPRINT_ERROR_CANCELED);
}
removeClient(mEnrollClient);
- if (result != 0) {
- Slog.w(TAG, "startEnrollCancel failed, result=" + result);
- }
}
void startAuthentication(IBinder token, long opId, int groupId,
IFingerprintServiceReceiver receiver, int flags) {
+ IFingerprintDaemon daemon = getFingerprintDaemon();
+ if (daemon == null) {
+ Slog.w(TAG, "startAuthentication: no fingeprintd!");
+ return;
+ }
stopPendingOperations();
mAuthClient = new ClientMonitor(token, receiver, groupId);
if (inLockoutMode()) {
@@ -322,32 +343,54 @@ public class FingerprintService extends SystemService {
return;
}
final int timeout = (int) (ENROLLMENT_TIMEOUT_MS / MS_PER_SEC);
- final int result = nativeAuthenticate(opId, groupId);
- if (result != 0) {
- Slog.w(TAG, "startAuthentication failed, result=" + result);
+ try {
+ final int result = daemon.authenticate(opId, groupId);
+ if (result != 0) {
+ Slog.w(TAG, "startAuthentication failed, result=" + result);
+ }
+ } catch (RemoteException e) {
+ Slog.e(TAG, "startAuthentication failed", e);
}
}
void stopAuthentication(IBinder token, boolean notify) {
+ IFingerprintDaemon daemon = getFingerprintDaemon();
+ if (daemon == null) {
+ Slog.w(TAG, "stopAuthentication: no fingeprintd!");
+ return;
+ }
final ClientMonitor client = mAuthClient;
if (client == null || client.token != token) return;
- int result = nativeStopAuthentication();
+ try {
+ int result = daemon.cancelAuthentication();
+ if (result != 0) {
+ Slog.w(TAG, "stopAuthentication failed, result=" + result);
+ }
+ } catch (RemoteException e) {
+ Slog.e(TAG, "stopAuthentication failed", e);
+ }
if (notify) {
client.sendError(FingerprintManager.FINGERPRINT_ERROR_CANCELED);
}
removeClient(mAuthClient);
- if (result != 0) {
- Slog.w(TAG, "stopAuthentication failed, result=" + result);
- }
}
void startRemove(IBinder token, int fingerId, int userId,
IFingerprintServiceReceiver receiver) {
+ IFingerprintDaemon daemon = getFingerprintDaemon();
+ if (daemon == null) {
+ Slog.w(TAG, "startRemove: no fingeprintd!");
+ return;
+ }
mRemoveClient = new ClientMonitor(token, receiver, userId);
// The fingerprint template ids will be removed when we get confirmation from the HAL
- final int result = nativeRemove(fingerId, userId);
- if (result != 0) {
- Slog.w(TAG, "startRemove with id = " + fingerId + " failed with result=" + result);
+ try {
+ final int result = daemon.remove(fingerId, userId);
+ if (result != 0) {
+ Slog.w(TAG, "startRemove with id = " + fingerId + " failed, result=" + result);
+ }
+ } catch (RemoteException e) {
+ Slog.e(TAG, "startRemove failed", e);
}
}
@@ -364,7 +407,7 @@ public class FingerprintService extends SystemService {
"Must have " + permission + " permission.");
}
- private boolean canUserFingerPrint(String opPackageName) {
+ private boolean canUseFingerprint(String opPackageName) {
checkPermission(USE_FINGERPRINT);
return mAppOps.noteOp(AppOpsManager.OP_USE_FINGERPRINT, Binder.getCallingUid(),
@@ -496,15 +539,48 @@ public class FingerprintService extends SystemService {
}
}
- private final class FingerprintServiceWrapper extends IFingerprintService.Stub {
+ private IFingerprintDaemonCallback mDaemonCallback = new IFingerprintDaemonCallback.Stub() {
+
+ @Override
+ public void onEnrollResult(long deviceId, int fingerId, int groupId, int remaining) {
+ dispatchEnrollResult(deviceId, fingerId, groupId, remaining);
+ }
+
+ @Override
+ public void onAcquired(long deviceId, int acquiredInfo) {
+ dispatchAcquired(deviceId, acquiredInfo);
+ }
+
+ @Override
+ public void onAuthenticated(long deviceId, int fingerId, int groupId) {
+ dispatchAuthenticated(deviceId, fingerId, groupId);
+ }
+
+ @Override
+ public void onError(long deviceId, int error) {
+ dispatchError(deviceId, error);
+ }
+
+ @Override
+ public void onRemoved(long deviceId, int fingerId, int groupId) {
+ dispatchRemoved(deviceId, fingerId, groupId);
+ }
+
@Override
+ public void onEnumerate(long deviceId, int[] fingerIds, int[] groupIds) {
+ dispatchEnumerate(deviceId, fingerIds, groupIds);
+ }
+
+ };
+
+ private final class FingerprintServiceWrapper extends IFingerprintService.Stub {
+ @Override // Binder call
public long preEnroll(IBinder token) {
checkPermission(MANAGE_FINGERPRINT);
return startPreEnroll(token);
}
- @Override
- // Binder call
+ @Override // Binder call
public void enroll(final IBinder token, final byte[] cryptoToken, final int groupId,
final IFingerprintServiceReceiver receiver, final int flags) {
checkPermission(MANAGE_FINGERPRINT);
@@ -517,8 +593,7 @@ public class FingerprintService extends SystemService {
});
}
- @Override
- // Binder call
+ @Override // Binder call
public void cancelEnrollment(final IBinder token) {
checkPermission(MANAGE_FINGERPRINT);
mHandler.post(new Runnable() {
@@ -529,12 +604,11 @@ public class FingerprintService extends SystemService {
});
}
- @Override
- // Binder call
+ @Override // Binder call
public void authenticate(final IBinder token, final long opId, final int groupId,
final IFingerprintServiceReceiver receiver, final int flags, String opPackageName) {
checkPermission(USE_FINGERPRINT);
- if (!canUserFingerPrint(opPackageName)) {
+ if (!canUseFingerprint(opPackageName)) {
return;
}
mHandler.post(new Runnable() {
@@ -545,11 +619,9 @@ public class FingerprintService extends SystemService {
});
}
- @Override
-
- // Binder call
+ @Override // Binder call
public void cancelAuthentication(final IBinder token, String opPackageName) {
- if (!canUserFingerPrint(opPackageName)) {
+ if (!canUseFingerprint(opPackageName)) {
return;
}
mHandler.post(new Runnable() {
@@ -560,8 +632,7 @@ public class FingerprintService extends SystemService {
});
}
- @Override
- // Binder call
+ @Override // Binder call
public void remove(final IBinder token, final int fingerId, final int groupId,
final IFingerprintServiceReceiver receiver) {
checkPermission(MANAGE_FINGERPRINT); // TODO: Maybe have another permission
@@ -574,17 +645,15 @@ public class FingerprintService extends SystemService {
}
- @Override
- // Binder call
+ @Override // Binder call
public boolean isHardwareDetected(long deviceId, String opPackageName) {
- if (!canUserFingerPrint(opPackageName)) {
+ if (!canUseFingerprint(opPackageName)) {
return false;
}
- return mHalDeviceId != 0; // TODO
+ return mHalDeviceId != 0;
}
- @Override
- // Binder call
+ @Override // Binder call
public void rename(final int fingerId, final int groupId, final String name) {
checkPermission(MANAGE_FINGERPRINT);
mHandler.post(new Runnable() {
@@ -595,69 +664,102 @@ public class FingerprintService extends SystemService {
});
}
- @Override
- // Binder call
+ @Override // Binder call
public List<Fingerprint> getEnrolledFingerprints(int groupId, String opPackageName) {
- if (!canUserFingerPrint(opPackageName)) {
+ if (!canUseFingerprint(opPackageName)) {
return Collections.emptyList();
}
return FingerprintService.this.getEnrolledFingerprints(groupId);
}
- @Override
- // Binder call
+ @Override // Binder call
public boolean hasEnrolledFingerprints(int groupId, String opPackageName) {
- if (!canUserFingerPrint(opPackageName)) {
+ if (!canUseFingerprint(opPackageName)) {
return false;
}
return FingerprintService.this.hasEnrolledFingerprints(groupId);
}
- @Override
+ @Override // Binder call
public long getAuthenticatorId(String opPackageName) {
- if (!canUserFingerPrint(opPackageName)) {
+ if (!canUseFingerprint(opPackageName)) {
return 0;
}
- return nativeGetAuthenticatorId();
+ return FingerprintService.this.getAuthenticatorId();
}
}
@Override
public void onStart() {
publishBinderService(Context.FINGERPRINT_SERVICE, new FingerprintServiceWrapper());
- mHalDeviceId = nativeOpenHal();
- updateActiveGroup(ActivityManager.getCurrentUser());
+ IFingerprintDaemon daemon = getFingerprintDaemon();
+ if (daemon != null) {
+ try {
+ daemon.init(mDaemonCallback);
+ mHalDeviceId = daemon.openHal();
+ updateActiveGroup(ActivityManager.getCurrentUser());
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Failed to open fingeprintd HAL", e);
+ }
+ }
if (DEBUG) Slog.v(TAG, "Fingerprint HAL id: " + mHalDeviceId);
listenForUserSwitches();
}
private void updateActiveGroup(int userId) {
- if (mHalDeviceId != 0) {
- File path = Environment.getUserSystemDirectory(userId);
- nativeSetActiveGroup(userId, path.getAbsolutePath().getBytes());
+ IFingerprintDaemon daemon = getFingerprintDaemon();
+ if (daemon != null) {
+ try {
+ // TODO: if this is a managed profile, use the profile parent's directory for
+ // storage.
+ final File systemDir = Environment.getUserSystemDirectory(userId);
+ final File fpDir = new File(systemDir, FP_DATA_DIR);
+ if (!fpDir.exists()) {
+ if (!fpDir.mkdir()) {
+ Slog.v(TAG, "Cannot make directory: " + fpDir.getAbsolutePath());
+ return;
+ }
+ }
+ daemon.setActiveGroup(userId, fpDir.getAbsolutePath().getBytes());
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Failed to setActiveGroup():", e);
+ }
}
}
private void listenForUserSwitches() {
try {
ActivityManagerNative.getDefault().registerUserSwitchObserver(
- new IUserSwitchObserver.Stub() {
- @Override
- public void onUserSwitching(int newUserId, IRemoteCallback reply) {
- mHandler.obtainMessage(MSG_USER_SWITCHING, newUserId, 0 /* unused */)
- .sendToTarget();
- }
- @Override
- public void onUserSwitchComplete(int newUserId) throws RemoteException {
- // Ignore.
- }
- @Override
- public void onForegroundProfileSwitch(int newProfileId) {
- // Ignore.
- }
- });
+ new IUserSwitchObserver.Stub() {
+ @Override
+ public void onUserSwitching(int newUserId, IRemoteCallback reply) {
+ mHandler.obtainMessage(MSG_USER_SWITCHING, newUserId, 0 /* unused */)
+ .sendToTarget();
+ }
+ @Override
+ public void onUserSwitchComplete(int newUserId) throws RemoteException {
+ // Ignore.
+ }
+ @Override
+ public void onForegroundProfileSwitch(int newProfileId) {
+ // Ignore.
+ }
+ });
} catch (RemoteException e) {
Slog.w(TAG, "Failed to listen for user switching event" ,e);
}
}
+
+ public long getAuthenticatorId() {
+ IFingerprintDaemon daemon = getFingerprintDaemon();
+ if (daemon != null) {
+ try {
+ return daemon.getAuthenticatorId();
+ } catch (RemoteException e) {
+ Slog.e(TAG, "getAuthenticatorId failed", e);
+ }
+ }
+ return 0;
+ }
+
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 74e8e4d..6a47238 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -6356,12 +6356,14 @@ public class PackageManagerService extends IPackageManager.Stub {
// to scan the package again.
deriveNonSystemPackageAbi(pkg, scanFile, cpuAbiOverride, false /* extract libs */);
if (!TextUtils.equals(oldPrimaryCpuAbi, pkg.applicationInfo.primaryCpuAbi)) {
- throw new IllegalStateException("unexpected abi change for " + pkg.packageName + " ("
+ throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
+ "unexpected abi change for " + pkg.packageName + " ("
+ oldPrimaryCpuAbi + "-> " + pkg.applicationInfo.primaryCpuAbi);
}
if (!TextUtils.equals(oldSecondaryCpuAbi, pkg.applicationInfo.secondaryCpuAbi)) {
- throw new IllegalStateException("unexpected abi change for " + pkg.packageName + " ("
+ throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
+ "unexpected abi change for " + pkg.packageName + " ("
+ oldSecondaryCpuAbi + "-> " + pkg.applicationInfo.secondaryCpuAbi);
}
}
@@ -11661,7 +11663,7 @@ public class PackageManagerService extends IPackageManager.Stub {
true /* extract libs */);
} catch (PackageManagerException pme) {
Slog.e(TAG, "Error deriving application ABI", pme);
- res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error ");
+ res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI");
return;
}
diff --git a/services/core/java/com/android/server/pm/PermissionsState.java b/services/core/java/com/android/server/pm/PermissionsState.java
index 8942325..ad662be 100644
--- a/services/core/java/com/android/server/pm/PermissionsState.java
+++ b/services/core/java/com/android/server/pm/PermissionsState.java
@@ -381,10 +381,10 @@ public final class PermissionsState {
*
* @return The gids for all device users.
*/
- public int[] computeGids() {
+ public int[] computeGids(int[] userIds) {
int[] gids = mGlobalGids;
- for (int userId : UserManagerService.getInstance().getUserIds()) {
+ for (int userId : userIds) {
final int[] userGids = computeGids(userId);
gids = appendInts(gids, userGids);
}
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 76ef19f..d2a135c 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -2022,83 +2022,8 @@ final class Settings {
|FileUtils.S_IRGRP|FileUtils.S_IWGRP,
-1, -1);
- // Write package list file now, use a JournaledFile.
- File tempFile = new File(mPackageListFilename.getAbsolutePath() + ".tmp");
- JournaledFile journal = new JournaledFile(mPackageListFilename, tempFile);
-
- final File writeTarget = journal.chooseForWrite();
- fstr = new FileOutputStream(writeTarget);
- str = new BufferedOutputStream(fstr);
- try {
- FileUtils.setPermissions(fstr.getFD(), 0640, SYSTEM_UID, PACKAGE_INFO_GID);
-
- StringBuilder sb = new StringBuilder();
- for (final PackageSetting pkg : mPackages.values()) {
- if (pkg.pkg == null || pkg.pkg.applicationInfo == null) {
- Slog.w(TAG, "Skipping " + pkg + " due to missing metadata");
- continue;
- }
-
- final ApplicationInfo ai = pkg.pkg.applicationInfo;
- final String dataPath = ai.dataDir;
- final boolean isDebug = (ai.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
- final int[] gids = pkg.getPermissionsState().computeGids();
-
- // Avoid any application that has a space in its path.
- if (dataPath.indexOf(" ") >= 0)
- continue;
-
- // we store on each line the following information for now:
- //
- // pkgName - package name
- // userId - application-specific user id
- // debugFlag - 0 or 1 if the package is debuggable.
- // dataPath - path to package's data path
- // seinfo - seinfo label for the app (assigned at install time)
- // gids - supplementary gids this app launches with
- //
- // NOTE: We prefer not to expose all ApplicationInfo flags for now.
- //
- // DO NOT MODIFY THIS FORMAT UNLESS YOU CAN ALSO MODIFY ITS USERS
- // FROM NATIVE CODE. AT THE MOMENT, LOOK AT THE FOLLOWING SOURCES:
- // system/core/logd/LogStatistics.cpp
- // system/core/run-as/run-as.c
- // system/core/sdcard/sdcard.c
- // external/libselinux/src/android.c:package_info_init()
- //
- sb.setLength(0);
- sb.append(ai.packageName);
- sb.append(" ");
- sb.append((int)ai.uid);
- sb.append(isDebug ? " 1 " : " 0 ");
- sb.append(dataPath);
- sb.append(" ");
- sb.append(ai.seinfo);
- sb.append(" ");
- if (gids != null && gids.length > 0) {
- sb.append(gids[0]);
- for (int i = 1; i < gids.length; i++) {
- sb.append(",");
- sb.append(gids[i]);
- }
- } else {
- sb.append("none");
- }
- sb.append("\n");
- str.write(sb.toString().getBytes());
- }
- str.flush();
- FileUtils.sync(fstr);
- str.close();
- journal.commit();
- } catch (Exception e) {
- Slog.wtf(TAG, "Failed to write packages.list", e);
- IoUtils.closeQuietly(str);
- journal.rollback();
- }
-
+ writePackageListLPr();
writeAllUsersPackageRestrictionsLPr();
-
writeAllRuntimePermissionsLPr();
return;
@@ -2119,6 +2044,99 @@ final class Settings {
//Debug.stopMethodTracing();
}
+ void writePackageListLPr() {
+ writePackageListLPr(-1);
+ }
+
+ void writePackageListLPr(int creatingUserId) {
+ // Only derive GIDs for active users (not dying)
+ final List<UserInfo> users = UserManagerService.getInstance().getUsers(true);
+ int[] userIds = new int[users.size()];
+ for (int i = 0; i < userIds.length; i++) {
+ userIds[i] = users.get(i).id;
+ }
+ if (creatingUserId != -1) {
+ userIds = ArrayUtils.appendInt(userIds, creatingUserId);
+ }
+
+ // Write package list file now, use a JournaledFile.
+ File tempFile = new File(mPackageListFilename.getAbsolutePath() + ".tmp");
+ JournaledFile journal = new JournaledFile(mPackageListFilename, tempFile);
+
+ final File writeTarget = journal.chooseForWrite();
+ FileOutputStream fstr = null;
+ BufferedOutputStream str = null;
+ try {
+ fstr = new FileOutputStream(writeTarget);
+ str = new BufferedOutputStream(fstr);
+ FileUtils.setPermissions(fstr.getFD(), 0640, SYSTEM_UID, PACKAGE_INFO_GID);
+
+ StringBuilder sb = new StringBuilder();
+ for (final PackageSetting pkg : mPackages.values()) {
+ if (pkg.pkg == null || pkg.pkg.applicationInfo == null) {
+ Slog.w(TAG, "Skipping " + pkg + " due to missing metadata");
+ continue;
+ }
+
+ final ApplicationInfo ai = pkg.pkg.applicationInfo;
+ final String dataPath = ai.dataDir;
+ final boolean isDebug = (ai.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
+ final int[] gids = pkg.getPermissionsState().computeGids(userIds);
+
+ // Avoid any application that has a space in its path.
+ if (dataPath.indexOf(" ") >= 0)
+ continue;
+
+ // we store on each line the following information for now:
+ //
+ // pkgName - package name
+ // userId - application-specific user id
+ // debugFlag - 0 or 1 if the package is debuggable.
+ // dataPath - path to package's data path
+ // seinfo - seinfo label for the app (assigned at install time)
+ // gids - supplementary gids this app launches with
+ //
+ // NOTE: We prefer not to expose all ApplicationInfo flags for now.
+ //
+ // DO NOT MODIFY THIS FORMAT UNLESS YOU CAN ALSO MODIFY ITS USERS
+ // FROM NATIVE CODE. AT THE MOMENT, LOOK AT THE FOLLOWING SOURCES:
+ // system/core/logd/LogStatistics.cpp
+ // system/core/run-as/run-as.c
+ // system/core/sdcard/sdcard.c
+ // external/libselinux/src/android.c:package_info_init()
+ //
+ sb.setLength(0);
+ sb.append(ai.packageName);
+ sb.append(" ");
+ sb.append((int)ai.uid);
+ sb.append(isDebug ? " 1 " : " 0 ");
+ sb.append(dataPath);
+ sb.append(" ");
+ sb.append(ai.seinfo);
+ sb.append(" ");
+ if (gids != null && gids.length > 0) {
+ sb.append(gids[0]);
+ for (int i = 1; i < gids.length; i++) {
+ sb.append(",");
+ sb.append(gids[i]);
+ }
+ } else {
+ sb.append("none");
+ }
+ sb.append("\n");
+ str.write(sb.toString().getBytes());
+ }
+ str.flush();
+ FileUtils.sync(fstr);
+ str.close();
+ journal.commit();
+ } catch (Exception e) {
+ Slog.wtf(TAG, "Failed to write packages.list", e);
+ IoUtils.closeQuietly(str);
+ journal.rollback();
+ }
+ }
+
void writeDisabledSysPackageLPr(XmlSerializer serializer, final PackageSetting pkg)
throws java.io.IOException {
serializer.startTag(null, "updated-package");
@@ -3491,6 +3509,7 @@ final class Settings {
}
readDefaultPreferredAppsLPw(service, userHandle);
writePackageRestrictionsLPr(userHandle);
+ writePackageListLPr(userHandle);
}
void removeUserLPw(int userId) {
@@ -3506,6 +3525,8 @@ final class Settings {
removeCrossProfileIntentFiltersLPw(userId);
mRuntimePermissionsPersistence.onUserRemoved(userId);
+
+ writePackageListLPr();
}
void removeCrossProfileIntentFiltersLPw(int userId) {
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index a4e9c68..9bb5e40 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -51,7 +51,6 @@ import android.media.IAudioService;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.media.session.MediaSessionLegacyHelper;
-import android.os.Build;
import android.os.Bundle;
import android.os.Debug;
import android.os.FactoryTest;
@@ -97,7 +96,6 @@ import com.android.internal.policy.PhoneWindow;
import android.view.Surface;
import android.view.View;
import android.view.ViewConfiguration;
-import android.view.ViewRootImpl;
import android.view.Window;
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
@@ -458,7 +456,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// menu needs to be displayed.
boolean mLastFocusNeedsMenu = false;
- FakeWindow mHideNavFakeWindow = null;
+ InputConsumer mInputConsumer = null;
static final Rect mTmpParentFrame = new Rect();
static final Rect mTmpDisplayFrame = new Rect();
@@ -1817,7 +1815,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
case TYPE_APPLICATION_STARTING:
case TYPE_BOOT_PROGRESS:
case TYPE_DISPLAY_OVERLAY:
- case TYPE_HIDDEN_NAV_CONSUMER:
+ case TYPE_INPUT_CONSUMER:
case TYPE_KEYGUARD_SCRIM:
case TYPE_KEYGUARD_DIALOG:
case TYPE_MAGNIFICATION_OVERLAY:
@@ -1942,75 +1940,75 @@ public class PhoneWindowManager implements WindowManagerPolicy {
case TYPE_VOICE_INTERACTION:
// voice interaction layer is almost immediately above apps.
return 5;
- case TYPE_SYSTEM_DIALOG:
+ case TYPE_INPUT_CONSUMER:
return 6;
+ case TYPE_SYSTEM_DIALOG:
+ return 7;
case TYPE_TOAST:
// toasts and the plugged-in battery thing
- return 7;
+ return 8;
case TYPE_PRIORITY_PHONE:
// SIM errors and unlock. Not sure if this really should be in a high layer.
- return 8;
+ return 9;
case TYPE_DREAM:
// used for Dreams (screensavers with TYPE_DREAM windows)
- return 9;
+ return 10;
case TYPE_SYSTEM_ALERT:
// like the ANR / app crashed dialogs
- return 10;
+ return 11;
case TYPE_INPUT_METHOD:
// on-screen keyboards and other such input method user interfaces go here.
- return 11;
+ return 12;
case TYPE_INPUT_METHOD_DIALOG:
// on-screen keyboards and other such input method user interfaces go here.
- return 12;
+ return 13;
case TYPE_KEYGUARD_SCRIM:
// the safety window that shows behind keyguard while keyguard is starting
- return 13;
- case TYPE_STATUS_BAR_SUB_PANEL:
return 14;
- case TYPE_STATUS_BAR:
+ case TYPE_STATUS_BAR_SUB_PANEL:
return 15;
- case TYPE_STATUS_BAR_PANEL:
+ case TYPE_STATUS_BAR:
return 16;
- case TYPE_KEYGUARD_DIALOG:
+ case TYPE_STATUS_BAR_PANEL:
return 17;
+ case TYPE_KEYGUARD_DIALOG:
+ return 18;
case TYPE_VOLUME_OVERLAY:
// the on-screen volume indicator and controller shown when the user
// changes the device volume
- return 18;
+ return 19;
case TYPE_SYSTEM_OVERLAY:
// the on-screen volume indicator and controller shown when the user
// changes the device volume
- return 19;
+ return 20;
case TYPE_NAVIGATION_BAR:
// the navigation bar, if available, shows atop most things
- return 20;
+ return 21;
case TYPE_NAVIGATION_BAR_PANEL:
// some panels (e.g. search) need to show on top of the navigation bar
- return 21;
+ return 22;
case TYPE_SYSTEM_ERROR:
// system-level error dialogs
- return 22;
+ return 23;
case TYPE_MAGNIFICATION_OVERLAY:
// used to highlight the magnified portion of a display
- return 23;
+ return 24;
case TYPE_DISPLAY_OVERLAY:
// used to simulate secondary display devices
- return 24;
+ return 25;
case TYPE_DRAG:
// the drag layer: input for drag-and-drop is associated with this window,
// which sits above all other focusable windows
- return 25;
+ return 26;
case TYPE_ACCESSIBILITY_OVERLAY:
// overlay put by accessibility services to intercept user interaction
- return 26;
- case TYPE_SECURE_SYSTEM_OVERLAY:
return 27;
- case TYPE_BOOT_PROGRESS:
+ case TYPE_SECURE_SYSTEM_OVERLAY:
return 28;
+ case TYPE_BOOT_PROGRESS:
+ return 29;
case TYPE_POINTER:
// the (mouse) pointer layer
- return 29;
- case TYPE_HIDDEN_NAV_CONSUMER:
return 30;
}
Log.e(TAG, "Unknown window type: " + type);
@@ -3385,15 +3383,13 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// detect when the user presses anywhere to bring back the nav
// bar and ensure the application doesn't see the event.
if (navVisible || navAllowedHidden) {
- if (mHideNavFakeWindow != null) {
- mHideNavFakeWindow.dismiss();
- mHideNavFakeWindow = null;
+ if (mInputConsumer != null) {
+ mInputConsumer.dismiss();
+ mInputConsumer = null;
}
- } else if (mHideNavFakeWindow == null) {
- mHideNavFakeWindow = mWindowManagerFuncs.addFakeWindow(
- mHandler.getLooper(), mHideNavInputEventReceiverFactory,
- "hidden nav", WindowManager.LayoutParams.TYPE_HIDDEN_NAV_CONSUMER, 0,
- 0, false, false, true);
+ } else if (mInputConsumer == null) {
+ mInputConsumer = mWindowManagerFuncs.addInputConsumer(mHandler.getLooper(),
+ mHideNavInputEventReceiverFactory);
}
// For purposes of positioning and showing the nav bar, if we have
@@ -6311,7 +6307,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
vis = mNavigationBarController.applyTranslucentFlagLw(transWin, vis, oldVis);
// prevent status bar interaction from clearing certain flags
- boolean statusBarHasFocus = win.getAttrs().type == TYPE_STATUS_BAR;
+ int type = win.getAttrs().type;
+ boolean statusBarHasFocus = type == TYPE_STATUS_BAR;
if (statusBarHasFocus && !isStatusBarKeyguard()) {
int flags = View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
@@ -6323,6 +6320,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
vis = (vis & ~flags) | (oldVis & flags);
}
+ if (windowTypeToLayerLw(type) > windowTypeToLayerLw(TYPE_INPUT_CONSUMER)) {
+ // We can't get into fullscreen from this window otherwise the consumer would not get
+ // the input events.
+ vis = (vis & ~View.SYSTEM_UI_FLAG_FULLSCREEN);
+ }
if (!areTranslucentBarsAllowed() && transWin != mStatusBar) {
vis &= ~(View.NAVIGATION_BAR_TRANSLUCENT | View.STATUS_BAR_TRANSLUCENT
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index 482ae24..66ae9ef 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -1248,7 +1248,7 @@ final class AccessibilityController {
&& windowType != WindowManager.LayoutParams.TYPE_BOOT_PROGRESS
&& windowType != WindowManager.LayoutParams.TYPE_DISPLAY_OVERLAY
&& windowType != WindowManager.LayoutParams.TYPE_DRAG
- && windowType != WindowManager.LayoutParams.TYPE_HIDDEN_NAV_CONSUMER
+ && windowType != WindowManager.LayoutParams.TYPE_INPUT_CONSUMER
&& windowType != WindowManager.LayoutParams.TYPE_POINTER
&& windowType != WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY
&& windowType != WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY
diff --git a/services/core/java/com/android/server/wm/FakeWindowImpl.java b/services/core/java/com/android/server/wm/InputConsumerImpl.java
index 1136ced..0581a16 100644
--- a/services/core/java/com/android/server/wm/FakeWindowImpl.java
+++ b/services/core/java/com/android/server/wm/InputConsumerImpl.java
@@ -16,17 +16,18 @@
package com.android.server.wm;
-import com.android.server.input.InputApplicationHandle;
-import com.android.server.input.InputWindowHandle;
-
import android.os.Looper;
import android.os.Process;
import android.view.Display;
import android.view.InputChannel;
import android.view.InputEventReceiver;
+import android.view.WindowManager;
import android.view.WindowManagerPolicy;
-public final class FakeWindowImpl implements WindowManagerPolicy.FakeWindow {
+import com.android.server.input.InputApplicationHandle;
+import com.android.server.input.InputWindowHandle;
+
+public final class InputConsumerImpl implements WindowManagerPolicy.InputConsumer {
final WindowManagerService mService;
final InputChannel mServerChannel, mClientChannel;
final InputApplicationHandle mApplicationHandle;
@@ -34,12 +35,9 @@ public final class FakeWindowImpl implements WindowManagerPolicy.FakeWindow {
final InputEventReceiver mInputEventReceiver;
final int mWindowLayer;
- boolean mTouchFullscreen;
-
- public FakeWindowImpl(WindowManagerService service,
- Looper looper, InputEventReceiver.Factory inputEventReceiverFactory,
- String name, int windowType, int layoutParamsFlags,
- boolean canReceiveKeys, boolean hasFocus, boolean touchFullscreen) {
+ public InputConsumerImpl(WindowManagerService service, Looper looper,
+ InputEventReceiver.Factory inputEventReceiverFactory) {
+ String name = "input consumer";
mService = service;
InputChannel[] channels = InputChannel.openInputChannelPair(name);
@@ -58,31 +56,25 @@ public final class FakeWindowImpl implements WindowManagerPolicy.FakeWindow {
mWindowHandle = new InputWindowHandle(mApplicationHandle, null, Display.DEFAULT_DISPLAY);
mWindowHandle.name = name;
mWindowHandle.inputChannel = mServerChannel;
- mWindowLayer = getLayerLw(windowType);
+ mWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_INPUT_CONSUMER;
+ mWindowLayer = getLayerLw(mWindowHandle.layoutParamsType);
mWindowHandle.layer = mWindowLayer;
- mWindowHandle.layoutParamsFlags = layoutParamsFlags;
- mWindowHandle.layoutParamsType = windowType;
+ mWindowHandle.layoutParamsFlags = 0;
mWindowHandle.dispatchingTimeoutNanos =
WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
mWindowHandle.visible = true;
- mWindowHandle.canReceiveKeys = canReceiveKeys;
- mWindowHandle.hasFocus = hasFocus;
+ mWindowHandle.canReceiveKeys = false;
+ mWindowHandle.hasFocus = false;
mWindowHandle.hasWallpaper = false;
mWindowHandle.paused = false;
mWindowHandle.ownerPid = Process.myPid();
mWindowHandle.ownerUid = Process.myUid();
mWindowHandle.inputFeatures = 0;
mWindowHandle.scaleFactor = 1.0f;
-
- mTouchFullscreen = touchFullscreen;
}
void layout(int dw, int dh) {
- if (mTouchFullscreen) {
- mWindowHandle.touchableRegion.set(0, 0, dw, dh);
- } else {
- mWindowHandle.touchableRegion.setEmpty();
- }
+ mWindowHandle.touchableRegion.set(0, 0, dw, dh);
mWindowHandle.frameLeft = 0;
mWindowHandle.frameTop = 0;
mWindowHandle.frameRight = dw;
@@ -92,7 +84,7 @@ public final class FakeWindowImpl implements WindowManagerPolicy.FakeWindow {
@Override
public void dismiss() {
synchronized (mService.mWindowMap) {
- if (mService.removeFakeWindowLocked(this)) {
+ if (mService.removeInputConsumer()) {
mInputEventReceiver.dispose();
mService.mInputManager.unregisterInputChannel(mServerChannel);
mClientChannel.dispose();
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index c24fcb3..ae442e5 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -16,10 +16,6 @@
package com.android.server.wm;
-import com.android.server.input.InputManagerService;
-import com.android.server.input.InputApplicationHandle;
-import com.android.server.input.InputWindowHandle;
-
import android.app.ActivityManagerNative;
import android.graphics.Rect;
import android.os.RemoteException;
@@ -30,17 +26,21 @@ import android.view.InputChannel;
import android.view.KeyEvent;
import android.view.WindowManager;
+import com.android.server.input.InputApplicationHandle;
+import com.android.server.input.InputManagerService;
+import com.android.server.input.InputWindowHandle;
+
import java.util.Arrays;
final class InputMonitor implements InputManagerService.WindowManagerCallbacks {
private final WindowManagerService mService;
-
+
// Current window with input focus for keys and other non-touch events. May be null.
private WindowState mInputFocus;
-
+
// When true, prevents input dispatch from proceeding until set to false again.
private boolean mInputDispatchFrozen;
-
+
// When true, input dispatch proceeds normally. Otherwise all events are dropped.
// Initially false, so that input does not get dispatched until boot is finished at
// which point the ActivityManager will enable dispatching.
@@ -256,10 +256,7 @@ final class InputMonitor implements InputManagerService.WindowManagerCallbacks {
}
}
- final int NFW = mService.mFakeWindows.size();
- for (int i = 0; i < NFW; i++) {
- addInputWindowHandleLw(mService.mFakeWindows.get(i).mWindowHandle);
- }
+ boolean addInputConsumerHandle = mService.mInputConsumer != null;
// Add all windows on the default display.
final int numDisplays = mService.mDisplayContents.size();
@@ -273,6 +270,11 @@ final class InputMonitor implements InputManagerService.WindowManagerCallbacks {
// Skip this window because it cannot possibly receive input.
continue;
}
+ if (addInputConsumerHandle
+ && inputWindowHandle.layer <= mService.mInputConsumer.mWindowHandle.layer) {
+ addInputWindowHandleLw(mService.mInputConsumer.mWindowHandle);
+ addInputConsumerHandle = false;
+ }
final int flags = child.mAttrs.flags;
final int privateFlags = child.mAttrs.privateFlags;
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index d956d76..cebb909 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -108,7 +108,6 @@ import android.view.WindowManager.LayoutParams;
import android.view.WindowManagerGlobal;
import android.view.WindowManagerInternal;
import android.view.WindowManagerPolicy;
-import android.view.WindowManagerPolicy.FakeWindow;
import android.view.WindowManagerPolicy.PointerEventListener;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
@@ -382,10 +381,10 @@ public class WindowManagerService extends IWindowManager.Stub
final ArrayList<AppWindowToken> mFinishedStarting = new ArrayList<>();
/**
- * Fake windows added to the window manager. Note: ordered from top to
- * bottom, opposite of mWindows.
+ * The input consumer added to the window manager which consumes input events to windows below
+ * it.
*/
- final ArrayList<FakeWindowImpl> mFakeWindows = new ArrayList<>();
+ InputConsumerImpl mInputConsumer;
/**
* Windows that are being resized. Used so we can tell the client about
@@ -8966,9 +8965,8 @@ public class WindowManagerService extends IWindowManager.Stub
final int dw = displayInfo.logicalWidth;
final int dh = displayInfo.logicalHeight;
- final int NFW = mFakeWindows.size();
- for (int i=0; i<NFW; i++) {
- mFakeWindows.get(i).layout(dw, dh);
+ if (mInputConsumer != null) {
+ mInputConsumer.layout(dw, dh);
}
final int N = windows.size();
@@ -10995,28 +10993,19 @@ public class WindowManagerService extends IWindowManager.Stub
}
@Override
- public FakeWindow addFakeWindow(Looper looper,
- InputEventReceiver.Factory inputEventReceiverFactory,
- String name, int windowType, int layoutParamsFlags, int layoutParamsPrivateFlags,
- boolean canReceiveKeys, boolean hasFocus, boolean touchFullscreen) {
+ public InputConsumerImpl addInputConsumer(Looper looper,
+ InputEventReceiver.Factory inputEventReceiverFactory) {
synchronized (mWindowMap) {
- FakeWindowImpl fw = new FakeWindowImpl(this, looper, inputEventReceiverFactory,
- name, windowType, layoutParamsFlags, canReceiveKeys, hasFocus, touchFullscreen);
- int i=0;
- while (i<mFakeWindows.size()) {
- if (mFakeWindows.get(i).mWindowLayer <= fw.mWindowLayer) {
- break;
- }
- }
- mFakeWindows.add(i, fw);
+ mInputConsumer = new InputConsumerImpl(this, looper, inputEventReceiverFactory);
mInputMonitor.updateInputWindowsLw(true);
- return fw;
+ return mInputConsumer;
}
}
- boolean removeFakeWindowLocked(FakeWindow window) {
+ boolean removeInputConsumer() {
synchronized (mWindowMap) {
- if (mFakeWindows.remove(window)) {
+ if (mInputConsumer != null) {
+ mInputConsumer = null;
mInputMonitor.updateInputWindowsLw(true);
return true;
}
diff --git a/services/core/jni/Android.mk b/services/core/jni/Android.mk
index a5546cf..9556b08 100644
--- a/services/core/jni/Android.mk
+++ b/services/core/jni/Android.mk
@@ -10,7 +10,6 @@ LOCAL_SRC_FILES += \
$(LOCAL_REL_DIR)/com_android_server_AssetAtlasService.cpp \
$(LOCAL_REL_DIR)/com_android_server_connectivity_Vpn.cpp \
$(LOCAL_REL_DIR)/com_android_server_ConsumerIrService.cpp \
- $(LOCAL_REL_DIR)/com_android_server_fingerprint_FingerprintService.cpp \
$(LOCAL_REL_DIR)/com_android_server_hdmi_HdmiCecController.cpp \
$(LOCAL_REL_DIR)/com_android_server_input_InputApplicationHandle.cpp \
$(LOCAL_REL_DIR)/com_android_server_input_InputManagerService.cpp \
diff --git a/services/core/jni/onload.cpp b/services/core/jni/onload.cpp
index 7db7414..67872da 100644
--- a/services/core/jni/onload.cpp
+++ b/services/core/jni/onload.cpp
@@ -41,7 +41,6 @@ int register_android_server_connectivity_Vpn(JNIEnv* env);
int register_android_server_hdmi_HdmiCecController(JNIEnv* env);
int register_android_server_tv_TvInputHal(JNIEnv* env);
int register_android_server_PersistentDataBlockService(JNIEnv* env);
-int register_android_server_fingerprint_FingerprintService(JNIEnv* env);
int register_android_server_Watchdog(JNIEnv* env);
};
@@ -79,7 +78,6 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
register_android_server_hdmi_HdmiCecController(env);
register_android_server_tv_TvInputHal(env);
register_android_server_PersistentDataBlockService(env);
- register_android_server_fingerprint_FingerprintService(env);
register_android_server_Watchdog(env);
return JNI_VERSION_1_4;
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 9ad7e11..a9e76d8 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -6392,25 +6392,34 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
@Override
- public boolean setPermissionGranted(ComponentName admin, String packageName,
- String permission, boolean granted) throws RemoteException {
+ public boolean setPermissionGrantState(ComponentName admin, String packageName,
+ String permission, int grantState) throws RemoteException {
UserHandle user = Binder.getCallingUserHandle();
synchronized (this) {
getActiveAdminForCallerLocked(admin, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
long ident = Binder.clearCallingIdentity();
try {
PackageManager packageManager = mContext.getPackageManager();
- if (granted) {
- packageManager.grantRuntimePermission(packageName, permission, user);
- packageManager.updatePermissionFlags(permission, packageName,
- PackageManager.FLAG_PERMISSION_POLICY_FIXED,
- PackageManager.FLAG_PERMISSION_POLICY_FIXED, user);
- } else {
- packageManager.revokeRuntimePermission(packageName,
- permission, user);
- packageManager.updatePermissionFlags(permission, packageName,
- PackageManager.FLAG_PERMISSION_POLICY_FIXED,
- PackageManager.FLAG_PERMISSION_POLICY_FIXED, user);
+ switch (grantState) {
+ case DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED: {
+ packageManager.grantRuntimePermission(packageName, permission, user);
+ packageManager.updatePermissionFlags(permission, packageName,
+ PackageManager.FLAG_PERMISSION_POLICY_FIXED,
+ PackageManager.FLAG_PERMISSION_POLICY_FIXED, user);
+ } break;
+
+ case DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED: {
+ packageManager.revokeRuntimePermission(packageName,
+ permission, user);
+ packageManager.updatePermissionFlags(permission, packageName,
+ PackageManager.FLAG_PERMISSION_POLICY_FIXED,
+ PackageManager.FLAG_PERMISSION_POLICY_FIXED, user);
+ } break;
+
+ case DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT: {
+ packageManager.updatePermissionFlags(permission, packageName,
+ PackageManager.FLAG_PERMISSION_POLICY_FIXED, 0, user);
+ } break;
}
return true;
} catch (SecurityException se) {
diff --git a/services/usage/java/com/android/server/usage/IntervalStats.java b/services/usage/java/com/android/server/usage/IntervalStats.java
index d6ff475..a615675 100644
--- a/services/usage/java/com/android/server/usage/IntervalStats.java
+++ b/services/usage/java/com/android/server/usage/IntervalStats.java
@@ -131,6 +131,11 @@ class IntervalStats {
usageStats.mBeginIdleTime = timeStamp;
}
+ void updateLastUsedTime(String packageName, long lastUsedTime) {
+ UsageStats usageStats = getOrCreateUsageStats(packageName);
+ usageStats.mLastTimeUsed = lastUsedTime;
+ }
+
void updateConfigurationStats(Configuration config, long timeStamp) {
if (activeConfiguration != null) {
ConfigurationStats activeStats = configurations.get(activeConfiguration);
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index f7bcf2a..ff3bb28 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -99,7 +99,9 @@ public class UsageStatsService extends SystemService implements
private static final long TIME_CHANGE_THRESHOLD_MILLIS = 2 * 1000; // Two seconds.
static final long DEFAULT_APP_IDLE_THRESHOLD_MILLIS = DEBUG ? ONE_MINUTE * 4
- : 1L * 24 * 60 * ONE_MINUTE; // 1 day
+ : 12 * 60 * ONE_MINUTE; // 12 hours of screen-on time sans dream-time
+ static final long DEFAULT_WALLCLOCK_APP_IDLE_THRESHOLD_MILLIS = DEBUG ? ONE_MINUTE * 8
+ : 2L * 24 * 60 * ONE_MINUTE; // 2 days
static final long DEFAULT_CHECK_IDLE_INTERVAL = DEBUG ? ONE_MINUTE
: 8 * 60 * ONE_MINUTE; // 8 hours
static final long DEFAULT_PAROLE_INTERVAL = DEBUG ? ONE_MINUTE * 10
@@ -356,7 +358,7 @@ public class UsageStatsService extends SystemService implements
final int packageCount = packages.size();
for (int p = 0; p < packageCount; p++) {
final String packageName = packages.get(p).packageName;
- final boolean isIdle = isAppIdleFiltered(packageName, userId);
+ final boolean isIdle = isAppIdleFiltered(packageName, userId, timeNow);
mHandler.sendMessage(mHandler.obtainMessage(MSG_INFORM_LISTENERS,
userId, isIdle ? 1 : 0, packageName));
mAppIdleHistory.addEntry(packageName, userId, isIdle, timeNow);
@@ -386,7 +388,8 @@ public class UsageStatsService extends SystemService implements
void updateDisplayLocked() {
boolean screenOn = mDisplayManager.getDisplay(Display.DEFAULT_DISPLAY).getState()
- != Display.STATE_OFF;
+ == Display.STATE_ON;
+
if (screenOn == mScreenOn) return;
mScreenOn = screenOn;
@@ -533,14 +536,16 @@ public class UsageStatsService extends SystemService implements
void reportEvent(UsageEvents.Event event, int userId) {
synchronized (mLock) {
final long timeNow = checkAndGetTimeLocked();
+ final long screenOnTime = getScreenOnTimeLocked(timeNow);
convertToSystemTimeLocked(event);
final UserUsageStatsService service =
getUserDataAndInitializeIfNeededLocked(userId, timeNow);
- final long lastUsed = service.getBeginIdleTime(event.mPackage);
- final long screenOnTime = getScreenOnTimeLocked(timeNow);
- final boolean previouslyIdle = hasPassedIdleTimeout(lastUsed, screenOnTime);
- service.reportEvent(event, screenOnTime);
+ final long beginIdleTime = service.getBeginIdleTime(event.mPackage);
+ final long lastUsedTime = service.getLastUsedTime(event.mPackage);
+ final boolean previouslyIdle = hasPassedIdleTimeoutLocked(beginIdleTime,
+ lastUsedTime, screenOnTime, timeNow);
+ service.reportEvent(event, getScreenOnTimeLocked(timeNow));
// Inform listeners if necessary
if ((event.mEventType == Event.MOVE_TO_FOREGROUND
|| event.mEventType == Event.MOVE_TO_BACKGROUND
@@ -556,8 +561,9 @@ public class UsageStatsService extends SystemService implements
}
/**
- * Forces the app's beginIdleTime to reflect idle or active. If idle, then it rolls back the
- * beginIdleTime to a point in time thats behind the threshold for idle.
+ * Forces the app's beginIdleTime and lastUsedTime to reflect idle or active. If idle,
+ * then it rolls back the beginIdleTime and lastUsedTime to a point in time that's behind
+ * the threshold for idle.
*/
void forceIdleState(String packageName, int userId, boolean idle) {
synchronized (mLock) {
@@ -567,10 +573,13 @@ public class UsageStatsService extends SystemService implements
final UserUsageStatsService service =
getUserDataAndInitializeIfNeededLocked(userId, timeNow);
- final long lastUsed = service.getBeginIdleTime(packageName);
- final boolean previouslyIdle = hasPassedIdleTimeout(lastUsed,
- getScreenOnTimeLocked(timeNow));
+ final long beginIdleTime = service.getBeginIdleTime(packageName);
+ final long lastUsedTime = service.getLastUsedTime(packageName);
+ final boolean previouslyIdle = hasPassedIdleTimeoutLocked(beginIdleTime,
+ lastUsedTime, screenOnTime, timeNow);
service.setBeginIdleTime(packageName, deviceUsageTime);
+ service.setLastUsedTime(packageName,
+ timeNow - (idle ? DEFAULT_WALLCLOCK_APP_IDLE_THRESHOLD_MILLIS : 0) - 5000);
// Inform listeners if necessary
if (previouslyIdle != idle) {
// Slog.d(TAG, "Informing listeners of out-of-idle " + event.mPackage);
@@ -650,13 +659,14 @@ public class UsageStatsService extends SystemService implements
}
}
- private boolean isAppIdleUnfiltered(String packageName, int userId) {
+ private boolean isAppIdleUnfiltered(String packageName, int userId, long timeNow) {
synchronized (mLock) {
- final long timeNow = checkAndGetTimeLocked();
+ final long screenOnTime = getScreenOnTimeLocked(timeNow);
final UserUsageStatsService service =
getUserDataAndInitializeIfNeededLocked(userId, timeNow);
long beginIdleTime = service.getBeginIdleTime(packageName);
- return hasPassedIdleTimeout(beginIdleTime, getScreenOnTimeLocked(timeNow));
+ long lastUsedTime = service.getLastUsedTime(packageName);
+ return hasPassedIdleTimeoutLocked(beginIdleTime, lastUsedTime, screenOnTime, timeNow);
}
}
@@ -665,8 +675,10 @@ public class UsageStatsService extends SystemService implements
* @param currentTime current time in device usage timebase
* @return whether it's been used far enough in the past to be considered inactive
*/
- boolean hasPassedIdleTimeout(long timestamp, long currentTime) {
- return timestamp <= currentTime - mAppIdleDurationMillis;
+ boolean hasPassedIdleTimeoutLocked(long beginIdleTime, long lastUsedTime,
+ long screenOnTime, long currentTime) {
+ return (beginIdleTime <= screenOnTime - mAppIdleDurationMillis)
+ && (lastUsedTime <= currentTime - DEFAULT_WALLCLOCK_APP_IDLE_THRESHOLD_MILLIS);
}
void addListener(AppIdleStateChangeListener listener) {
@@ -689,9 +701,12 @@ public class UsageStatsService extends SystemService implements
* This happens if the device is plugged in or temporarily allowed to make exceptions.
* Called by interface impls.
*/
- boolean isAppIdleFiltered(String packageName, int userId) {
+ boolean isAppIdleFiltered(String packageName, int userId, long timeNow) {
if (packageName == null) return false;
synchronized (mLock) {
+ if (timeNow == -1) {
+ timeNow = checkAndGetTimeLocked();
+ }
// Temporary exemption, probably due to device charging or occasional allowance to
// be allowed to sync, etc.
if (mAppIdleParoled) {
@@ -715,7 +730,7 @@ public class UsageStatsService extends SystemService implements
return false;
}
- return isAppIdleUnfiltered(packageName, userId);
+ return isAppIdleUnfiltered(packageName, userId, timeNow);
}
void setAppIdle(String packageName, boolean idle, int userId) {
@@ -948,7 +963,7 @@ public class UsageStatsService extends SystemService implements
}
final long token = Binder.clearCallingIdentity();
try {
- return UsageStatsService.this.isAppIdleFiltered(packageName, userId);
+ return UsageStatsService.this.isAppIdleFiltered(packageName, userId, -1);
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -1053,7 +1068,7 @@ public class UsageStatsService extends SystemService implements
@Override
public boolean isAppIdle(String packageName, int userId) {
- return UsageStatsService.this.isAppIdleFiltered(packageName, userId);
+ return UsageStatsService.this.isAppIdleFiltered(packageName, userId, -1);
}
@Override
diff --git a/services/usage/java/com/android/server/usage/UserUsageStatsService.java b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
index b7e1c22..7c00dae 100644
--- a/services/usage/java/com/android/server/usage/UserUsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
@@ -216,12 +216,19 @@ class UserUsageStatsService {
}
/**
- * Sets the last timestamp for each of the intervals.
- * @param lastTimestamp
+ * Sets the beginIdleTime for each of the intervals.
+ * @param beginIdleTime
*/
- void setBeginIdleTime(String packageName, long deviceUsageTime) {
+ void setBeginIdleTime(String packageName, long beginIdleTime) {
for (IntervalStats stats : mCurrentStats) {
- stats.updateBeginIdleTime(packageName, deviceUsageTime);
+ stats.updateBeginIdleTime(packageName, beginIdleTime);
+ }
+ notifyStatsChanged();
+ }
+
+ void setLastUsedTime(String packageName, long lastUsedTime) {
+ for (IntervalStats stats : mCurrentStats) {
+ stats.updateLastUsedTime(packageName, lastUsedTime);
}
notifyStatsChanged();
}
@@ -390,6 +397,16 @@ class UserUsageStatsService {
}
}
+ long getLastUsedTime(String packageName) {
+ final IntervalStats yearly = mCurrentStats[UsageStatsManager.INTERVAL_YEARLY];
+ UsageStats packageUsage;
+ if ((packageUsage = yearly.packageStats.get(packageName)) == null) {
+ return -1;
+ } else {
+ return packageUsage.getLastTimeUsed();
+ }
+ }
+
void persistActiveStats() {
if (mStatsChanged) {
Slog.i(TAG, mLogPrefix + "Flushing usage stats to disk");
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index fcdb6d6..35bdceb 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -151,7 +151,7 @@ public class VoiceInteractionManagerService extends SystemService {
// the user to have the default voice interaction service enabled.
// Note that we don't do this for low-RAM devices, since we aren't
// supporting voice interaction services there.
- curInteractorInfo = findAvailInteractor(userHandle, curRecognizer);
+ curInteractorInfo = findAvailInteractor(userHandle, curRecognizer.getPackageName());
if (curInteractorInfo != null) {
// Looks good! We'll apply this one. To make it happen, we clear the
// recognizer so that we don't think we have anything set and will
@@ -162,6 +162,18 @@ public class VoiceInteractionManagerService extends SystemService {
}
}
+ // If forceInteractorPackage exists, try to apply the interactor from this package if
+ // possible and ignore the regular interactor setting.
+ String forceInteractorPackage =
+ getForceVoiceInteractionServicePackage(mContext.getResources());
+ if (forceInteractorPackage != null) {
+ curInteractorInfo = findAvailInteractor(userHandle, forceInteractorPackage);
+ if (curInteractorInfo != null) {
+ // We'll apply this one. Clear the recognizer and re-apply the settings.
+ curRecognizer = null;
+ }
+ }
+
// If we are on a svelte device, make sure an interactor is not currently
// enabled; if it is, turn it off.
if (!mEnableService && curInteractorStr != null) {
@@ -225,8 +237,14 @@ public class VoiceInteractionManagerService extends SystemService {
private boolean shouldEnableService(Resources res) {
// VoiceInteractionService should not be enabled on low ram devices unless it has the config flag.
- return !ActivityManager.isLowRamDeviceStatic()
- || res.getBoolean(com.android.internal.R.bool.config_forceEnableVoiceInteractionService);
+ return !ActivityManager.isLowRamDeviceStatic() ||
+ getForceVoiceInteractionServicePackage(res) != null;
+ }
+
+ private String getForceVoiceInteractionServicePackage(Resources res) {
+ String interactorPackage =
+ res.getString(com.android.internal.R.string.config_forceVoiceInteractionServicePackage);
+ return TextUtils.isEmpty(interactorPackage) ? null : interactorPackage;
}
public void systemRunning(boolean safeMode) {
@@ -279,7 +297,7 @@ public class VoiceInteractionManagerService extends SystemService {
}
}
- VoiceInteractionServiceInfo findAvailInteractor(int userHandle, ComponentName recognizer) {
+ VoiceInteractionServiceInfo findAvailInteractor(int userHandle, String packageName) {
List<ResolveInfo> available =
mContext.getPackageManager().queryIntentServicesAsUser(
new Intent(VoiceInteractionService.SERVICE_INTERFACE), 0, userHandle);
@@ -300,8 +318,8 @@ public class VoiceInteractionManagerService extends SystemService {
VoiceInteractionServiceInfo info = new VoiceInteractionServiceInfo(
mContext.getPackageManager(), comp, userHandle);
if (info.getParseError() == null) {
- if (recognizer == null || info.getServiceInfo().packageName.equals(
- recognizer.getPackageName())) {
+ if (packageName == null || info.getServiceInfo().packageName.equals(
+ packageName)) {
if (foundInfo == null) {
foundInfo = info;
} else {
diff --git a/tests/RenderScriptTests/FBOTest/src/com/android/fbotest/fbosync.rs b/tests/RenderScriptTests/FBOTest/src/com/android/fbotest/fbosync.rs
index 42b1cf1..0c177ef 100644
--- a/tests/RenderScriptTests/FBOTest/src/com/android/fbotest/fbosync.rs
+++ b/tests/RenderScriptTests/FBOTest/src/com/android/fbotest/fbosync.rs
@@ -116,7 +116,6 @@ static void renderAllMeshes() {
rs_allocation allMeshes = rsGetAllocation(gMeshes);
int size = rsAllocationGetDimX(allMeshes);
gLookAt = 0.0f;
- float minX, minY, minZ, maxX, maxY, maxZ;
for (int i = 0; i < size; i++) {
MeshInfo_t *info = (MeshInfo_t*)rsGetElementAt(allMeshes, i);
rsgDrawMesh(info->mMesh);
@@ -124,7 +123,6 @@ static void renderAllMeshes() {
}
static void drawDescription() {
- uint width = rsgGetWidth();
uint height = rsgGetHeight();
int left = 0, right = 0, top = 0, bottom = 0;
@@ -196,7 +194,6 @@ int root(void) {
uint32_t w = rsAllocationGetDimX(gOffscreen);
uint32_t h = rsAllocationGetDimY(gOffscreen);
- uint32_t numElements = w*h;
rsgAllocationSyncAll(gOffscreen, RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET);
diff --git a/tests/RenderScriptTests/FBOTest/src/com/android/fbotest/fbotest.rs b/tests/RenderScriptTests/FBOTest/src/com/android/fbotest/fbotest.rs
index 05ef3ac..13a3c85 100644
--- a/tests/RenderScriptTests/FBOTest/src/com/android/fbotest/fbotest.rs
+++ b/tests/RenderScriptTests/FBOTest/src/com/android/fbotest/fbotest.rs
@@ -115,7 +115,6 @@ static void renderAllMeshes() {
rs_allocation allMeshes = rsGetAllocation(gMeshes);
int size = rsAllocationGetDimX(allMeshes);
gLookAt = 0.0f;
- float minX, minY, minZ, maxX, maxY, maxZ;
for (int i = 0; i < size; i++) {
MeshInfo_t *info = (MeshInfo_t*)rsGetElementAt(allMeshes, i);
rsgDrawMesh(info->mMesh);
@@ -123,7 +122,6 @@ static void renderAllMeshes() {
}
static void drawDescription() {
- uint width = rsgGetWidth();
uint height = rsgGetHeight();
int left = 0, right = 0, top = 0, bottom = 0;
diff --git a/tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/simplemodel.rs b/tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/simplemodel.rs
index de2a0a7..d3dd5b9 100644
--- a/tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/simplemodel.rs
+++ b/tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/simplemodel.rs
@@ -123,7 +123,6 @@ static void renderAllMeshes() {
rs_allocation allMeshes = rsGetAllocation(gMeshes);
int size = rsAllocationGetDimX(allMeshes);
gLookAt = 0.0f;
- float minX, minY, minZ, maxX, maxY, maxZ;
for (int i = 0; i < size; i++) {
MeshInfo_t *info = (MeshInfo_t*)rsGetElementAt(allMeshes, i);
rsgDrawMesh(info->mMesh);
@@ -131,7 +130,6 @@ static void renderAllMeshes() {
}
void drawDescription() {
- uint width = rsgGetWidth();
uint height = rsgGetHeight();
int left = 0, right = 0, top = 0, bottom = 0;
@@ -163,7 +161,7 @@ int root(void) {
rsMatrixMultiply(&matrix, &gPostureMatrix);
rsMatrixRotate(&matrix, gRotateX, 1.0f, 0.0f, 0.0f);
rsMatrixRotate(&matrix, gRotateY, 0.0f, 1.0f, 0.0f);
-
+
rsgProgramVertexLoadModelMatrix(&matrix);
renderAllMeshes();
diff --git a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/rsbench.rs b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/rsbench.rs
index 27e5b11..43cf4e0 100644
--- a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/rsbench.rs
+++ b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/rsbench.rs
@@ -85,7 +85,7 @@ static void runSubTest(int index) {
TestData testData;
fillSurfaceParams(&testData);
- rs_allocation null_alloc;
+ rs_allocation null_alloc = {0};
rsForEach(gTestScripts[index].testScript,
gTestScripts[index].testData,
null_alloc,
@@ -125,7 +125,6 @@ static bool checkInit() {
static int benchMode = 0;
static bool benchmarkSingleTest = false;
-static int benchSubMode = 0;
static int runningLoops = 0;
static bool sendMsgFlag = false;
@@ -209,7 +208,6 @@ static void benchmark() {
drawOffscreenResult(0, 0, quadW, quadH);
int left = 0, right = 0, top = 0, bottom = 0;
- uint width = rsgGetWidth();
uint height = rsgGetHeight();
rsgFontColor(0.9f, 0.9f, 0.95f, 1.0f);
rsgBindFont(gFontSerif);
diff --git a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/text_test.rs b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/text_test.rs
index 7f10019..0f50828 100644
--- a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/text_test.rs
+++ b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/text_test.rs
@@ -52,7 +52,6 @@ static void displayFontSamples(int fillNum) {
fonts[3] = gFontSerif;
fonts[4] = gFontSans;
- uint width = gRenderSurfaceW;
uint height = gRenderSurfaceH;
int left = 0, right = 0, top = 0, bottom = 0;
rsgMeasureText(sampleText, &left, &right, &top, &bottom);
diff --git a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/ui_test.rs b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/ui_test.rs
index 5089092..e87db39 100644
--- a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/ui_test.rs
+++ b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/ui_test.rs
@@ -143,7 +143,6 @@ static void createParticle(Particle_t *part, int idx, float scale) {
float d = fabs(randomGauss()) * gGalaxyRadius * 0.5f + rsRand(64.0f);
float id = d / gGalaxyRadius;
float z = randomGauss() * 0.4f * (1.0f - id);
- float p = -d * ELLIPSE_TWIST;
if (d < gGalaxyRadius * 0.33f) {
part->color.x = (uchar) (220 + id * 35);
@@ -305,7 +304,6 @@ static void drawMeshInPage(float xStart, float yStart, int wResolution, int hRes
int left = 0, right = 0, top = 0, bottom = 0;
rsgMeasureText(gSampleTextList100[0].item, &left, &right, &top, &bottom);
float textHeight = (float)(top - bottom);
- float textWidth = (float)(right - left);
rs_matrix4x4 matrix;
rsMatrixLoadScale(&matrix, size, size, 1.0);
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/params.rsh b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/params.rsh
index 575794b..00793c0 100644
--- a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/params.rsh
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/params.rsh
@@ -19,7 +19,7 @@
#include "scenegraph_objects.rsh"
//#define DEBUG_PARAMS
-static void debugParam(SgShaderParam *p, SgShaderParamData *pData) {
+static inline void debugParam(SgShaderParam *p, SgShaderParamData *pData) {
rsDebug("____________ Param ____________", p);
printName(pData->paramName);
rsDebug("bufferOffset", p->bufferOffset);
@@ -44,8 +44,7 @@ static void debugParam(SgShaderParam *p, SgShaderParamData *pData) {
}
}
-
-static void writeFloatData(float *ptr, const float4 *input, uint32_t vecSize) {
+static inline void writeFloatData(float *ptr, const float4 *input, uint32_t vecSize) {
#ifdef DEBUG_PARAMS
rsDebug("Writing value ", *input);
rsDebug("Writing vec size ", vecSize);
@@ -67,7 +66,7 @@ static void writeFloatData(float *ptr, const float4 *input, uint32_t vecSize) {
}
}
-static bool processParam(SgShaderParam *p, SgShaderParamData *pData,
+static inline bool processParam(SgShaderParam *p, SgShaderParamData *pData,
uint8_t *constantBuffer,
const SgCamera *currentCam,
SgFragmentShader *shader) {
@@ -155,7 +154,7 @@ static bool processParam(SgShaderParam *p, SgShaderParamData *pData,
return true;
}
-static void processAllParams(rs_allocation shaderConst,
+static inline void processAllParams(rs_allocation shaderConst,
rs_allocation allParams,
const SgCamera *camera) {
if (rsIsObject(shaderConst)) {
@@ -177,7 +176,7 @@ static void processAllParams(rs_allocation shaderConst,
}
}
-static void processTextureParams(SgFragmentShader *shader) {
+static inline void processTextureParams(SgFragmentShader *shader) {
int numParams = 0;
if (rsIsObject(shader->shaderTextureParams)) {
numParams = rsAllocationGetDimX(shader->shaderTextureParams);
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/render.rs b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/render.rs
index 8a73dbd..205b2cb 100644
--- a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/render.rs
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/render.rs
@@ -78,7 +78,7 @@ static void draw(SgRenderable *obj) {
if (rsIsObject(renderState->pr)) {
rsgBindProgramRaster(renderState->pr);
} else {
- rs_program_raster pr;
+ rs_program_raster pr = {0};
rsgBindProgramRaster(pr);
}
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/scenegraph_objects.rsh b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/scenegraph_objects.rsh
index bdca3ab..90ae212 100644
--- a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/scenegraph_objects.rsh
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/scenegraph_objects.rsh
@@ -208,7 +208,7 @@ typedef struct Texture_s {
rs_allocation texture;
} SgTexture;
-static void printName(rs_allocation name) {
+static inline void printName(rs_allocation name) {
if (!rsIsObject(name)) {
rsDebug("no name", 0);
return;
@@ -217,7 +217,7 @@ static void printName(rs_allocation name) {
rsDebug((const char*)rsGetElementAt(name, 0), 0);
}
-static void printCameraInfo(const SgCamera *cam) {
+static inline void printCameraInfo(const SgCamera *cam) {
rsDebug("***** Camera information. ptr:", cam);
printName(cam->name);
const SgTransform *camTransform = (const SgTransform *)rsGetElementAt(cam->transformMatrix, 0);
@@ -233,7 +233,7 @@ static void printCameraInfo(const SgCamera *cam) {
rsDebug("View: ", &cam->view);
}
-static void printLightInfo(const SgLight *light) {
+static inline void printLightInfo(const SgLight *light) {
rsDebug("***** Light information. ptr:", light);
printName(light->name);
const SgTransform *lTransform = (const SgTransform *)rsGetElementAt(light->transformMatrix, 0);
@@ -246,7 +246,7 @@ static void printLightInfo(const SgLight *light) {
rsDebug("Type: ", light->type);
}
-static void getCameraRay(const SgCamera *cam, int screenX, int screenY, float3 *pnt, float3 *vec) {
+static inline void getCameraRay(const SgCamera *cam, int screenX, int screenY, float3 *pnt, float3 *vec) {
rsDebug("=================================", screenX);
rsDebug("Point X", screenX);
rsDebug("Point Y", screenY);
@@ -290,7 +290,7 @@ static void getCameraRay(const SgCamera *cam, int screenX, int screenY, float3 *
*pnt = cam->position.xyz;
}
-static bool intersect(const SgRenderable *obj, float3 pnt, float3 vec) {
+static inline bool intersect(const SgRenderable *obj, float3 pnt, float3 vec) {
// Solving for t^2 + Bt + C = 0
float3 originMinusCenter = pnt - obj->worldBoundingSphere.xyz;
float B = dot(originMinusCenter, vec) * 2.0f;
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/transform.rs b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/transform.rs
index 941b5a8..1d0b5be 100644
--- a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/transform.rs
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/transform.rs
@@ -26,6 +26,7 @@ typedef struct {
} ParentData;
//#define DEBUG_TRANSFORMS
+/* Unused function:
static void debugTransform(SgTransform *data, const ParentData *parent) {
rsDebug("****** <Transform> ******", (int)data);
printName(data->name);
@@ -53,6 +54,7 @@ static void debugTransform(SgTransform *data, const ParentData *parent) {
rsDebug("timestamp", data->timestamp);
rsDebug("****** </Transform> ******", (int)data);
}
+*/
static void appendTransformation(int type, float4 data, rs_matrix4x4 *mat) {
rs_matrix4x4 temp;
@@ -119,7 +121,7 @@ void root(const rs_allocation *v_in, rs_allocation *v_out, const void *usrData)
}
if (rsIsObject(data->children)) {
- rs_allocation nullAlloc;
+ rs_allocation nullAlloc = {0};
rsForEach(gTransformScript, data->children, nullAlloc, &toChild, sizeof(toChild));
}
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/test_app.rs b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/test_app.rs
index 997a1a7..d94da52 100644
--- a/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/test_app.rs
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/test_app.rs
@@ -41,9 +41,7 @@ void init() {
gRotate = 0.0f;
}
-static int pos = 50;
static float gRotateY = 120.0f;
-static float3 gLookAt = 0;
static float gZoom = 50.0f;
static void displayLoading() {
if (rsIsObject(gRobotTex) && rsIsObject(gRobotMesh)) {
diff --git a/tests/RenderScriptTests/ShadersTest/src/com/android/shaderstest/shaderstest.rs b/tests/RenderScriptTests/ShadersTest/src/com/android/shaderstest/shaderstest.rs
index ae32e3a..735f6b9 100644
--- a/tests/RenderScriptTests/ShadersTest/src/com/android/shaderstest/shaderstest.rs
+++ b/tests/RenderScriptTests/ShadersTest/src/com/android/shaderstest/shaderstest.rs
@@ -131,7 +131,6 @@ static void renderAllMeshes() {
rs_allocation allMeshes = rsGetAllocation(gMeshes);
int size = rsAllocationGetDimX(allMeshes);
gLookAt = 0.0f;
- float minX, minY, minZ, maxX, maxY, maxZ;
for (int i = 0; i < size; i++) {
MeshInfo_t *info = (MeshInfo_t*)rsGetElementAt(allMeshes, i);
rsgDrawMesh(info->mMesh);
diff --git a/tools/layoutlib/bridge/src/android/content/res/BridgeResources.java b/tools/layoutlib/bridge/src/android/content/res/BridgeResources.java
index 2c2c672..fdb6e75 100644
--- a/tools/layoutlib/bridge/src/android/content/res/BridgeResources.java
+++ b/tools/layoutlib/bridge/src/android/content/res/BridgeResources.java
@@ -169,7 +169,7 @@ public final class BridgeResources extends Resources {
}
@Override
- public int getColor(int id) throws NotFoundException {
+ public int getColor(int id, Theme theme) throws NotFoundException {
Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag);
if (value != null) {
@@ -192,22 +192,21 @@ public final class BridgeResources extends Resources {
}
}
- // id was not found or not resolved. Throw a NotFoundException.
- throwException(id);
-
- // this is not used since the method above always throws
- return 0;
+ // Suppress possible NPE. getColorStateList will never return null, it will instead
+ // throw an exception, but intelliJ can't figure that out
+ //noinspection ConstantConditions
+ return getColorStateList(id, theme).getDefaultColor();
}
@Override
- public ColorStateList getColorStateList(int id) throws NotFoundException {
+ public ColorStateList getColorStateList(int id, Theme theme) throws NotFoundException {
Pair<String, ResourceValue> resValue = getResourceValue(id, mPlatformResourceFlag);
if (resValue != null) {
ColorStateList stateList = ResourceHelper.getColorStateList(resValue.getSecond(),
mContext);
if (stateList != null) {
- return stateList;
+ return stateList.obtainForTheme(theme);
}
}
diff --git a/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java b/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java
index 771cf57..54a508a 100644
--- a/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java
+++ b/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java
@@ -320,7 +320,8 @@ public final class BridgeTypedArray extends TypedArray {
BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser(
parser, mContext, resValue.isFramework());
try {
- return ColorStateList.createFromXml(mContext.getResources(), blockParser);
+ return ColorStateList.createFromXml(mContext.getResources(), blockParser,
+ mContext.getTheme());
} finally {
blockParser.ensurePopped();
}
diff --git a/tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java b/tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java
index dda8ebb..4226526 100644
--- a/tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java
@@ -82,36 +82,8 @@ public class StaticLayout_Delegate {
builder.mText = text;
builder.mWidths = new float[length];
-
- // compute all possible breakpoints.
- BreakIterator it = BreakIterator.getLineInstance(new ULocale(builder.mLocale));
- it.setText(new Segment(builder.mText, 0, length));
-
- // average word length in english is 5. So, initialize the possible breaks with a guess.
- List<Integer> breaks = new ArrayList<Integer>((int) Math.ceil(length / 5d));
- int loc;
- it.first();
- while ((loc = it.next()) != BreakIterator.DONE) {
- breaks.add(loc);
- }
- LineWidth lineWidth = new LineWidth(firstWidth, firstWidthLineCount, restWidth);
- TabStops tabStopCalculator = new TabStops(variableTabStops, defaultTabStop);
- List<Primitive> primitives =
- computePrimitives(builder.mText, builder.mWidths, length, breaks);
- BreakStrategy strategy = BreakStrategy.getStrategy(breakStrategy);
- switch (strategy) {
- case GREEDY:
- builder.mLineBreaker =
- new GreedyLineBreaker(primitives, lineWidth, tabStopCalculator);
- break;
- case HIGH_QUALITY:
- // TODO
-// break;
- case BALANCED:
- builder.mLineBreaker = new OptimizingLineBreaker(primitives, lineWidth,
- tabStopCalculator);
- break;
- }
+ builder.mLineWidth = new LineWidth(firstWidth, firstWidthLineCount, restWidth);
+ builder.mTabStopCalculator = new TabStops(variableTabStops, defaultTabStop);
}
@LayoutlibDelegate
@@ -160,6 +132,37 @@ public class StaticLayout_Delegate {
if (builder == null) {
return 0;
}
+
+ // compute all possible breakpoints.
+ int length = builder.mWidths.length;
+ BreakIterator it = BreakIterator.getLineInstance(new ULocale(builder.mLocale));
+ it.setText(new Segment(builder.mText, 0, length));
+
+ // average word length in english is 5. So, initialize the possible breaks with a guess.
+ List<Integer> breaks = new ArrayList<Integer>((int) Math.ceil(length / 5d));
+ int loc;
+ it.first();
+ while ((loc = it.next()) != BreakIterator.DONE) {
+ breaks.add(loc);
+ }
+
+ List<Primitive> primitives =
+ computePrimitives(builder.mText, builder.mWidths, length, breaks);
+ switch (builder.mBreakStrategy) {
+ case Layout.BREAK_STRATEGY_SIMPLE:
+ builder.mLineBreaker = new GreedyLineBreaker(primitives, builder.mLineWidth,
+ builder.mTabStopCalculator);
+ break;
+ case Layout.BREAK_STRATEGY_HIGH_QUALITY:
+ // TODO
+// break;
+ case Layout.BREAK_STRATEGY_BALANCED:
+ builder.mLineBreaker = new OptimizingLineBreaker(primitives, builder.mLineWidth,
+ builder.mTabStopCalculator);
+ break;
+ default:
+ throw new AssertionError("Unknown break strategy: " + builder.mBreakStrategy);
+ }
builder.mLineBreaker.computeBreaks(recycle);
return recycle.breaks.length;
}
@@ -223,22 +226,8 @@ public class StaticLayout_Delegate {
float[] mWidths;
LineBreaker mLineBreaker;
long mNativeHyphenator;
- }
-
- private enum BreakStrategy {
- GREEDY, HIGH_QUALITY, BALANCED;
-
- static BreakStrategy getStrategy(int strategy) {
- switch (strategy) {
- case 0:
- return GREEDY;
- case 1:
- return HIGH_QUALITY;
- case 2:
- return BALANCED;
- default:
- throw new AssertionError("Unknown break strategy: " + strategy);
- }
- }
+ int mBreakStrategy;
+ LineWidth mLineWidth;
+ TabStops mTabStopCalculator;
}
}
diff --git a/tools/layoutlib/bridge/src/android/view/View_Delegate.java b/tools/layoutlib/bridge/src/android/view/View_Delegate.java
index 8215f7c..408ec54 100644
--- a/tools/layoutlib/bridge/src/android/view/View_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/view/View_Delegate.java
@@ -16,8 +16,12 @@
package android.view;
+import com.android.layoutlib.bridge.android.BridgeContext;
import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+import android.content.Context;
+import android.os.IBinder;
+
/**
* Delegate used to provide new implementation of a select few methods of {@link View}
*
@@ -31,4 +35,13 @@ public class View_Delegate {
/*package*/ static boolean isInEditMode(View thisView) {
return true;
}
+
+ @LayoutlibDelegate
+ /*package*/ static IBinder getWindowToken(View thisView) {
+ Context baseContext = BridgeContext.getBaseContext(thisView.getContext());
+ if (baseContext instanceof BridgeContext) {
+ return ((BridgeContext) baseContext).getBinder();
+ }
+ return null;
+ }
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index 59f07a7..eded804 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -65,8 +65,11 @@ import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
+import android.os.IInterface;
import android.os.Looper;
+import android.os.Parcel;
import android.os.PowerManager;
+import android.os.RemoteException;
import android.os.UserHandle;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
@@ -82,6 +85,7 @@ import android.view.accessibility.AccessibilityManager;
import android.view.textservice.TextServicesManager;
import java.io.File;
+import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
@@ -139,6 +143,7 @@ public final class BridgeContext extends Context {
private final Stack<BridgeXmlBlockParser> mParserStack = new Stack<BridgeXmlBlockParser>();
private SharedPreferences mSharedPreferences;
private ClassLoader mClassLoader;
+ private IBinder mBinder;
/**
* @param projectKey An Object identifying the project. This is used for the cache mechanism.
@@ -708,44 +713,48 @@ public final class BridgeContext extends Context {
}
}
} else if (defStyleRes != 0) {
- boolean isFrameworkRes = true;
- Pair<ResourceType, String> value = Bridge.resolveResourceId(defStyleRes);
- if (value == null) {
- value = mLayoutlibCallback.resolveResourceId(defStyleRes);
- isFrameworkRes = false;
- }
+ StyleResourceValue item = mDynamicIdToStyleMap.get(defStyleRes);
+ if (item != null) {
+ defStyleValues = item;
+ } else {
+ boolean isFrameworkRes = true;
+ Pair<ResourceType, String> value = Bridge.resolveResourceId(defStyleRes);
+ if (value == null) {
+ value = mLayoutlibCallback.resolveResourceId(defStyleRes);
+ isFrameworkRes = false;
+ }
- if (value != null) {
- if ((value.getFirst() == ResourceType.STYLE)) {
- // look for the style in all resources:
- StyleResourceValue item = mRenderResources.getStyle(value.getSecond(),
- isFrameworkRes);
- if (item != null) {
- if (defaultPropMap != null) {
- defaultPropMap.put("style", item.getName());
+ if (value != null) {
+ if ((value.getFirst() == ResourceType.STYLE)) {
+ // look for the style in all resources:
+ item = mRenderResources.getStyle(value.getSecond(), isFrameworkRes);
+ if (item != null) {
+ if (defaultPropMap != null) {
+ defaultPropMap.put("style", item.getName());
+ }
+
+ defStyleValues = item;
+ } else {
+ Bridge.getLog().error(null,
+ String.format(
+ "Style with id 0x%x (resolved to '%s') does not exist.",
+ defStyleRes, value.getSecond()),
+ null);
}
-
- defStyleValues = item;
} else {
Bridge.getLog().error(null,
String.format(
- "Style with id 0x%x (resolved to '%s') does not exist.",
- defStyleRes, value.getSecond()),
+ "Resource id 0x%x is not of type STYLE (instead %s)",
+ defStyleRes, value.getFirst().toString()),
null);
}
} else {
Bridge.getLog().error(null,
String.format(
- "Resource id 0x%x is not of type STYLE (instead %s)",
- defStyleRes, value.getFirst().toString()),
+ "Failed to find style with id 0x%x in current theme",
+ defStyleRes),
null);
}
- } else {
- Bridge.getLog().error(null,
- String.format(
- "Failed to find style with id 0x%x in current theme",
- defStyleRes),
- null);
}
}
@@ -996,6 +1005,61 @@ public final class BridgeContext extends Context {
return context;
}
+ public IBinder getBinder() {
+ if (mBinder == null) {
+ // create a dummy binder. We only need it be not null.
+ mBinder = new IBinder() {
+ @Override
+ public String getInterfaceDescriptor() throws RemoteException {
+ return null;
+ }
+
+ @Override
+ public boolean pingBinder() {
+ return false;
+ }
+
+ @Override
+ public boolean isBinderAlive() {
+ return false;
+ }
+
+ @Override
+ public IInterface queryLocalInterface(String descriptor) {
+ return null;
+ }
+
+ @Override
+ public void dump(FileDescriptor fd, String[] args) throws RemoteException {
+
+ }
+
+ @Override
+ public void dumpAsync(FileDescriptor fd, String[] args) throws RemoteException {
+
+ }
+
+ @Override
+ public boolean transact(int code, Parcel data, Parcel reply, int flags)
+ throws RemoteException {
+ return false;
+ }
+
+ @Override
+ public void linkToDeath(DeathRecipient recipient, int flags)
+ throws RemoteException {
+
+ }
+
+ @Override
+ public boolean unlinkToDeath(DeathRecipient recipient, int flags) {
+ return false;
+ }
+ };
+ }
+ return mBinder;
+ }
+
//------------ NOT OVERRIDEN --------------------
@Override
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
index 91be0bd..63115e4 100644
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
+++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
@@ -124,9 +124,14 @@ public class Main {
if (platformDir != null) {
return platformDir;
}
- // Test if workingDir is platform/frameworks/base/tools/layoutlib. That is, root should be
- // workingDir/../../../../ (4 levels up)
+
+ // Test if workingDir is platform/frameworks/base/tools/layoutlib/bridge.
File currentDir = workingDir;
+ if (currentDir.getName().equalsIgnoreCase("bridge")) {
+ currentDir = currentDir.getParentFile();
+ }
+ // Test if currentDir is platform/frameworks/base/tools/layoutlib. That is, root should be
+ // workingDir/../../../../ (4 levels up)
for (int i = 0; i < 4; i++) {
if (currentDir != null) {
currentDir = currentDir.getParentFile();
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java
index 3aa7cdf..f6c2626 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java
@@ -24,9 +24,11 @@ import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.ListIterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
@@ -86,7 +88,23 @@ public class AsmGenerator {
public AsmGenerator(Log log, String osDestJar, ICreateInfo createInfo) {
mLog = log;
mOsDestJar = osDestJar;
- mInjectClasses = createInfo.getInjectedClasses();
+ ArrayList<Class<?>> injectedClasses =
+ new ArrayList<Class<?>>(Arrays.asList(createInfo.getInjectedClasses()));
+ // Search for and add anonymous inner classes also.
+ ListIterator<Class<?>> iter = injectedClasses.listIterator();
+ while (iter.hasNext()) {
+ Class<?> clazz = iter.next();
+ try {
+ int i = 1;
+ while(i < 100) {
+ iter.add(Class.forName(clazz.getName() + "$" + i));
+ i++;
+ }
+ } catch (ClassNotFoundException ignored) {
+ // Expected.
+ }
+ }
+ mInjectClasses = injectedClasses.toArray(new Class<?>[0]);
mStubMethods = new HashSet<String>(Arrays.asList(createInfo.getOverriddenMethods()));
// Create the map/set of methods to change to delegates
@@ -290,13 +308,7 @@ public class AsmGenerator {
* e.g. it returns something like "com/foo/OuterClass$InnerClass1$InnerClass2.class"
*/
private String classToEntryPath(Class<?> clazz) {
- String name = "";
- Class<?> parent;
- while ((parent = clazz.getEnclosingClass()) != null) {
- name = "$" + clazz.getSimpleName() + name;
- clazz = parent;
- }
- return classNameToEntryPath(clazz.getCanonicalName() + name);
+ return classNameToEntryPath(clazz.getName());
}
/**
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
index deb94c4..499bea4 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
@@ -136,6 +136,8 @@ public final class CreateInfo implements ICreateInfo {
ICreateInfo.class,
CreateInfo.class,
LayoutlibDelegate.class,
+ InjectMethodRunnable.class,
+ InjectMethodRunnables.class,
/* Java package classes */
AutoCloseable.class,
Objects.class,
@@ -172,6 +174,7 @@ public final class CreateInfo implements ICreateInfo {
"android.view.Display#getWindowManager",
"android.view.LayoutInflater#rInflate",
"android.view.LayoutInflater#parseInclude",
+ "android.view.View#getWindowToken",
"android.view.View#isInEditMode",
"android.view.ViewRootImpl#isInTouchMode",
"android.view.WindowManagerGlobal#getWindowManagerService",
@@ -302,4 +305,3 @@ public final class CreateInfo implements ICreateInfo {
InjectMethodRunnables.CONTEXT_GET_FRAMEWORK_CLASS_LOADER);
}};
}
-
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ICreateInfo.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ICreateInfo.java
index ac10639..54b1fe6 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ICreateInfo.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ICreateInfo.java
@@ -85,6 +85,12 @@ public interface ICreateInfo {
Map<String, InjectMethodRunnable> getInjectedMethodsMap();
abstract class InjectMethodRunnable {
- public abstract void generateMethods(ClassVisitor cv);
+ /**
+ * @param cv Must be {@link ClassVisitor}. However, the param type is object so that when
+ * loading the class, ClassVisitor is not loaded. This is because when injecting
+ * CreateInfo in LayoutLib (see {@link #getInjectedClasses()}, we don't want to inject
+ * asm classes also, but still keep CreateInfo loadable.
+ */
+ public abstract void generateMethods(Object cv);
}
}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/InjectMethodRunnables.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/InjectMethodRunnables.java
index 39d46d7..37fc096 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/InjectMethodRunnables.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/InjectMethodRunnables.java
@@ -30,7 +30,9 @@ public class InjectMethodRunnables {
public static final ICreateInfo.InjectMethodRunnable CONTEXT_GET_FRAMEWORK_CLASS_LOADER
= new InjectMethodRunnable() {
@Override
- public void generateMethods(ClassVisitor cv) {
+ public void generateMethods(Object classVisitor) {
+ assert classVisitor instanceof ClassVisitor;
+ ClassVisitor cv = (ClassVisitor) classVisitor;
// generated by compiling the class:
// class foo { public ClassLoader getFrameworkClassLoader() { return getClass().getClassLoader(); } }
// and then running ASMifier on it: