summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Android.mk1
-rw-r--r--api/current.txt43
-rw-r--r--cmds/bootanimation/BootAnimation.cpp4
-rw-r--r--core/java/android/app/Activity.java2
-rw-r--r--core/java/android/app/VoiceInteractor.java262
-rw-r--r--core/java/android/app/WallpaperManager.java71
-rw-r--r--core/java/android/os/Build.java43
-rw-r--r--core/java/android/provider/Settings.java5
-rw-r--r--core/java/android/service/notification/StatusBarNotification.java2
-rw-r--r--core/java/android/service/voice/IVoiceInteractionSessionService.aidl28
-rw-r--r--core/java/android/service/voice/VoiceInteractionService.java8
-rw-r--r--core/java/android/service/voice/VoiceInteractionServiceInfo.java125
-rw-r--r--core/java/android/service/voice/VoiceInteractionSession.java4
-rw-r--r--core/java/android/service/voice/VoiceInteractionSessionService.java82
-rw-r--r--core/java/android/transition/Fade.java12
-rw-r--r--core/java/android/transition/Visibility.java3
-rw-r--r--core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl7
-rw-r--r--core/java/com/android/internal/app/IVoiceInteractorCallback.aidl2
-rw-r--r--core/res/res/values/attrs.xml1
-rw-r--r--core/res/res/values/public.xml16
-rw-r--r--graphics/java/android/graphics/drawable/TouchFeedbackDrawable.java45
-rw-r--r--packages/Keyguard/res/layout/keyguard_emergency_carrier_area.xml4
-rw-r--r--packages/Keyguard/res/values/attrs.xml4
-rw-r--r--packages/Keyguard/src/com/android/keyguard/CarrierText.java10
-rw-r--r--packages/SystemUI/res/layout/status_bar_expanded.xml9
-rw-r--r--packages/SystemUI/res/layout/status_bar_notification_keyguard_overflow.xml49
-rw-r--r--packages/SystemUI/res/layout/status_bar_notification_row.xml46
-rw-r--r--packages/SystemUI/res/values/dimens.xml9
-rw-r--r--packages/SystemUI/src/com/android/systemui/ExpandHelper.java65
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java (renamed from packages/SystemUI/src/com/android/systemui/statusbar/LatestItemView.java)28
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java19
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java62
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/InterceptedNotifications.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationOverflowContainer.java41
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java23
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java43
-rwxr-xr-xservices/core/java/com/android/server/pm/PackageManagerService.java2
-rw-r--r--services/core/java/com/android/server/wallpaper/WallpaperManagerService.java9
-rw-r--r--services/java/com/android/server/SystemServer.java5
-rw-r--r--services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java50
-rw-r--r--services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java169
-rw-r--r--tests/VoiceInteraction/AndroidManifest.xml6
-rw-r--r--tests/VoiceInteraction/res/xml/interaction_service.xml21
-rw-r--r--tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java3
-rw-r--r--tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java7
-rw-r--r--tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSessionService.java28
-rw-r--r--tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java22
52 files changed, 995 insertions, 534 deletions
diff --git a/Android.mk b/Android.mk
index 852247c..232f5bf 100644
--- a/Android.mk
+++ b/Android.mk
@@ -201,6 +201,7 @@ LOCAL_SRC_FILES += \
core/java/android/service/trust/ITrustAgentServiceCallback.aidl \
core/java/android/service/voice/IVoiceInteractionService.aidl \
core/java/android/service/voice/IVoiceInteractionSession.aidl \
+ core/java/android/service/voice/IVoiceInteractionSessionService.aidl \
core/java/android/service/wallpaper/IWallpaperConnection.aidl \
core/java/android/service/wallpaper/IWallpaperEngine.aidl \
core/java/android/service/wallpaper/IWallpaperService.aidl \
diff --git a/api/current.txt b/api/current.txt
index 4fef0d0..34b1ac8 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -1009,6 +1009,7 @@ package android {
field public static final int selectedDateVerticalBar = 16843591; // 0x1010347
field public static final int selectedWeekBackgroundColor = 16843586; // 0x1010342
field public static final int sequence = 16843815; // 0x1010427
+ field public static final int sessionService = 16843850; // 0x101044a
field public static final int settingsActivity = 16843301; // 0x1010225
field public static final int shadowColor = 16843105; // 0x1010161
field public static final int shadowDx = 16843106; // 0x1010162
@@ -1663,10 +1664,14 @@ package android {
field public static final int decelerate_cubic = 17563651; // 0x10c0003
field public static final int decelerate_quad = 17563649; // 0x10c0001
field public static final int decelerate_quint = 17563653; // 0x10c0005
- field public static final int fast_out_linear_in = 17563663; // 0x10c000f
- field public static final int fast_out_slow_in = 17563661; // 0x10c000d
+ field public static final int fast_out_linear_in = 17563667; // 0x10c0013
+ field public static final int fast_out_slow_in = 17563665; // 0x10c0011
+ field public static final int l_resource_pad1 = 17563664; // 0x10c0010
+ field public static final int l_resource_pad2 = 17563663; // 0x10c000f
+ field public static final int l_resource_pad3 = 17563662; // 0x10c000e
+ field public static final int l_resource_pad4 = 17563661; // 0x10c000d
field public static final int linear = 17563659; // 0x10c000b
- field public static final int linear_out_slow_in = 17563662; // 0x10c000e
+ field public static final int linear_out_slow_in = 17563666; // 0x10c0012
field public static final int overshoot = 17563656; // 0x10c0008
}
@@ -4842,20 +4847,26 @@ package android.app {
}
public class VoiceInteractor {
- method public android.app.VoiceInteractor.Request startCommand(android.app.VoiceInteractor.Callback, java.lang.String, android.os.Bundle);
- method public android.app.VoiceInteractor.Request startConfirmation(android.app.VoiceInteractor.Callback, java.lang.String, android.os.Bundle);
+ method public boolean submitRequest(android.app.VoiceInteractor.Request);
method public boolean[] supportsCommands(java.lang.String[]);
}
- public static class VoiceInteractor.Callback {
- ctor public VoiceInteractor.Callback();
- method public void onCancel(android.app.VoiceInteractor.Request);
- method public void onCommandResult(android.app.VoiceInteractor.Request, android.os.Bundle);
- method public void onConfirmationResult(android.app.VoiceInteractor.Request, boolean, android.os.Bundle);
+ public static class VoiceInteractor.CommandRequest extends android.app.VoiceInteractor.Request {
+ ctor public VoiceInteractor.CommandRequest(java.lang.String, android.os.Bundle);
+ method public void onCommandResult(android.os.Bundle);
}
- public static class VoiceInteractor.Request {
+ public static class VoiceInteractor.ConfirmationRequest extends android.app.VoiceInteractor.Request {
+ ctor public VoiceInteractor.ConfirmationRequest(java.lang.CharSequence, android.os.Bundle);
+ method public void onConfirmationResult(boolean, android.os.Bundle);
+ }
+
+ public static abstract class VoiceInteractor.Request {
+ ctor public VoiceInteractor.Request();
method public void cancel();
+ method public android.app.Activity getActivity();
+ method public android.content.Context getContext();
+ method public void onCancel();
}
public final class WallpaperInfo implements android.os.Parcelable {
@@ -24919,7 +24930,7 @@ package android.service.voice {
public class VoiceInteractionService extends android.app.Service {
ctor public VoiceInteractionService();
method public android.os.IBinder onBind(android.content.Intent);
- method public void startVoiceActivity(android.content.Intent, android.service.voice.VoiceInteractionSession);
+ method public void startVoiceActivity(android.content.Intent, android.os.Bundle);
field public static final java.lang.String SERVICE_INTERFACE = "android.service.voice.VoiceInteractionService";
field public static final java.lang.String SERVICE_META_DATA = "android.voice_interaction";
}
@@ -24938,10 +24949,16 @@ package android.service.voice {
public static class VoiceInteractionSession.Request {
method public void sendCancelResult();
- method public void sendCommandResult(android.os.Bundle);
+ method public void sendCommandResult(boolean, android.os.Bundle);
method public void sendConfirmResult(boolean, android.os.Bundle);
}
+ public abstract class VoiceInteractionSessionService extends android.app.Service {
+ ctor public VoiceInteractionSessionService();
+ method public android.os.IBinder onBind(android.content.Intent);
+ method public abstract android.service.voice.VoiceInteractionSession onNewSession(android.os.Bundle);
+ }
+
}
package android.service.wallpaper {
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index 41afa39..1780e03 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -51,6 +51,7 @@
#include "BootAnimation.h"
+#define OEM_BOOTANIMATION_FILE "/oem/media/bootanimation.zip"
#define SYSTEM_BOOTANIMATION_FILE "/system/media/bootanimation.zip"
#define SYSTEM_ENCRYPTED_BOOTANIMATION_FILE "/system/media/bootanimation-encrypted.zip"
#define EXIT_PROP_NAME "service.bootanim.exit"
@@ -283,6 +284,9 @@ status_t BootAnimation::readyToRun() {
(access(SYSTEM_ENCRYPTED_BOOTANIMATION_FILE, R_OK) == 0) &&
((zipFile = ZipFileRO::open(SYSTEM_ENCRYPTED_BOOTANIMATION_FILE)) != NULL)) ||
+ ((access(OEM_BOOTANIMATION_FILE, R_OK) == 0) &&
+ ((zipFile = ZipFileRO::open(OEM_BOOTANIMATION_FILE)) != NULL)) ||
+
((access(SYSTEM_BOOTANIMATION_FILE, R_OK) == 0) &&
((zipFile = ZipFileRO::open(SYSTEM_BOOTANIMATION_FILE)) != NULL))) {
mZip = zipFile;
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 197eaf8..8981c88 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -5454,7 +5454,7 @@ public class Activity extends ContextThemeWrapper
mEmbeddedID = id;
mLastNonConfigurationInstances = lastNonConfigurationInstances;
mVoiceInteractor = voiceInteractor != null
- ? new VoiceInteractor(this, voiceInteractor, Looper.myLooper()) : null;
+ ? new VoiceInteractor(this, this, voiceInteractor, Looper.myLooper()) : null;
mWindow.setWindowManager(
(WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
diff --git a/core/java/android/app/VoiceInteractor.java b/core/java/android/app/VoiceInteractor.java
index 6820dfd..6dc48b0 100644
--- a/core/java/android/app/VoiceInteractor.java
+++ b/core/java/android/app/VoiceInteractor.java
@@ -22,6 +22,7 @@ import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
+import android.util.ArrayMap;
import android.util.Log;
import com.android.internal.app.IVoiceInteractor;
import com.android.internal.app.IVoiceInteractorCallback;
@@ -39,50 +40,85 @@ public class VoiceInteractor {
static final boolean DEBUG = true;
final Context mContext;
+ final Activity mActivity;
final IVoiceInteractor mInteractor;
final HandlerCaller mHandlerCaller;
final HandlerCaller.Callback mHandlerCallerCallback = new HandlerCaller.Callback() {
@Override
public void executeMessage(Message msg) {
SomeArgs args = (SomeArgs)msg.obj;
+ Request request;
switch (msg.what) {
case MSG_CONFIRMATION_RESULT:
+ request = pullRequest((IVoiceInteractorRequest)args.arg1, true);
if (DEBUG) Log.d(TAG, "onConfirmResult: req="
- + ((IVoiceInteractorRequest)args.arg2).asBinder()
- + " confirmed=" + msg.arg1 + " result=" + args.arg3);
- ((Callback)args.arg1).onConfirmationResult(
- findRequest((IVoiceInteractorRequest)args.arg2),
- msg.arg1 != 0, (Bundle)args.arg3);
+ + ((IVoiceInteractorRequest)args.arg1).asBinder() + "/" + request
+ + " confirmed=" + msg.arg1 + " result=" + args.arg2);
+ if (request != null) {
+ ((ConfirmationRequest)request).onConfirmationResult(msg.arg1 != 0,
+ (Bundle) args.arg2);
+ request.clear();
+ }
break;
case MSG_COMMAND_RESULT:
+ request = pullRequest((IVoiceInteractorRequest)args.arg1, msg.arg1 != 0);
if (DEBUG) Log.d(TAG, "onCommandResult: req="
- + ((IVoiceInteractorRequest)args.arg2).asBinder()
+ + ((IVoiceInteractorRequest)args.arg1).asBinder() + "/" + request
+ " result=" + args.arg2);
- ((Callback)args.arg1).onCommandResult(
- findRequest((IVoiceInteractorRequest) args.arg2),
- (Bundle) args.arg3);
+ if (request != null) {
+ ((CommandRequest)request).onCommandResult((Bundle) args.arg2);
+ if (msg.arg1 != 0) {
+ request.clear();
+ }
+ }
break;
case MSG_CANCEL_RESULT:
+ request = pullRequest((IVoiceInteractorRequest)args.arg1, true);
if (DEBUG) Log.d(TAG, "onCancelResult: req="
- + ((IVoiceInteractorRequest)args.arg2).asBinder());
- ((Callback)args.arg1).onCancel(
- findRequest((IVoiceInteractorRequest) args.arg2));
+ + ((IVoiceInteractorRequest)args.arg1).asBinder() + "/" + request);
+ if (request != null) {
+ request.onCancel();
+ request.clear();
+ }
break;
}
}
};
- final WeakHashMap<IBinder, Request> mActiveRequests = new WeakHashMap<IBinder, Request>();
+ final IVoiceInteractorCallback.Stub mCallback = new IVoiceInteractorCallback.Stub() {
+ @Override
+ public void deliverConfirmationResult(IVoiceInteractorRequest request, boolean confirmed,
+ Bundle result) {
+ mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageIOO(
+ MSG_CONFIRMATION_RESULT, confirmed ? 1 : 0, request, result));
+ }
+
+ @Override
+ public void deliverCommandResult(IVoiceInteractorRequest request, boolean complete,
+ Bundle result) {
+ mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageIOO(
+ MSG_COMMAND_RESULT, complete ? 1 : 0, request, result));
+ }
+
+ @Override
+ public void deliverCancel(IVoiceInteractorRequest request) throws RemoteException {
+ mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageO(
+ MSG_CANCEL_RESULT, request));
+ }
+ };
+
+ final ArrayMap<IBinder, Request> mActiveRequests = new ArrayMap<IBinder, Request>();
static final int MSG_CONFIRMATION_RESULT = 1;
static final int MSG_COMMAND_RESULT = 2;
static final int MSG_CANCEL_RESULT = 3;
- public static class Request {
- final IVoiceInteractorRequest mRequestInterface;
+ public static abstract class Request {
+ IVoiceInteractorRequest mRequestInterface;
+ Context mContext;
+ Activity mActivity;
- Request(IVoiceInteractorRequest requestInterface) {
- mRequestInterface = requestInterface;
+ public Request() {
}
public void cancel() {
@@ -92,126 +128,130 @@ public class VoiceInteractor {
Log.w(TAG, "Voice interactor has died", e);
}
}
+
+ public Context getContext() {
+ return mContext;
+ }
+
+ public Activity getActivity() {
+ return mActivity;
+ }
+
+ public void onCancel() {
+ }
+
+ void clear() {
+ mRequestInterface = null;
+ mContext = null;
+ mActivity = null;
+ }
+
+ abstract IVoiceInteractorRequest submit(IVoiceInteractor interactor,
+ String packageName, IVoiceInteractorCallback callback) throws RemoteException;
}
- public static class Callback {
- VoiceInteractor mInteractor;
+ public static class ConfirmationRequest extends Request {
+ final CharSequence mPrompt;
+ final Bundle mExtras;
- final IVoiceInteractorCallback.Stub mWrapper = new IVoiceInteractorCallback.Stub() {
- @Override
- public void deliverConfirmationResult(IVoiceInteractorRequest request, boolean confirmed,
- Bundle result) {
- mInteractor.mHandlerCaller.sendMessage(mInteractor.mHandlerCaller.obtainMessageIOOO(
- MSG_CONFIRMATION_RESULT, confirmed ? 1 : 0, Callback.this, request,
- result));
- }
+ /**
+ * Confirms an operation with the user via the trusted system
+ * VoiceInteractionService. This allows an Activity to complete an unsafe operation that
+ * would require the user to touch the screen when voice interaction mode is not enabled.
+ * The result of the confirmation will be returned through an asynchronous call to
+ * either {@link #onConfirmationResult(boolean, android.os.Bundle)} or
+ * {@link #onCancel()}.
+ *
+ * <p>In some cases this may be a simple yes / no confirmation or the confirmation could
+ * include context information about how the action will be completed
+ * (e.g. booking a cab might include details about how long until the cab arrives)
+ * so the user can give a confirmation.
+ * @param prompt Optional confirmation text to read to the user as the action being
+ * confirmed.
+ * @param extras Additional optional information.
+ */
+ public ConfirmationRequest(CharSequence prompt, Bundle extras) {
+ mPrompt = prompt;
+ mExtras = extras;
+ }
- @Override
- public void deliverCommandResult(IVoiceInteractorRequest request, Bundle result) {
- mInteractor.mHandlerCaller.sendMessage(mInteractor.mHandlerCaller.obtainMessageOOO(
- MSG_COMMAND_RESULT, Callback.this, request, result));
- }
+ public void onConfirmationResult(boolean confirmed, Bundle result) {
+ }
- @Override
- public void deliverCancel(IVoiceInteractorRequest request) throws RemoteException {
- mInteractor.mHandlerCaller.sendMessage(mInteractor.mHandlerCaller.obtainMessageOO(
- MSG_CANCEL_RESULT, Callback.this, request));
- }
- };
+ IVoiceInteractorRequest submit(IVoiceInteractor interactor, String packageName,
+ IVoiceInteractorCallback callback) throws RemoteException {
+ return interactor.startConfirmation(packageName, callback, mPrompt.toString(), mExtras);
+ }
+ }
- public void onConfirmationResult(Request request, boolean confirmed, Bundle result) {
+ public static class CommandRequest extends Request {
+ final String mCommand;
+ final Bundle mArgs;
+
+ /**
+ * Execute a command using the trusted system VoiceInteractionService.
+ * This allows an Activity to request additional information from the user needed to
+ * complete an action (e.g. booking a table might have several possible times that the
+ * user could select from or an app might need the user to agree to a terms of service).
+ * The result of the confirmation will be returned through an asynchronous call to
+ * either {@link #onCommandResult(android.os.Bundle)} or
+ * {@link #onCancel()}.
+ *
+ * <p>The command is a string that describes the generic operation to be performed.
+ * The command will determine how the properties in extras are interpreted and the set of
+ * available commands is expected to grow over time. An example might be
+ * "com.google.voice.commands.REQUEST_NUMBER_BAGS" to request the number of bags as part of
+ * airline check-in. (This is not an actual working example.)
+ *
+ * @param command The desired command to perform.
+ * @param args Additional arguments to control execution of the command.
+ */
+ public CommandRequest(String command, Bundle args) {
+ mCommand = command;
+ mArgs = args;
}
- public void onCommandResult(Request request, Bundle result) {
+ public void onCommandResult(Bundle result) {
}
- public void onCancel(Request request) {
+ IVoiceInteractorRequest submit(IVoiceInteractor interactor, String packageName,
+ IVoiceInteractorCallback callback) throws RemoteException {
+ return interactor.startConfirmation(packageName, callback, mCommand, mArgs);
}
- }
+ }
- VoiceInteractor(Context context, IVoiceInteractor interactor, Looper looper) {
+ VoiceInteractor(Context context, Activity activity, IVoiceInteractor interactor,
+ Looper looper) {
mContext = context;
+ mActivity = activity;
mInteractor = interactor;
mHandlerCaller = new HandlerCaller(context, looper, mHandlerCallerCallback, true);
}
- Request storeRequest(IVoiceInteractorRequest request) {
- synchronized (mActiveRequests) {
- Request req = new Request(request);
- mActiveRequests.put(request.asBinder(), req);
- return req;
- }
- }
-
- Request findRequest(IVoiceInteractorRequest request) {
+ Request pullRequest(IVoiceInteractorRequest request, boolean complete) {
synchronized (mActiveRequests) {
Request req = mActiveRequests.get(request.asBinder());
- if (req == null) {
- throw new IllegalStateException("Received callback without active request: "
- + request);
+ if (req != null && complete) {
+ mActiveRequests.remove(request.asBinder());
}
return req;
}
}
- /**
- * Asynchronously confirms an operation with the user via the trusted system
- * VoiceinteractionService. This allows an Activity to complete an unsafe operation that
- * would require the user to touch the screen when voice interaction mode is not enabled.
- * The result of the confirmation will be returned by calling the
- * {@link Callback#onConfirmationResult Callback.onConfirmationResult} method.
- *
- * In some cases this may be a simple yes / no confirmation or the confirmation could
- * include context information about how the action will be completed
- * (e.g. booking a cab might include details about how long until the cab arrives) so the user
- * can give informed consent.
- * @param callback Required callback target for interaction results.
- * @param prompt Optional confirmation text to read to the user as the action being confirmed.
- * @param extras Additional optional information.
- * @return Returns a new {@link Request} object representing this operation.
- */
- public Request startConfirmation(Callback callback, String prompt, Bundle extras) {
+ public boolean submitRequest(Request request) {
try {
- callback.mInteractor = this;
- Request req = storeRequest(mInteractor.startConfirmation(
- mContext.getOpPackageName(), callback.mWrapper, prompt, extras));
- if (DEBUG) Log.d(TAG, "startConfirmation: req=" + req.mRequestInterface.asBinder()
- + " prompt=" + prompt + " extras=" + extras);
- return req;
- } catch (RemoteException e) {
- throw new RuntimeException("Voice interactor has died", e);
- }
- }
-
- /**
- * Asynchronously executes a command using the trusted system VoiceinteractionService.
- * This allows an Activity to request additional information from the user needed to
- * complete an action (e.g. booking a table might have several possible times that the
- * user could select from or an app might need the user to agree to a terms of service).
- *
- * The command is a string that describes the generic operation to be performed.
- * The command will determine how the properties in extras are interpreted and the set of
- * available commands is expected to grow over time. An example might be
- * "com.google.voice.commands.REQUEST_NUMBER_BAGS" to request the number of bags as part of
- * airline check-in. (This is not an actual working example.)
- * The result of the command will be returned by calling the
- * {@link Callback#onCommandResult Callback.onCommandResult} method.
- *
- * @param callback Required callback target for interaction results.
- * @param command
- * @param extras
- * @return Returns a new {@link Request} object representing this operation.
- */
- public Request startCommand(Callback callback, String command, Bundle extras) {
- try {
- callback.mInteractor = this;
- Request req = storeRequest(mInteractor.startCommand(
- mContext.getOpPackageName(), callback.mWrapper, command, extras));
- if (DEBUG) Log.d(TAG, "startCommand: req=" + req.mRequestInterface.asBinder()
- + " command=" + command + " extras=" + extras);
- return req;
+ IVoiceInteractorRequest ireq = request.submit(mInteractor,
+ mContext.getOpPackageName(), mCallback);
+ request.mRequestInterface = ireq;
+ request.mContext = mContext;
+ request.mActivity = mActivity;
+ synchronized (mActiveRequests) {
+ mActiveRequests.put(ireq.asBinder(), request);
+ }
+ return true;
} catch (RemoteException e) {
- throw new RuntimeException("Voice interactor has died", e);
+ Log.w(TAG, "Remove voice interactor service died", e);
+ return false;
}
}
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index e6e0f35..f08097b 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -16,6 +16,7 @@
package android.app;
+import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
@@ -44,10 +45,14 @@ import android.os.Looper;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.SystemProperties;
+import android.text.TextUtils;
import android.util.Log;
import android.view.WindowManagerGlobal;
import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -65,6 +70,11 @@ public class WallpaperManager {
private float mWallpaperXStep = -1;
private float mWallpaperYStep = -1;
+ /** {@hide} */
+ private static final String PROP_WALLPAPER = "ro.config.wallpaper";
+ /** {@hide} */
+ private static final String PROP_WALLPAPER_COMPONENT = "ro.config.wallpaper_component";
+
/**
* Activity Action: Show settings for choosing wallpaper. Do not use directly to construct
* an intent; instead, use {@link #getCropAndSetWallpaperIntent}.
@@ -298,8 +308,7 @@ public class WallpaperManager {
private Bitmap getDefaultWallpaperLocked(Context context) {
try {
- InputStream is = context.getResources().openRawResource(
- com.android.internal.R.drawable.default_wallpaper);
+ InputStream is = openDefaultWallpaper(context);
if (is != null) {
int width = mService.getWidthHint();
int height = mService.getHeightHint();
@@ -403,8 +412,7 @@ public class WallpaperManager {
horizontalAlignment = Math.max(0, Math.min(1, horizontalAlignment));
verticalAlignment = Math.max(0, Math.min(1, verticalAlignment));
- InputStream is = new BufferedInputStream(
- resources.openRawResource(com.android.internal.R.drawable.default_wallpaper));
+ InputStream is = new BufferedInputStream(openDefaultWallpaper(mContext));
if (is == null) {
Log.e(TAG, "default wallpaper input stream is null");
@@ -429,8 +437,7 @@ public class WallpaperManager {
}
}
- is = new BufferedInputStream(resources.openRawResource(
- com.android.internal.R.drawable.default_wallpaper));
+ is = new BufferedInputStream(openDefaultWallpaper(mContext));
RectF cropRectF;
@@ -479,8 +486,7 @@ public class WallpaperManager {
if (crop == null) {
// BitmapRegionDecoder has failed, try to crop in-memory
- is = new BufferedInputStream(resources.openRawResource(
- com.android.internal.R.drawable.default_wallpaper));
+ is = new BufferedInputStream(openDefaultWallpaper(mContext));
Bitmap fullSize = null;
if (is != null) {
BitmapFactory.Options options = new BitmapFactory.Options();
@@ -1009,6 +1015,53 @@ public class WallpaperManager {
* wallpaper.
*/
public void clear() throws IOException {
- setResource(com.android.internal.R.drawable.default_wallpaper);
+ setStream(openDefaultWallpaper(mContext));
+ }
+
+ /**
+ * Open stream representing the default static image wallpaper.
+ *
+ * @hide
+ */
+ public static InputStream openDefaultWallpaper(Context context) {
+ final String path = SystemProperties.get(PROP_WALLPAPER);
+ if (!TextUtils.isEmpty(path)) {
+ final File file = new File(path);
+ if (file.exists()) {
+ try {
+ return new FileInputStream(file);
+ } catch (IOException e) {
+ // Ignored, fall back to platform default below
+ }
+ }
+ }
+ return context.getResources().openRawResource(
+ com.android.internal.R.drawable.default_wallpaper);
+ }
+
+ /**
+ * Return {@link ComponentName} of the default live wallpaper, or
+ * {@code null} if none is defined.
+ *
+ * @hide
+ */
+ public static ComponentName getDefaultWallpaperComponent(Context context) {
+ String flat = SystemProperties.get(PROP_WALLPAPER_COMPONENT);
+ if (!TextUtils.isEmpty(flat)) {
+ final ComponentName cn = ComponentName.unflattenFromString(flat);
+ if (cn != null) {
+ return cn;
+ }
+ }
+
+ flat = context.getString(com.android.internal.R.string.default_wallpaper_component);
+ if (!TextUtils.isEmpty(flat)) {
+ final ComponentName cn = ComponentName.unflattenFromString(flat);
+ if (cn != null) {
+ return cn;
+ }
+ }
+
+ return null;
}
}
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 11e3795..0336dd6 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -16,12 +16,17 @@
package android.os;
+import android.text.TextUtils;
+import android.util.Slog;
+
import com.android.internal.telephony.TelephonyProperties;
/**
* Information about the current build, extracted from system properties.
*/
public class Build {
+ private static final String TAG = "Build";
+
/** Value used for when a build property is unknown. */
public static final String UNKNOWN = "unknown";
@@ -509,7 +514,43 @@ public class Build {
public static final String TAGS = getString("ro.build.tags");
/** A string that uniquely identifies this build. Do not attempt to parse this value. */
- public static final String FINGERPRINT = getString("ro.build.fingerprint");
+ public static final String FINGERPRINT = deriveFingerprint();
+
+ /**
+ * Some devices split the fingerprint components between multiple
+ * partitions, so we might derive the fingerprint at runtime.
+ */
+ private static String deriveFingerprint() {
+ String finger = SystemProperties.get("ro.build.fingerprint");
+ if (TextUtils.isEmpty(finger)) {
+ finger = getString("ro.product.brand") + '/' +
+ getString("ro.product.name") + '/' +
+ getString("ro.product.device") + ':' +
+ getString("ro.build.version.release") + '/' +
+ getString("ro.build.id") + '/' +
+ getString("ro.build.version.incremental") + ':' +
+ getString("ro.build.type") + '/' +
+ getString("ro.build.tags");
+ }
+ return finger;
+ }
+
+ /**
+ * Ensure that raw fingerprint system property is defined. If it was derived
+ * dynamically by {@link #deriveFingerprint()} this is where we push the
+ * derived value into the property service.
+ *
+ * @hide
+ */
+ public static void ensureFingerprintProperty() {
+ if (TextUtils.isEmpty(SystemProperties.get("ro.build.fingerprint"))) {
+ try {
+ SystemProperties.set("ro.build.fingerprint", FINGERPRINT);
+ } catch (IllegalArgumentException e) {
+ Slog.e(TAG, "Failed to set fingerprint property", e);
+ }
+ }
+ }
// The following properties only make sense for internal engineering builds.
public static final long TIME = getLong("ro.build.date.utc") * 1000;
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index b578b48..ab06230 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -764,6 +764,11 @@ public final class Settings {
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
public static final String ACTION_ZEN_MODE_SETTINGS = "android.settings.ZEN_MODE_SETTINGS";
+ /** {@hide} */
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String
+ ACTION_SHOW_REGULATORY_INFO = "android.settings.SHOW_REGULATORY_INFO";
+
// End of Intent actions for Settings
/**
diff --git a/core/java/android/service/notification/StatusBarNotification.java b/core/java/android/service/notification/StatusBarNotification.java
index 2c0b76d..72720d1 100644
--- a/core/java/android/service/notification/StatusBarNotification.java
+++ b/core/java/android/service/notification/StatusBarNotification.java
@@ -87,7 +87,7 @@ public class StatusBarNotification implements Parcelable {
}
private String key() {
- return pkg + '|' + opPkg + '|' + id + '|' + tag + '|' + uid;
+ return pkg + '|' + id + '|' + tag + '|' + uid;
}
public void writeToParcel(Parcel out, int flags) {
diff --git a/core/java/android/service/voice/IVoiceInteractionSessionService.aidl b/core/java/android/service/voice/IVoiceInteractionSessionService.aidl
new file mode 100644
index 0000000..2519442
--- /dev/null
+++ b/core/java/android/service/voice/IVoiceInteractionSessionService.aidl
@@ -0,0 +1,28 @@
+/*
+ * 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.service.voice;
+
+import android.os.Bundle;
+
+import android.service.voice.IVoiceInteractionSession;
+
+/**
+ * @hide
+ */
+oneway interface IVoiceInteractionSessionService {
+ void newSession(IBinder token, in Bundle args);
+}
diff --git a/core/java/android/service/voice/VoiceInteractionService.java b/core/java/android/service/voice/VoiceInteractionService.java
index ed93b74..d005890 100644
--- a/core/java/android/service/voice/VoiceInteractionService.java
+++ b/core/java/android/service/voice/VoiceInteractionService.java
@@ -21,6 +21,7 @@ import android.app.Instrumentation;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
+import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -50,12 +51,11 @@ public class VoiceInteractionService extends Service {
IVoiceInteractionManagerService mSystemService;
- public void startVoiceActivity(Intent intent, VoiceInteractionSession session) {
+ public void startVoiceActivity(Intent intent, Bundle sessionArgs) {
try {
- int res = mSystemService.startVoiceActivity(intent,
+ mSystemService.startVoiceActivity(intent,
intent.resolveType(getContentResolver()),
- mInterface, session.mSession, session.mInteractor);
- Instrumentation.checkStartActivityResult(res, intent);
+ mInterface, sessionArgs);
} catch (RemoteException e) {
}
}
diff --git a/core/java/android/service/voice/VoiceInteractionServiceInfo.java b/core/java/android/service/voice/VoiceInteractionServiceInfo.java
new file mode 100644
index 0000000..a909ead
--- /dev/null
+++ b/core/java/android/service/voice/VoiceInteractionServiceInfo.java
@@ -0,0 +1,125 @@
+/*
+ * 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.service.voice;
+
+import android.Manifest;
+import android.content.ComponentName;
+import android.content.pm.PackageManager;
+import android.content.pm.ServiceInfo;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.content.res.XmlResourceParser;
+import android.speech.RecognitionService;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.Xml;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+
+/** @hide */
+public class VoiceInteractionServiceInfo {
+ static final String TAG = "VoiceInteractionServiceInfo";
+
+ private String mParseError;
+
+ private ServiceInfo mServiceInfo;
+ private String mSessionService;
+ private String mSettingsActivity;
+
+ public VoiceInteractionServiceInfo(PackageManager pm, ComponentName comp)
+ throws PackageManager.NameNotFoundException {
+ this(pm, pm.getServiceInfo(comp, PackageManager.GET_META_DATA));
+ }
+
+ public VoiceInteractionServiceInfo(PackageManager pm, ServiceInfo si) {
+ if (!Manifest.permission.BIND_VOICE_INTERACTION.equals(si.permission)) {
+ mParseError = "Service does not require permission "
+ + Manifest.permission.BIND_VOICE_INTERACTION;
+ return;
+ }
+
+ XmlResourceParser parser = null;
+ try {
+ parser = si.loadXmlMetaData(pm, VoiceInteractionService.SERVICE_META_DATA);
+ if (parser == null) {
+ mParseError = "No " + VoiceInteractionService.SERVICE_META_DATA
+ + " meta-data for " + si.packageName;
+ return;
+ }
+
+ Resources res = pm.getResourcesForApplication(si.applicationInfo);
+
+ AttributeSet attrs = Xml.asAttributeSet(parser);
+
+ int type;
+ while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
+ && type != XmlPullParser.START_TAG) {
+ }
+
+ String nodeName = parser.getName();
+ if (!"voice-interaction-service".equals(nodeName)) {
+ mParseError = "Meta-data does not start with voice-interaction-service tag";
+ return;
+ }
+
+ TypedArray array = res.obtainAttributes(attrs,
+ com.android.internal.R.styleable.VoiceInteractionService);
+ mSessionService = array.getString(
+ com.android.internal.R.styleable.VoiceInteractionService_sessionService);
+ mSettingsActivity = array.getString(
+ com.android.internal.R.styleable.VoiceInteractionService_settingsActivity);
+ array.recycle();
+ if (mSessionService == null) {
+ mParseError = "No sessionService specified";
+ return;
+ }
+ } catch (XmlPullParserException e) {
+ mParseError = "Error parsing voice interation service meta-data: " + e;
+ Log.w(TAG, "error parsing voice interaction service meta-data", e);
+ return;
+ } catch (IOException e) {
+ mParseError = "Error parsing voice interation service meta-data: " + e;
+ Log.w(TAG, "error parsing voice interaction service meta-data", e);
+ return;
+ } catch (PackageManager.NameNotFoundException e) {
+ mParseError = "Error parsing voice interation service meta-data: " + e;
+ Log.w(TAG, "error parsing voice interaction service meta-data", e);
+ return;
+ } finally {
+ if (parser != null) parser.close();
+ }
+ mServiceInfo = si;
+ }
+
+ public String getParseError() {
+ return mParseError;
+ }
+
+ public ServiceInfo getServiceInfo() {
+ return mServiceInfo;
+ }
+
+ public String getSessionService() {
+ return mSessionService;
+ }
+
+ public String getSettingsActivity() {
+ return mSettingsActivity;
+ }
+}
diff --git a/core/java/android/service/voice/VoiceInteractionSession.java b/core/java/android/service/voice/VoiceInteractionSession.java
index 59544be..963b6b4 100644
--- a/core/java/android/service/voice/VoiceInteractionSession.java
+++ b/core/java/android/service/voice/VoiceInteractionSession.java
@@ -96,11 +96,11 @@ public abstract class VoiceInteractionSession {
}
}
- public void sendCommandResult(Bundle result) {
+ public void sendCommandResult(boolean complete, Bundle result) {
try {
if (DEBUG) Log.d(TAG, "sendCommandResult: req=" + mInterface
+ " result=" + result);
- mCallback.deliverCommandResult(mInterface, result);
+ mCallback.deliverCommandResult(mInterface, complete, result);
} catch (RemoteException e) {
}
}
diff --git a/core/java/android/service/voice/VoiceInteractionSessionService.java b/core/java/android/service/voice/VoiceInteractionSessionService.java
new file mode 100644
index 0000000..40e5bba
--- /dev/null
+++ b/core/java/android/service/voice/VoiceInteractionSessionService.java
@@ -0,0 +1,82 @@
+/**
+ * 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.service.voice;
+
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import com.android.internal.app.IVoiceInteractionManagerService;
+import com.android.internal.os.HandlerCaller;
+import com.android.internal.os.SomeArgs;
+
+public abstract class VoiceInteractionSessionService extends Service {
+
+ static final int MSG_NEW_SESSION = 1;
+
+ IVoiceInteractionManagerService mSystemService;
+
+ IVoiceInteractionSessionService mInterface = new IVoiceInteractionSessionService.Stub() {
+ public void newSession(IBinder token, Bundle args) {
+ mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageOO(MSG_NEW_SESSION,
+ token, args));
+
+ }
+ };
+
+ HandlerCaller mHandlerCaller;
+ final HandlerCaller.Callback mHandlerCallerCallback = new HandlerCaller.Callback() {
+ @Override
+ public void executeMessage(Message msg) {
+ SomeArgs args = (SomeArgs)msg.obj;
+ switch (msg.what) {
+ case MSG_NEW_SESSION:
+ doNewSession((IBinder)args.arg1, (Bundle)args.arg2);
+ break;
+ }
+ }
+ };
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ mSystemService = IVoiceInteractionManagerService.Stub.asInterface(
+ ServiceManager.getService(Context.VOICE_INTERACTION_MANAGER_SERVICE));
+ mHandlerCaller = new HandlerCaller(this, Looper.myLooper(),
+ mHandlerCallerCallback, true);
+ }
+
+ public abstract VoiceInteractionSession onNewSession(Bundle args);
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return mInterface.asBinder();
+ }
+
+ void doNewSession(IBinder token, Bundle args) {
+ VoiceInteractionSession session = onNewSession(args);
+ try {
+ mSystemService.deliverNewSession(token, session.mSession, session.mInteractor);
+ } catch (RemoteException e) {
+ }
+ }
+}
diff --git a/core/java/android/transition/Fade.java b/core/java/android/transition/Fade.java
index 08e27d3..e70dc0c 100644
--- a/core/java/android/transition/Fade.java
+++ b/core/java/android/transition/Fade.java
@@ -105,7 +105,7 @@ public class Fade extends Visibility {
if (DBG) {
Log.d(LOG_TAG, "Created animator " + anim);
}
- FadeAnimatorListener listener = new FadeAnimatorListener(view, endAlpha);
+ FadeAnimatorListener listener = new FadeAnimatorListener(view);
anim.addListener(listener);
anim.addPauseListener(listener);
return anim;
@@ -138,13 +138,11 @@ public class Fade extends Visibility {
private static class FadeAnimatorListener extends AnimatorListenerAdapter {
private final View mView;
- private final float mEndAlpha;
private boolean mCanceled = false;
- private float mPausedAlpha;
+ private float mPausedAlpha = -1;
- public FadeAnimatorListener(View view, float endAlpha) {
+ public FadeAnimatorListener(View view) {
mView = view;
- mEndAlpha = endAlpha;
}
@Override
@@ -158,14 +156,14 @@ public class Fade extends Visibility {
@Override
public void onAnimationEnd(Animator animator) {
if (!mCanceled) {
- mView.setTransitionAlpha(mEndAlpha);
+ mView.setTransitionAlpha(1);
}
}
@Override
public void onAnimationPause(Animator animator) {
mPausedAlpha = mView.getTransitionAlpha();
- mView.setTransitionAlpha(mEndAlpha);
+ mView.setTransitionAlpha(1);
}
@Override
diff --git a/core/java/android/transition/Visibility.java b/core/java/android/transition/Visibility.java
index 526803a..6e6496c 100644
--- a/core/java/android/transition/Visibility.java
+++ b/core/java/android/transition/Visibility.java
@@ -347,10 +347,11 @@ public abstract class Visibility extends Transition {
}
if (viewToKeep != null) {
+ int originalVisibility = viewToKeep.getVisibility();
viewToKeep.setVisibility(View.VISIBLE);
Animator animator = onDisappear(sceneRoot, viewToKeep, startValues, endValues);
if (animator == null) {
- viewToKeep.setVisibility(finalVisibility);
+ viewToKeep.setVisibility(originalVisibility);
} else {
final View finalViewToKeep = viewToKeep;
animator.addListener(new AnimatorListenerAdapter() {
diff --git a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
index e3c0728..3219ddd 100644
--- a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
+++ b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
@@ -17,12 +17,15 @@
package com.android.internal.app;
import android.content.Intent;
+import android.os.Bundle;
import com.android.internal.app.IVoiceInteractor;
import android.service.voice.IVoiceInteractionService;
import android.service.voice.IVoiceInteractionSession;
interface IVoiceInteractionManagerService {
- int startVoiceActivity(in Intent intent, String resolvedType, IVoiceInteractionService service,
- IVoiceInteractionSession session, IVoiceInteractor interactor);
+ void startVoiceActivity(in Intent intent, String resolvedType, IVoiceInteractionService service,
+ in Bundle sessionArgs);
+ int deliverNewSession(IBinder token, IVoiceInteractionSession session,
+ IVoiceInteractor interactor);
}
diff --git a/core/java/com/android/internal/app/IVoiceInteractorCallback.aidl b/core/java/com/android/internal/app/IVoiceInteractorCallback.aidl
index f5392e9..c6f93e1 100644
--- a/core/java/com/android/internal/app/IVoiceInteractorCallback.aidl
+++ b/core/java/com/android/internal/app/IVoiceInteractorCallback.aidl
@@ -26,6 +26,6 @@ import com.android.internal.app.IVoiceInteractorRequest;
oneway interface IVoiceInteractorCallback {
void deliverConfirmationResult(IVoiceInteractorRequest request, boolean confirmed,
in Bundle result);
- void deliverCommandResult(IVoiceInteractorRequest request, in Bundle result);
+ void deliverCommandResult(IVoiceInteractorRequest request, boolean complete, in Bundle result);
void deliverCancel(IVoiceInteractorRequest request);
}
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 326485d..69440be 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -6279,6 +6279,7 @@
its {@link android.service.voice.VoiceInteractionService#SERVICE_META_DATA} meta-data entry.
Described here are the attributes that can be included in that tag. -->
<declare-styleable name="VoiceInteractionService">
+ <attr name="sessionService" format="string" />
<attr name="settingsActivity" />
</declare-styleable>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 6491b33..085b9c3 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2155,6 +2155,13 @@
<public type="attr" name="colorPrimaryDark" />
<public type="attr" name="colorAccent" />
<public type="attr" name="nestedScrollingEnabled" />
+ <public type="attr" name="windowEnterTransition" />
+ <public type="attr" name="windowExitTransition" />
+ <public type="attr" name="windowSharedElementEnterTransition" />
+ <public type="attr" name="windowSharedElementExitTransition" />
+ <public type="attr" name="windowAllowExitTransitionOverlap" />
+ <public type="attr" name="windowAllowEnterTransitionOverlap" />
+ <public type="attr" name="sessionService" />
<public-padding type="dimen" name="l_resource_pad" end="0x01050010" />
@@ -2385,17 +2392,14 @@
<public type="style" name="Widget.Holo.Light.Button.Borderless" />
+ <public-padding type="interpolator" name="l_resource_pad" end="0x010c0010" />
+
<!-- An interpolator which accelerates fast but decelerates slowly. -->
<public type="interpolator" name="fast_out_slow_in" />
<!-- An interpolator which starts with a peak non-zero velocity and decelerates slowly. -->
<public type="interpolator" name="linear_out_slow_in" />
<!-- An interpolator which accelerates fast and keeps accelerating until the end. -->
<public type="interpolator" name="fast_out_linear_in" />
- <public type="attr" name="windowEnterTransition" />
- <public type="attr" name="windowExitTransition" />
- <public type="attr" name="windowSharedElementEnterTransition" />
- <public type="attr" name="windowSharedElementExitTransition" />
- <public type="attr" name="windowAllowExitTransitionOverlap" />
- <public type="attr" name="windowAllowEnterTransitionOverlap" />
+
<public type="transition" name="no_transition" id="0x010f0000"/>
</resources>
diff --git a/graphics/java/android/graphics/drawable/TouchFeedbackDrawable.java b/graphics/java/android/graphics/drawable/TouchFeedbackDrawable.java
index 824e108..0e8831f 100644
--- a/graphics/java/android/graphics/drawable/TouchFeedbackDrawable.java
+++ b/graphics/java/android/graphics/drawable/TouchFeedbackDrawable.java
@@ -501,10 +501,32 @@ public class TouchFeedbackDrawable extends LayerDrawable {
}
private int drawRippleLayer(Canvas canvas, Rect bounds, boolean maskOnly) {
- final Ripple[] activeRipples = mActiveRipples;
final int ripplesCount = mActiveRipplesCount;
+ if (ripplesCount == 0) {
+ return -1;
+ }
+
+ final Ripple[] activeRipples = mActiveRipples;
+ final boolean projected = isProjected();
+ final Rect layerBounds = projected ? getDirtyBounds() : bounds;
+
+ // Separate the ripple color and alpha channel. The alpha will be
+ // applied when we merge the ripples down to the canvas.
+ final int rippleColor;
+ if (mState.mTint != null) {
+ rippleColor = mState.mTint.getColorForState(getState(), Color.TRANSPARENT);
+ } else {
+ rippleColor = Color.TRANSPARENT;
+ }
+ final int rippleAlpha = Color.alpha(rippleColor);
+
+ if (mRipplePaint == null) {
+ mRipplePaint = new Paint();
+ mRipplePaint.setAntiAlias(true);
+ }
+ final Paint ripplePaint = mRipplePaint;
+ ripplePaint.setColor(rippleColor);
- Paint ripplePaint = null;
boolean drewRipples = false;
int restoreToCount = -1;
int activeRipplesCount = 0;
@@ -524,20 +546,9 @@ public class TouchFeedbackDrawable extends LayerDrawable {
// If we're masking the ripple layer, make sure we have a layer
// first. This will merge SRC_OVER (directly) onto the canvas.
if (restoreToCount < 0) {
- // Separate the ripple color and alpha channel. The alpha will be
- // applied when we merge the ripples down to the canvas.
- final int rippleColor;
- if (mState.mTint != null) {
- rippleColor = mState.mTint.getColorForState(getState(), Color.TRANSPARENT);
- } else {
- rippleColor = Color.TRANSPARENT;
- }
- final int rippleAlpha = Color.alpha(rippleColor);
-
// If we're projecting or we only have a mask, we want to treat the
// underlying canvas as our content and merge the ripple layer down
// using the tint xfermode.
- final boolean projected = isProjected();
final PorterDuffXfermode xfermode;
if (projected || maskOnly) {
xfermode = mState.getTintXfermode();
@@ -547,18 +558,12 @@ public class TouchFeedbackDrawable extends LayerDrawable {
final Paint layerPaint = getMaskingPaint(xfermode);
layerPaint.setAlpha(rippleAlpha);
- final Rect layerBounds = projected ? getDirtyBounds() : bounds;
restoreToCount = canvas.saveLayer(layerBounds.left, layerBounds.top,
layerBounds.right, layerBounds.bottom, layerPaint);
layerPaint.setAlpha(255);
}
- if (mRipplePaint == null) {
- mRipplePaint = new Paint();
- mRipplePaint.setAntiAlias(true);
- }
-
- drewRipples |= ripple.draw(canvas, mRipplePaint);
+ drewRipples |= ripple.draw(canvas, ripplePaint);
activeRipples[activeRipplesCount] = activeRipples[i];
activeRipplesCount++;
diff --git a/packages/Keyguard/res/layout/keyguard_emergency_carrier_area.xml b/packages/Keyguard/res/layout/keyguard_emergency_carrier_area.xml
index b4847f0..b2d0219 100644
--- a/packages/Keyguard/res/layout/keyguard_emergency_carrier_area.xml
+++ b/packages/Keyguard/res/layout/keyguard_emergency_carrier_area.xml
@@ -20,6 +20,7 @@
<!-- This contains emergency call button and carrier as shared by pin/pattern/password screens -->
<com.android.keyguard.EmergencyCarrierArea
xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
@@ -35,7 +36,8 @@
android:ellipsize="marquee"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="@dimen/kg_status_line_font_size"
- android:textColor="?android:attr/textColorSecondary" />
+ android:textColor="?android:attr/textColorSecondary"
+ androidprv:allCaps="@bool/kg_use_all_caps" />
<LinearLayout
android:layout_width="match_parent"
diff --git a/packages/Keyguard/res/values/attrs.xml b/packages/Keyguard/res/values/attrs.xml
index e045dd2..2410b6a 100644
--- a/packages/Keyguard/res/values/attrs.xml
+++ b/packages/Keyguard/res/values/attrs.xml
@@ -133,4 +133,8 @@
<attr name="digit" format="integer" />
<attr name="textView" format="reference" />
</declare-styleable>
+
+ <declare-styleable name="CarrierText">
+ <attr name="allCaps" format="boolean" />
+ </declare-styleable>
</resources>
diff --git a/packages/Keyguard/src/com/android/keyguard/CarrierText.java b/packages/Keyguard/src/com/android/keyguard/CarrierText.java
index 88558cd..05f2962 100644
--- a/packages/Keyguard/src/com/android/keyguard/CarrierText.java
+++ b/packages/Keyguard/src/com/android/keyguard/CarrierText.java
@@ -17,6 +17,7 @@
package com.android.keyguard;
import android.content.Context;
+import android.content.res.TypedArray;
import android.text.method.SingleLineTransformationMethod;
import android.text.TextUtils;
import android.util.AttributeSet;
@@ -81,7 +82,14 @@ public class CarrierText extends TextView {
public CarrierText(Context context, AttributeSet attrs) {
super(context, attrs);
mLockPatternUtils = new LockPatternUtils(mContext);
- boolean useAllCaps = mContext.getResources().getBoolean(R.bool.kg_use_all_caps);
+ boolean useAllCaps;
+ TypedArray a = context.getTheme().obtainStyledAttributes(
+ attrs, R.styleable.CarrierText, 0, 0);
+ try {
+ useAllCaps = a.getBoolean(R.styleable.CarrierText_allCaps, false);
+ } finally {
+ a.recycle();
+ }
setTransformationMethod(new CarrierTextTransformationMethod(mContext, useAllCaps));
}
diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml
index 69fbc1b..24ccb2b 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded.xml
@@ -45,6 +45,15 @@
android:layout_marginTop="@dimen/status_bar_height"
android:visibility="gone" />
+ <com.android.keyguard.CarrierText
+ android:id="@+id/keyguard_carrier_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="2dp"
+ android:layout_marginLeft="8dp"
+ android:ellipsize="marquee"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
diff --git a/packages/SystemUI/res/layout/status_bar_notification_keyguard_overflow.xml b/packages/SystemUI/res/layout/status_bar_notification_keyguard_overflow.xml
index 5d2f330..d81e525 100644
--- a/packages/SystemUI/res/layout/status_bar_notification_keyguard_overflow.xml
+++ b/packages/SystemUI/res/layout/status_bar_notification_keyguard_overflow.xml
@@ -19,34 +19,27 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:focusable="true"
+ android:clickable="true"
+ android:background="@*android:drawable/notification_quantum_bg_dim"
>
- <com.android.systemui.statusbar.LatestItemView
- android:id="@+id/container"
+ <TextView
+ android:id="@+id/more_text"
android:layout_width="match_parent"
- android:layout_height="40dp"
- android:layout_marginTop="@dimen/notification_divider_height"
- android:focusable="true"
- android:clickable="true"
- android:background="@*android:drawable/notification_quantum_bg_dim"
- >
- <TextView
- android:id="@+id/more_text"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
- android:gravity="center_horizontal"
- android:textColor="@color/keyguard_overflow_content_color"
- android:textAllCaps="true"
- android:textAppearance="?android:attr/textAppearanceMedium"
- />
- <com.android.systemui.statusbar.NotificationOverflowIconsView
- android:id="@+id/overflow_icons_view"
- android:layout_gravity="end|center_vertical"
- android:gravity="end"
- android:paddingLeft="8dp"
- android:paddingRight="8dp"
- android:layout_width="120dp"
- android:layout_height="wrap_content"
- />
- </com.android.systemui.statusbar.LatestItemView>
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:gravity="center_horizontal"
+ android:textColor="@color/keyguard_overflow_content_color"
+ android:textAllCaps="true"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ />
+ <com.android.systemui.statusbar.NotificationOverflowIconsView
+ android:id="@+id/overflow_icons_view"
+ android:layout_gravity="end|center_vertical"
+ android:gravity="end"
+ android:paddingLeft="8dp"
+ android:paddingRight="8dp"
+ android:layout_width="120dp"
+ android:layout_height="wrap_content"
+ />
</com.android.systemui.statusbar.NotificationOverflowContainer>
diff --git a/packages/SystemUI/res/layout/status_bar_notification_row.xml b/packages/SystemUI/res/layout/status_bar_notification_row.xml
index d61d8b9..41e7dac 100644
--- a/packages/SystemUI/res/layout/status_bar_notification_row.xml
+++ b/packages/SystemUI/res/layout/status_bar_notification_row.xml
@@ -2,17 +2,18 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:focusable="true"
+ android:clickable="true"
+ android:background="@*android:drawable/notification_quantum_bg"
>
- <View
- android:id="@+id/top_glow"
- android:alpha="0"
- android:visibility="invisible"
+ <com.android.internal.widget.SizeAdaptiveLayout android:id="@+id/expanded"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+
+ <com.android.internal.widget.SizeAdaptiveLayout android:id="@+id/expandedPublic"
android:layout_width="match_parent"
- android:layout_height="@dimen/notification_divider_height"
- android:layout_gravity="top|center_horizontal"
- android:background="@drawable/top_divider_glow"
- />
+ android:layout_height="wrap_content" />
<Button
android:id="@+id/veto"
@@ -25,35 +26,6 @@
android:paddingStart="8dp"
/>
- <com.android.systemui.statusbar.LatestItemView android:id="@+id/container"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginBottom="@dimen/notification_divider_height"
- android:layout_marginTop="@dimen/notification_divider_height"
- android:focusable="true"
- android:clickable="true"
- android:background="@*android:drawable/notification_quantum_bg"
- >
-
- <com.android.internal.widget.SizeAdaptiveLayout android:id="@+id/expanded"
- android:layout_width="match_parent"
- android:layout_height="wrap_content" />
-
- <com.android.internal.widget.SizeAdaptiveLayout android:id="@+id/expandedPublic"
- android:layout_width="match_parent"
- android:layout_height="wrap_content" />
- </com.android.systemui.statusbar.LatestItemView>
-
- <View
- android:id="@+id/bottom_glow"
- android:alpha="0"
- android:visibility="invisible"
- android:layout_width="match_parent"
- android:layout_height="@dimen/notification_divider_height"
- android:layout_gravity="bottom|center_horizontal"
- android:background="@drawable/bottom_divider_glow"
- />
-
<TextView
android:id="@+id/debug_info"
android:visibility="invisible"
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 0604817..176879e 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -82,12 +82,6 @@
<!-- Height of a medium notification in the status bar -->
<dimen name="notification_mid_height">128dp</dimen>
- <!-- Height of a small notification in the status bar plus glow, padding, etc -->
- <dimen name="notification_row_min_height">68dp</dimen>
-
- <!-- Height of a large notification in the status bar plus glow, padding, etc -->
- <dimen name="notification_row_max_height">260dp</dimen>
-
<!-- size at which Notification icons will be drawn in the status bar -->
<dimen name="status_bar_icon_drawing_size">18dip</dimen>
@@ -261,6 +255,9 @@
<!-- Z distance between notifications if they are in the stack -->
<dimen name="z_distance_between_notifications">2dp</dimen>
+ <!-- The padding between the individual notification cards. -->
+ <dimen name="notification_padding">3dp</dimen>
+
<!-- Width of the zen mode interstitial dialog. -->
<dimen name="zen_mode_dialog_width">320dp</dimen>
diff --git a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
index 8dd3f8d..c585a5b 100644
--- a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
@@ -19,7 +19,6 @@ package com.android.systemui;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
-import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.media.AudioManager;
@@ -81,8 +80,6 @@ public class ExpandHelper implements Gefingerpoken, OnClickListener {
private boolean mHasPopped;
private View mEventSource;
private View mCurrView;
- private View mCurrViewTopGlow;
- private View mCurrViewBottomGlow;
private float mOldHeight;
private float mNaturalHeight;
private float mInitialTouchFocusY;
@@ -99,9 +96,6 @@ public class ExpandHelper implements Gefingerpoken, OnClickListener {
private ScaleGestureDetector mSGD;
private ViewScaler mScaler;
private ObjectAnimator mScaleAnimation;
- private AnimatorSet mGlowAnimationSet;
- private ObjectAnimator mGlowTopAnimation;
- private ObjectAnimator mGlowBottomAnimation;
private Vibrator mVibrator;
private int mSmallSize;
@@ -223,14 +217,6 @@ public class ExpandHelper implements Gefingerpoken, OnClickListener {
}
};
- mGlowTopAnimation = ObjectAnimator.ofFloat(null, "alpha", 0f);
- mGlowTopAnimation.addListener(glowVisibilityController);
- mGlowBottomAnimation = ObjectAnimator.ofFloat(null, "alpha", 0f);
- mGlowBottomAnimation.addListener(glowVisibilityController);
- mGlowAnimationSet = new AnimatorSet();
- mGlowAnimationSet.play(mGlowTopAnimation).with(mGlowBottomAnimation);
- mGlowAnimationSet.setDuration(GLOW_DURATION);
-
final ViewConfiguration configuration = ViewConfiguration.get(mContext);
mTouchSlop = configuration.getScaledTouchSlop();
@@ -251,7 +237,6 @@ public class ExpandHelper implements Gefingerpoken, OnClickListener {
float newHeight = clamp(target);
mScaler.setHeight(newHeight);
- setGlow(calculateGlow(target, newHeight));
mLastFocusY = mSGD.getFocusY();
mLastSpanY = mSGD.getCurrentSpan();
}
@@ -322,37 +307,6 @@ public class ExpandHelper implements Gefingerpoken, OnClickListener {
return (GLOW_BASE + strength * (1f - GLOW_BASE));
}
- public void setGlow(float glow) {
- if (!mGlowAnimationSet.isRunning() || glow == 0f) {
- if (mGlowAnimationSet.isRunning()) {
- mGlowAnimationSet.end();
- }
- if (mCurrViewTopGlow != null && mCurrViewBottomGlow != null) {
- if (glow == 0f || mCurrViewTopGlow.getAlpha() == 0f) {
- // animate glow in and out
- mGlowTopAnimation.setTarget(mCurrViewTopGlow);
- mGlowBottomAnimation.setTarget(mCurrViewBottomGlow);
- mGlowTopAnimation.setFloatValues(glow);
- mGlowBottomAnimation.setFloatValues(glow);
- mGlowAnimationSet.setupStartValues();
- mGlowAnimationSet.start();
- } else {
- // set it explicitly in reponse to touches.
- mCurrViewTopGlow.setAlpha(glow);
- mCurrViewBottomGlow.setAlpha(glow);
- handleGlowVisibility();
- }
- }
- }
- }
-
- private void handleGlowVisibility() {
- mCurrViewTopGlow.setVisibility(mCurrViewTopGlow.getAlpha() <= 0.0f ?
- View.INVISIBLE : View.VISIBLE);
- mCurrViewBottomGlow.setVisibility(mCurrViewBottomGlow.getAlpha() <= 0.0f ?
- View.INVISIBLE : View.VISIBLE);
- }
-
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
final int action = ev.getAction();
@@ -466,9 +420,6 @@ public class ExpandHelper implements Gefingerpoken, OnClickListener {
if (mHasPopped) {
mScaler.setHeight(newHeight);
- setGlow(GLOW_BASE);
- } else {
- setGlow(calculateGlow(4f * pull, 0f));
}
final int x = (int) mSGD.getFocusX();
@@ -517,7 +468,6 @@ public class ExpandHelper implements Gefingerpoken, OnClickListener {
if (DEBUG) Log.d(TAG, "scale type " + expandType + " beginning on view: " + v);
mCallback.setUserLockedChild(v, true);
setView(v);
- setGlow(GLOW_BASE);
mScaler.setView(v);
mOldHeight = mScaler.getHeight();
if (mCallback.canChildBeExpanded(v)) {
@@ -549,7 +499,6 @@ public class ExpandHelper implements Gefingerpoken, OnClickListener {
if (mScaleAnimation.isRunning()) {
mScaleAnimation.cancel();
}
- setGlow(0f);
mCallback.setUserExpandedChild(mCurrView, h == mNaturalHeight);
if (targetHeight != currentHeight) {
mScaleAnimation.setFloatValues(targetHeight);
@@ -571,23 +520,11 @@ public class ExpandHelper implements Gefingerpoken, OnClickListener {
private void clearView() {
mCurrView = null;
- mCurrViewTopGlow = null;
- mCurrViewBottomGlow = null;
+
}
private void setView(View v) {
mCurrView = v;
- if (v instanceof ViewGroup) {
- ViewGroup g = (ViewGroup) v;
- mCurrViewTopGlow = g.findViewById(R.id.top_glow);
- mCurrViewBottomGlow = g.findViewById(R.id.bottom_glow);
- if (DEBUG) {
- String debugLog = "Looking for glows: " +
- (mCurrViewTopGlow != null ? "found top " : "didn't find top") +
- (mCurrViewBottomGlow != null ? "found bottom " : "didn't find bottom");
- Log.v(TAG, debugLog);
- }
- }
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LatestItemView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
index 5e90084..d647dfa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/LatestItemView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 The Android Open Source Project
+ * 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.
@@ -11,7 +11,7 @@
* 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.
+ * limitations under the License
*/
package com.android.systemui.statusbar;
@@ -21,12 +21,15 @@ import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
-import android.view.accessibility.AccessibilityEvent;
import android.widget.FrameLayout;
import com.android.internal.R;
-public class LatestItemView extends FrameLayout {
+/**
+ * Base class for both {@link ExpandableNotificationRow} and {@link NotificationOverflowContainer}
+ * to implement dimming/activating on Keyguard for the double-tap gesture
+ */
+public class ActivatableNotificationView extends FrameLayout {
private static final long DOUBLETAP_TIMEOUT_MS = 1000;
@@ -48,11 +51,12 @@ public class LatestItemView extends FrameLayout {
private OnActivatedListener mOnActivatedListener;
- public LatestItemView(Context context, AttributeSet attrs) {
+ public ActivatableNotificationView(Context context, AttributeSet attrs) {
super(context, attrs);
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
}
+
private final Runnable mTapTimeoutRunnable = new Runnable() {
@Override
public void run() {
@@ -66,20 +70,6 @@ public class LatestItemView extends FrameLayout {
}
@Override
- public boolean onRequestSendAccessibilityEvent(View child, AccessibilityEvent event) {
- if (super.onRequestSendAccessibilityEvent(child, event)) {
- // Add a record for the entire layout since its content is somehow small.
- // The event comes from a leaf view that is interacted with.
- AccessibilityEvent record = AccessibilityEvent.obtain();
- onInitializeAccessibilityEvent(record);
- dispatchPopulateAccessibilityEvent(record);
- event.appendRecord(record);
- return true;
- }
- return false;
- }
-
- @Override
public boolean onTouchEvent(MotionEvent event) {
if (mLocked) {
return handleTouchEventLocked(event);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 2ea5add..3e21640 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -83,7 +83,7 @@ import java.util.ArrayList;
import java.util.Locale;
public abstract class BaseStatusBar extends SystemUI implements
- CommandQueue.Callbacks, LatestItemView.OnActivatedListener {
+ CommandQueue.Callbacks, ActivatableNotificationView.OnActivatedListener {
public static final String TAG = "StatusBar";
public static final boolean DEBUG = false;
public static final boolean MULTIUSER_DEBUG = false;
@@ -737,8 +737,9 @@ public abstract class BaseStatusBar extends SystemUI implements
return false;
}
- Log.v(TAG, "publicNotification: "
- + sbn.getNotification().publicVersion);
+ if (DEBUG) {
+ Log.v(TAG, "publicNotification: " + sbn.getNotification().publicVersion);
+ }
Notification publicNotification = sbn.getNotification().publicVersion;
@@ -759,20 +760,19 @@ public abstract class BaseStatusBar extends SystemUI implements
// NB: the large icon is now handled entirely by the template
// bind the click event to the content area
- ViewGroup content = (ViewGroup)row.findViewById(R.id.container);
SizeAdaptiveLayout expanded = (SizeAdaptiveLayout)row.findViewById(R.id.expanded);
SizeAdaptiveLayout expandedPublic
= (SizeAdaptiveLayout)row.findViewById(R.id.expandedPublic);
- content.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
+ row.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
PendingIntent contentIntent = sbn.getNotification().contentIntent;
if (contentIntent != null) {
final View.OnClickListener listener = makeClicker(contentIntent,
sbn.getPackageName(), sbn.getTag(), sbn.getId(), isHeadsUp, sbn.getUserId());
- content.setOnClickListener(listener);
+ row.setOnClickListener(listener);
} else {
- content.setOnClickListener(null);
+ row.setOnClickListener(null);
}
// set up the adaptive layout
@@ -882,7 +882,6 @@ public abstract class BaseStatusBar extends SystemUI implements
entry.row = row;
entry.row.setHeightRange(mRowMinHeight, mRowMaxHeight);
entry.row.setOnActivatedListener(this);
- entry.content = content;
entry.expanded = contentViewLocal;
entry.expandedPublic = publicViewLocal;
entry.setBigContentView(bigContentViewLocal);
@@ -1349,9 +1348,9 @@ public abstract class BaseStatusBar extends SystemUI implements
final View.OnClickListener listener = makeClicker(contentIntent,
notification.getPackageName(), notification.getTag(), notification.getId(),
isHeadsUp, notification.getUserId());
- entry.content.setOnClickListener(listener);
+ entry.row.setOnClickListener(listener);
} else {
- entry.content.setOnClickListener(null);
+ entry.row.setOnClickListener(null);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index bb481ec..35c02eb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -20,13 +20,12 @@ import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.FrameLayout;
+import android.view.accessibility.AccessibilityEvent;
import com.android.internal.widget.SizeAdaptiveLayout;
import com.android.systemui.R;
-public class ExpandableNotificationRow extends FrameLayout
- implements LatestItemView.OnActivatedListener {
+public class ExpandableNotificationRow extends ActivatableNotificationView {
private int mRowMinHeight;
private int mRowMaxHeight;
@@ -41,8 +40,6 @@ public class ExpandableNotificationRow extends FrameLayout
/** Are we showing the "public" version */
private boolean mShowingPublic;
- private LatestItemView mLatestItemView;
-
/**
* Is this notification expanded by the system. The expansion state can be overridden by the
* user expansion.
@@ -53,7 +50,6 @@ public class ExpandableNotificationRow extends FrameLayout
private int mMaxExpandHeight;
private boolean mMaxHeightNeedsUpdate;
private NotificationActivator mActivator;
- private LatestItemView.OnActivatedListener mOnActivatedListener;
private boolean mSelfInitiatedLayout;
public ExpandableNotificationRow(Context context, AttributeSet attrs) {
@@ -65,10 +61,22 @@ public class ExpandableNotificationRow extends FrameLayout
super.onFinishInflate();
mPublicLayout = (SizeAdaptiveLayout) findViewById(R.id.expandedPublic);
mPrivateLayout = (SizeAdaptiveLayout) findViewById(R.id.expanded);
- mLatestItemView = (LatestItemView) findViewById(R.id.container);
mActivator = new NotificationActivator(this);
- mLatestItemView.setOnActivatedListener(this);
+ }
+
+ @Override
+ public boolean onRequestSendAccessibilityEvent(View child, AccessibilityEvent event) {
+ if (super.onRequestSendAccessibilityEvent(child, event)) {
+ // Add a record for the entire layout since its content is somehow small.
+ // The event comes from a leaf view that is interacted with.
+ AccessibilityEvent record = AccessibilityEvent.obtain();
+ onInitializeAccessibilityEvent(record);
+ dispatchPopulateAccessibilityEvent(record);
+ event.appendRecord(record);
+ return true;
+ }
+ return false;
}
public void setHeightRange(int rowMinHeight, int rowMaxHeight) {
@@ -220,7 +228,7 @@ public class ExpandableNotificationRow extends FrameLayout
* Sets the notification as dimmed, meaning that it will appear in a more gray variant.
*/
public void setDimmed(boolean dimmed) {
- mLatestItemView.setDimmed(dimmed);
+ super.setDimmed(dimmed);
mActivator.setDimmed(dimmed);
}
@@ -232,46 +240,10 @@ public class ExpandableNotificationRow extends FrameLayout
return mMaxExpandHeight;
}
- /**
- * Sets the notification as locked. In the locked state, the first tap will produce a quantum
- * ripple to make the notification brighter and only the second tap will cause a click.
- */
- public void setLocked(boolean locked) {
- mLatestItemView.setLocked(locked);
- }
-
- public void setOnActivatedListener(LatestItemView.OnActivatedListener listener) {
- mOnActivatedListener = listener;
- }
-
public NotificationActivator getActivator() {
return mActivator;
}
- @Override
- public void onActivated(View view) {
- if (mOnActivatedListener != null) {
- mOnActivatedListener.onActivated(this);
- }
- }
-
- @Override
- public void onReset(View view) {
- if (mOnActivatedListener != null) {
- mOnActivatedListener.onReset(this);
- }
- }
-
- /**
- * Sets the resource id for the background of this notification.
- *
- * @param bgResId The background resource to use in normal state.
- * @param dimmedBgResId The background resource to use in dimmed state.
- */
- public void setBackgroundResourceIds(int bgResId, int dimmedBgResId) {
- mLatestItemView.setBackgroundResourceIds(bgResId, dimmedBgResId);
- }
-
/**
* @return the potential height this view could expand in addition.
*/
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/InterceptedNotifications.java b/packages/SystemUI/src/com/android/systemui/statusbar/InterceptedNotifications.java
index d563968..6401695 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/InterceptedNotifications.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/InterceptedNotifications.java
@@ -107,7 +107,7 @@ public class InterceptedNotifications {
mBar.updateNotification(mSynKey, sbn);
}
final NotificationData.Entry entry = mBar.mNotificationData.findByKey(mSynKey);
- entry.content.setOnClickListener(mSynClickListener);
+ entry.row.setOnClickListener(mSynClickListener);
}
private final View.OnClickListener mSynClickListener = new View.OnClickListener() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
index b9a59dd..6b6f55a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
@@ -33,7 +33,6 @@ public class NotificationData {
public StatusBarNotification notification;
public StatusBarIconView icon;
public ExpandableNotificationRow row; // the outer expanded view
- public View content; // takes the click events and sends the PendingIntent
public View expanded; // the inflated RemoteViews
public View expandedPublic; // for insecure lockscreens
public ImageView largeIcon;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationOverflowContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationOverflowContainer.java
index be58dad..af91314 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationOverflowContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationOverflowContainer.java
@@ -18,8 +18,6 @@ package com.android.systemui.statusbar;
import android.content.Context;
import android.util.AttributeSet;
-import android.view.View;
-import android.widget.FrameLayout;
import android.widget.TextView;
import com.android.systemui.R;
@@ -27,65 +25,30 @@ import com.android.systemui.R;
/**
* Container view for overflowing notification icons on Keyguard.
*/
-public class NotificationOverflowContainer extends FrameLayout
- implements LatestItemView.OnActivatedListener {
+public class NotificationOverflowContainer extends ActivatableNotificationView {
private NotificationOverflowIconsView mIconsView;
- private LatestItemView.OnActivatedListener mOnActivatedListener;
private NotificationActivator mActivator;
- public NotificationOverflowContainer(Context context) {
- super(context);
- }
-
public NotificationOverflowContainer(Context context, AttributeSet attrs) {
super(context, attrs);
}
- public NotificationOverflowContainer(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- }
-
- public NotificationOverflowContainer(Context context, AttributeSet attrs, int defStyleAttr,
- int defStyleRes) {
- super(context, attrs, defStyleAttr, defStyleRes);
- }
-
@Override
protected void onFinishInflate() {
super.onFinishInflate();
mIconsView = (NotificationOverflowIconsView) findViewById(R.id.overflow_icons_view);
mIconsView.setMoreText((TextView) findViewById(R.id.more_text));
- LatestItemView latestItemView = (LatestItemView) findViewById(R.id.container);
mActivator = new NotificationActivator(this);
mActivator.setDimmed(true);
- latestItemView.setOnActivatedListener(this);
- latestItemView.setLocked(true);
+ setLocked(true);
}
public NotificationOverflowIconsView getIconsView() {
return mIconsView;
}
- public void setOnActivatedListener(LatestItemView.OnActivatedListener onActivatedListener) {
- mOnActivatedListener = onActivatedListener;
- }
-
- @Override
- public void onActivated(View view) {
- if (mOnActivatedListener != null) {
- mOnActivatedListener.onActivated(this);
- }
- }
-
- @Override
- public void onReset(View view) {
- if (mOnActivatedListener != null) {
- mOnActivatedListener.onReset(this);
- }
- }
-
public NotificationActivator getActivator() {
return mActivator;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 9326946..545352c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -247,6 +247,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
private int mCarrierLabelHeight;
private TextView mEmergencyCallLabel;
private int mNotificationHeaderHeight;
+ private View mKeyguardCarrierLabel;
private boolean mShowCarrierInPanel = false;
@@ -616,6 +617,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
(NotificationOverflowContainer) LayoutInflater.from(mContext).inflate(
R.layout.status_bar_notification_keyguard_overflow, mStackScroller, false);
mKeyguardIconOverflowContainer.setOnActivatedListener(this);
+ mKeyguardCarrierLabel = mStatusBarWindow.findViewById(R.id.keyguard_carrier_text);
mStackScroller.addView(mKeyguardIconOverflowContainer);
mExpandedContents = mStackScroller;
@@ -1344,7 +1346,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
!(emergencyCallsShownElsewhere && mNetworkController.isEmergencyOnly())
&& mStackScroller.getHeight() < (mNotificationPanel.getHeight()
- mCarrierLabelHeight - mNotificationHeaderHeight)
- && mStackScroller.getVisibility() == View.VISIBLE;
+ && mStackScroller.getVisibility() == View.VISIBLE
+ && !mOnKeyguard;
if (force || mCarrierLabelVisible != makeVisible) {
mCarrierLabelVisible = makeVisible;
@@ -2715,8 +2718,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
}
mHeadsUpNotificationDecay = res.getInteger(R.integer.heads_up_notification_decay);
- mRowMinHeight = res.getDimensionPixelSize(R.dimen.notification_row_min_height);
- mRowMaxHeight = res.getDimensionPixelSize(R.dimen.notification_row_max_height);
+ mRowMinHeight = res.getDimensionPixelSize(R.dimen.notification_min_height);
+ mRowMaxHeight = res.getDimensionPixelSize(R.dimen.notification_max_height);
mKeyguardMaxNotificationCount = res.getInteger(R.integer.keyguard_max_notification_count);
@@ -2956,6 +2959,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
mKeyguardBottomArea.setVisibility(View.VISIBLE);
mKeyguardIndicationTextView.setVisibility(View.VISIBLE);
mKeyguardIndicationTextView.switchIndication(mKeyguardHotwordPhrase);
+ mKeyguardCarrierLabel.setVisibility(View.VISIBLE);
mNotificationPanelHeader.setVisibility(View.GONE);
mKeyguardFlipper.setVisibility(View.VISIBLE);
@@ -2964,6 +2968,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
mKeyguardStatusView.setVisibility(View.GONE);
mKeyguardBottomArea.setVisibility(View.GONE);
mKeyguardIndicationTextView.setVisibility(View.GONE);
+ mKeyguardCarrierLabel.setVisibility(View.GONE);
mNotificationPanelHeader.setVisibility(View.VISIBLE);
mKeyguardFlipper.setVisibility(View.GONE);
@@ -2974,6 +2979,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
updateRowStates();
checkBarModes();
updateNotificationIcons();
+ updateCarrierLabelVisibility(false);
}
public void userActivity() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
index c5dae85..6b5ef5a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
@@ -69,8 +69,8 @@ public class StatusBarWindowView extends FrameLayout
mStackScrollLayout = (NotificationStackScrollLayout) findViewById(
R.id.notification_stack_scroller);
mNotificationPanel = (NotificationPanelView) findViewById(R.id.notification_panel);
- int minHeight = getResources().getDimensionPixelSize(R.dimen.notification_row_min_height);
- int maxHeight = getResources().getDimensionPixelSize(R.dimen.notification_row_max_height);
+ int minHeight = getResources().getDimensionPixelSize(R.dimen.notification_min_height);
+ int maxHeight = getResources().getDimensionPixelSize(R.dimen.notification_max_height);
mExpandHelper = new ExpandHelper(getContext(), mStackScrollLayout,
minHeight, maxHeight);
mExpandHelper.setEventSource(this);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
index 2dba669..c94c65f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
@@ -135,8 +135,8 @@ public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper.
mSwipeHelper = new SwipeHelper(SwipeHelper.X, this, densityScale, pagingTouchSlop);
mEdgeSwipeHelper = new EdgeSwipeHelper(touchSlop);
- int minHeight = getResources().getDimensionPixelSize(R.dimen.notification_row_min_height);
- int maxHeight = getResources().getDimensionPixelSize(R.dimen.notification_row_max_height);
+ int minHeight = getResources().getDimensionPixelSize(R.dimen.notification_min_height);
+ int maxHeight = getResources().getDimensionPixelSize(R.dimen.notification_max_height);
mExpandHelper = new ExpandHelper(getContext(), this, minHeight, maxHeight);
mContentHolder = (ViewGroup) findViewById(R.id.content_holder);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index 36d94a9..948ef90 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -145,13 +145,13 @@ public class NotificationStackScrollLayout extends ViewGroup
mSidePaddings = context.getResources()
.getDimensionPixelSize(R.dimen.notification_side_padding);
mCollapsedSize = context.getResources()
- .getDimensionPixelSize(R.dimen.notification_row_min_height);
+ .getDimensionPixelSize(R.dimen.notification_min_height);
mBottomStackPeekSize = context.getResources()
.getDimensionPixelSize(R.dimen.bottom_stack_peek_amount);
mEmptyMarginBottom = context.getResources().getDimensionPixelSize(
R.dimen.notification_stack_margin_bottom);
- // currently the padding is in the elements themself
- mPaddingBetweenElements = 0;
+ mPaddingBetweenElements = context.getResources()
+ .getDimensionPixelSize(R.dimen.notification_padding);
mStackScrollAlgorithm = new StackScrollAlgorithm(context);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
index d9e7f66..2a6e4ae 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
@@ -62,11 +62,10 @@ public class StackScrollAlgorithm {
}
private void initConstants(Context context) {
-
- // currently the padding is in the elements themself
- mPaddingBetweenElements = 0;
+ mPaddingBetweenElements = context.getResources()
+ .getDimensionPixelSize(R.dimen.notification_padding);
mCollapsedSize = context.getResources()
- .getDimensionPixelSize(R.dimen.notification_row_min_height);
+ .getDimensionPixelSize(R.dimen.notification_min_height);
mTopStackPeekSize = context.getResources()
.getDimensionPixelSize(R.dimen.top_stack_peek_amount);
mBottomStackPeekSize = context.getResources()
@@ -323,7 +322,8 @@ public class StackScrollAlgorithm {
// the offset starting at the transitionPosition of the bottom stack
float offset = mBottomStackIndentationFunctor.getValue(algorithmState.partialInBottom);
algorithmState.itemsInBottomStack += algorithmState.partialInBottom;
- childViewState.yTranslation = transitioningPositionStart + offset - childHeight;
+ childViewState.yTranslation = transitioningPositionStart + offset - childHeight
+ - mPaddingBetweenElements;
// We want at least to be at the end of the top stack when collapsing
clampPositionToTopStackEnd(childViewState, childHeight);
@@ -339,7 +339,8 @@ public class StackScrollAlgorithm {
if (algorithmState.itemsInBottomStack < MAX_ITEMS_IN_BOTTOM_STACK) {
// We are visually entering the bottom stack
currentYPosition = transitioningPositionStart
- + mBottomStackIndentationFunctor.getValue(algorithmState.itemsInBottomStack);
+ + mBottomStackIndentationFunctor.getValue(algorithmState.itemsInBottomStack)
+ - mPaddingBetweenElements;
childViewState.location = StackScrollState.ViewState.LOCATION_BOTTOM_STACK_PEEKING;
} else {
// we are fully inside the stack
@@ -542,9 +543,13 @@ public class StackScrollAlgorithm {
public void onLayoutChange(View v, int left, int top, int right,
int bottom, int oldLeft, int oldTop, int oldRight,
int oldBottom) {
- mFirstChildMaxHeight = getMaxAllowedChildHeight(
- mFirstChildWhileExpanding);
- mFirstChildWhileExpanding.removeOnLayoutChangeListener(this);
+ if (mFirstChildWhileExpanding != null) {
+ mFirstChildMaxHeight = getMaxAllowedChildHeight(
+ mFirstChildWhileExpanding);
+ } else {
+ mFirstChildMaxHeight = 0;
+ }
+ v.removeOnLayoutChangeListener(this);
}
});
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java
index 9742e65..6e2e87e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java
@@ -197,18 +197,12 @@ public class StackScrollState {
* @param clipHeight the desired clip height, the rest of the view will be clipped from the top
*/
private void updateChildClip(View child, int height, float clipHeight) {
- // The children currently have paddings inside themselfs because of the expansion
- // visualization. In order for the clipping to work correctly we have to set the correct
- // clip rect on the child.
- View container = child.findViewById(R.id.container);
- if (container != null) {
- int clipInset = (int) (height - clipHeight);
- mClipRect.set(0,
- clipInset,
- child.getWidth(),
- height);
- child.setClipBounds(mClipRect);
- }
+ int clipInset = (int) (height - clipHeight);
+ mClipRect.set(0,
+ clipInset,
+ child.getWidth(),
+ height);
+ child.setClipBounds(mClipRect);
}
/**
@@ -218,22 +212,15 @@ public class StackScrollState {
* @param height the currently applied height of the view
* @param outlineHeight the desired height of the outline, the outline ends on the bottom
*/
- private void updateChildOutline(View child,
- int height,
- float outlineHeight) {
- // The children currently have paddings inside themselfs because of the expansion
- // visualization. In order for the shadows to work correctly we have to set the correct
- // outline on the child.
- View container = child.findViewById(R.id.container);
- if (container != null) {
- int shadowInset = (int) (height - outlineHeight);
- getOutlineForSize(container.getLeft(),
- container.getTop() + shadowInset,
- container.getWidth(),
- container.getHeight() - shadowInset,
- mChildOutline);
- child.setOutline(mChildOutline);
- }
+ private void updateChildOutline(View child, int height,
+ float outlineHeight) {
+ int shadowInset = (int) (height - outlineHeight);
+ getOutlineForSize(child.getLeft(),
+ child.getTop() + shadowInset,
+ child.getWidth(),
+ child.getHeight() - shadowInset,
+ mChildOutline);
+ child.setOutline(mChildOutline);
}
private void getOutlineForSize(int leftInset, int topInset, int width, int height,
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index c401efb..2c623b5 100755
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -5439,7 +5439,7 @@ public class PackageManagerService extends IPackageManager.Stub {
if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
codeRoot = Environment.getRootDirectory();
} else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
- codeRoot = Environment.getRootDirectory();
+ codeRoot = Environment.getOemDirectory();
} else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
codeRoot = Environment.getVendorDirectory();
} else {
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 87953fe..3eb2d5f 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -25,6 +25,7 @@ import android.app.IWallpaperManager;
import android.app.IWallpaperManagerCallback;
import android.app.PendingIntent;
import android.app.WallpaperInfo;
+import android.app.WallpaperManager;
import android.app.backup.BackupManager;
import android.app.backup.WallpaperBackupHelper;
import android.content.BroadcastReceiver;
@@ -844,13 +845,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub {
try {
if (componentName == null) {
- String defaultComponent =
- mContext.getString(com.android.internal.R.string.default_wallpaper_component);
- if (defaultComponent != null) {
- // See if there is a default wallpaper component specified
- componentName = ComponentName.unflattenFromString(defaultComponent);
- if (DEBUG) Slog.v(TAG, "Use default component wallpaper:" + componentName);
- }
+ componentName = WallpaperManager.getDefaultWallpaperComponent(mContext);
if (componentName == null) {
// Fall back to static image wallpaper
componentName = IMAGE_WALLPAPER;
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 00d5468..08b1eba 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -29,6 +29,7 @@ import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.media.AudioService;
+import android.os.Build;
import android.os.Environment;
import android.os.FactoryTest;
import android.os.Handler;
@@ -201,6 +202,10 @@ public final class SystemServer {
// as efficient as possible with its memory usage.
VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
+ // Some devices rely on runtime fingerprint generation, so make sure
+ // we've defined it before booting further.
+ Build.ensureFingerprintProperty();
+
// Within the system server, it is an error to access Environment paths without
// explicitly specifying a user.
Environment.setUserRequired(true);
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index 9e2bcab..045c0f6 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -16,14 +16,18 @@
package com.android.server.voiceinteraction;
+import android.Manifest;
import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.PackageManager;
import android.database.ContentObserver;
import android.os.Binder;
+import android.os.Bundle;
import android.os.Handler;
+import android.os.IBinder;
import android.os.UserHandle;
import android.provider.Settings;
import android.service.voice.IVoiceInteractionService;
@@ -134,9 +138,8 @@ public class VoiceInteractionManagerService extends SystemService {
}
@Override
- public int startVoiceActivity(Intent intent, String resolvedType,
- IVoiceInteractionService service,
- IVoiceInteractionSession session, IVoiceInteractor interactor) {
+ public void startVoiceActivity(Intent intent, String resolvedType,
+ IVoiceInteractionService service, Bundle args) {
synchronized (this) {
if (mImpl == null || service.asBinder() != mImpl.mService.asBinder()) {
throw new SecurityException(
@@ -146,8 +149,8 @@ public class VoiceInteractionManagerService extends SystemService {
final int callingUid = Binder.getCallingUid();
final long caller = Binder.clearCallingIdentity();
try {
- return mImpl.startVoiceActivityLocked(callingPid, callingUid,
- intent, resolvedType, session, interactor);
+ mImpl.startVoiceActivityLocked(callingPid, callingUid,
+ intent, resolvedType, args);
} finally {
Binder.restoreCallingIdentity(caller);
}
@@ -155,8 +158,43 @@ public class VoiceInteractionManagerService extends SystemService {
}
@Override
+ public int deliverNewSession(IBinder token, IVoiceInteractionSession session,
+ IVoiceInteractor interactor) {
+ synchronized (this) {
+ if (mImpl == null) {
+ Slog.w(TAG, "deliverNewSession without running voice interaction service");
+ return ActivityManager.START_CANCELED;
+ }
+ final int callingPid = Binder.getCallingPid();
+ final int callingUid = Binder.getCallingUid();
+ final long caller = Binder.clearCallingIdentity();
+ try {
+ return mImpl.deliverNewSessionLocked(callingPid, callingUid, token, session,
+ interactor);
+ } finally {
+ Binder.restoreCallingIdentity(caller);
+ }
+ }
+
+ }
+
+ @Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
+ if (mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP)
+ != PackageManager.PERMISSION_GRANTED) {
+ pw.println("Permission Denial: can't dump PowerManager from from pid="
+ + Binder.getCallingPid()
+ + ", uid=" + Binder.getCallingUid());
+ return;
+ }
+ synchronized (this) {
+ pw.println("VOICE INTERACTION MANAGER (dumpsys voiceinteraction)\n");
+ if (mImpl == null) {
+ pw.println(" (No active implementation)");
+ return;
+ }
+ mImpl.dumpLocked(fd, pw, args);
+ }
}
class SettingsObserver extends ContentObserver {
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
index af8ae1e..6bbd1c1 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
@@ -16,6 +16,7 @@
package com.android.server.voiceinteraction;
+import android.app.ActivityManager;
import android.app.ActivityManagerNative;
import android.app.IActivityManager;
import android.content.ComponentName;
@@ -24,29 +25,40 @@ import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.content.pm.ServiceInfo;
+import android.os.Binder;
+import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.UserHandle;
import android.service.voice.IVoiceInteractionService;
import android.service.voice.IVoiceInteractionSession;
+import android.service.voice.IVoiceInteractionSessionService;
import android.service.voice.VoiceInteractionService;
+import android.service.voice.VoiceInteractionServiceInfo;
import android.util.Slog;
import com.android.internal.app.IVoiceInteractor;
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
class VoiceInteractionManagerServiceImpl {
final static String TAG = "VoiceInteractionServiceManager";
+ final boolean mValid;
+
final Context mContext;
final Handler mHandler;
final Object mLock;
final int mUser;
final ComponentName mComponent;
final IActivityManager mAm;
+ final VoiceInteractionServiceInfo mInfo;
+ final ComponentName mSessionComponentName;
boolean mBound = false;
IVoiceInteractionService mService;
- IVoiceInteractionSession mActiveSession;
- IVoiceInteractor mActiveInteractor;
+
+ SessionConnection mActiveSession;
final ServiceConnection mConnection = new ServiceConnection() {
@Override
@@ -62,6 +74,72 @@ class VoiceInteractionManagerServiceImpl {
}
};
+ final class SessionConnection implements ServiceConnection {
+ final IBinder mToken = new Binder();
+ final Intent mIntent;
+ final String mResolvedType;
+ final Bundle mArgs;
+ boolean mBound;
+ IVoiceInteractionSessionService mService;
+ IVoiceInteractionSession mSession;
+ IVoiceInteractor mInteractor;
+
+ SessionConnection(Intent intent, String resolvedType, Bundle args) {
+ mIntent = intent;
+ mResolvedType = resolvedType;
+ mArgs = args;
+ Intent serviceIntent = new Intent(VoiceInteractionService.SERVICE_INTERFACE);
+ serviceIntent.setComponent(mSessionComponentName);
+ mBound = mContext.bindServiceAsUser(serviceIntent, this,
+ Context.BIND_AUTO_CREATE, new UserHandle(mUser));
+ if (!mBound) {
+ Slog.w(TAG, "Failed binding to voice interaction session service " + mComponent);
+ }
+ }
+
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ synchronized (mLock) {
+ mService = IVoiceInteractionSessionService.Stub.asInterface(service);
+ if (mActiveSession == this) {
+ try {
+ mService.newSession(mToken, mArgs);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Failed making new session", e);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ mService = null;
+ }
+
+ public void cancel() {
+ if (mBound) {
+ mContext.unbindService(this);
+ mBound = false;
+ mService = null;
+ mSession = null;
+ mInteractor = null;
+ }
+ }
+
+ public void dump(String prefix, PrintWriter pw) {
+ pw.print(prefix); pw.print("mToken="); pw.println(mToken);
+ pw.print(prefix); pw.print("mIntent="); pw.println(mIntent);
+ pw.print(" mResolvedType="); pw.println(mResolvedType);
+ pw.print(prefix); pw.print("mArgs="); pw.println(mArgs);
+ pw.print(prefix); pw.print("mBound="); pw.println(mBound);
+ if (mBound) {
+ pw.print(prefix); pw.print("mService="); pw.println(mService);
+ pw.print(prefix); pw.print("mSession="); pw.println(mSession);
+ pw.print(prefix); pw.print("mInteractor="); pw.println(mInteractor);
+ }
+ }
+ };
+
VoiceInteractionManagerServiceImpl(Context context, Handler handler, Object lock,
int userHandle, ComponentName service) {
mContext = context;
@@ -70,50 +148,85 @@ class VoiceInteractionManagerServiceImpl {
mUser = userHandle;
mComponent = service;
mAm = ActivityManagerNative.getDefault();
- }
-
- public int startVoiceActivityLocked(int callingPid, int callingUid, Intent intent,
- String resolvedType, IVoiceInteractionSession session, IVoiceInteractor interactor) {
- if (session == null) {
- throw new NullPointerException("session is null");
+ VoiceInteractionServiceInfo info;
+ try {
+ info = new VoiceInteractionServiceInfo(context.getPackageManager(), service);
+ } catch (PackageManager.NameNotFoundException e) {
+ Slog.w(TAG, "Voice interaction service not found: " + service);
+ mInfo = null;
+ mSessionComponentName = null;
+ mValid = false;
+ return;
}
- if (interactor == null) {
- throw new NullPointerException("interactor is null");
+ mInfo = info;
+ if (mInfo.getParseError() != null) {
+ Slog.w(TAG, "Bad voice interaction service: " + mInfo.getParseError());
+ mSessionComponentName = null;
+ mValid = false;
+ return;
}
+ mValid = true;
+ mSessionComponentName = new ComponentName(service.getPackageName(),
+ mInfo.getSessionService());
+ }
+
+ public void startVoiceActivityLocked(int callingPid, int callingUid, Intent intent,
+ String resolvedType, Bundle args) {
if (mActiveSession != null) {
- // XXX cancel current session.
+ mActiveSession.cancel();
+ mActiveSession = null;
}
+ mActiveSession = new SessionConnection(intent, resolvedType, args);
intent.addCategory(Intent.CATEGORY_VOICE);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
- mActiveSession = session;
- mActiveInteractor = interactor;
+ }
+
+ public int deliverNewSessionLocked(int callingPid, int callingUid, IBinder token,
+ IVoiceInteractionSession session, IVoiceInteractor interactor) {
try {
+ if (mActiveSession == null || token != mActiveSession.mToken) {
+ Slog.w(TAG, "deliverNewSession does not match active session");
+ return ActivityManager.START_CANCELED;
+ }
+ mActiveSession.mSession = session;
+ mActiveSession.mInteractor = interactor;
return mAm.startVoiceActivity(mComponent.getPackageName(), callingPid, callingUid,
- intent, resolvedType, mActiveSession, mActiveInteractor,
+ mActiveSession.mIntent, mActiveSession.mResolvedType,
+ mActiveSession.mSession, mActiveSession.mInteractor,
0, null, null, null, mUser);
} catch (RemoteException e) {
throw new IllegalStateException("Unexpected remote error", e);
}
}
- void startLocked() {
- Intent intent = new Intent(VoiceInteractionService.SERVICE_INTERFACE);
- intent.setComponent(mComponent);
- try {
- ServiceInfo si = mContext.getPackageManager().getServiceInfo(mComponent, 0);
- if (!android.Manifest.permission.BIND_VOICE_INTERACTION.equals(si.permission)) {
- Slog.w(TAG, "Not using voice interaction service " + mComponent
- + ": does not require permission "
- + android.Manifest.permission.BIND_VOICE_INTERACTION);
- return;
+ public void dumpLocked(FileDescriptor fd, PrintWriter pw, String[] args) {
+ if (!mValid) {
+ pw.print(" NOT VALID: ");
+ if (mInfo == null) {
+ pw.println("no info");
+ } else {
+ pw.println(mInfo.getParseError());
}
- } catch (PackageManager.NameNotFoundException e) {
- Slog.w(TAG, "Unable to find voice interaction service: " + mComponent, e);
return;
}
- mContext.bindServiceAsUser(intent, mConnection,
+ pw.print(" mComponent="); pw.println(mComponent.flattenToShortString());
+ pw.print(" Session service="); pw.println(mInfo.getSessionService());
+ pw.print(" Settings activity="); pw.println(mInfo.getSettingsActivity());
+ pw.print(" mBound="); pw.print(mBound); pw.print(" mService="); pw.println(mService);
+ if (mActiveSession != null) {
+ pw.println(" Active session:");
+ mActiveSession.dump(" ", pw);
+ }
+ }
+
+ void startLocked() {
+ Intent intent = new Intent(VoiceInteractionService.SERVICE_INTERFACE);
+ intent.setComponent(mComponent);
+ mBound = mContext.bindServiceAsUser(intent, mConnection,
Context.BIND_AUTO_CREATE, new UserHandle(mUser));
- mBound = true;
+ if (!mBound) {
+ Slog.w(TAG, "Failed binding to voice interaction service " + mComponent);
+ }
}
void shutdownLocked() {
diff --git a/tests/VoiceInteraction/AndroidManifest.xml b/tests/VoiceInteraction/AndroidManifest.xml
index 9c5acf9..ac0f701 100644
--- a/tests/VoiceInteraction/AndroidManifest.xml
+++ b/tests/VoiceInteraction/AndroidManifest.xml
@@ -12,10 +12,16 @@
<service android:name="MainInteractionService"
android:permission="android.permission.BIND_VOICE_INTERACTION"
android:process=":interactor">
+ <meta-data android:name="android.voice_interaction"
+ android:resource="@xml/interaction_service" />
<intent-filter>
<action android:name="android.service.voice.VoiceInteractionService" />
</intent-filter>
</service>
+ <service android:name="MainInteractionSessionService"
+ android:permission="android.permission.BIND_VOICE_INTERACTION"
+ android:process=":session">
+ </service>
<activity android:name="TestInteractionActivity" android:label="Voice Interaction Target">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
diff --git a/tests/VoiceInteraction/res/xml/interaction_service.xml b/tests/VoiceInteraction/res/xml/interaction_service.xml
new file mode 100644
index 0000000..45bd994d
--- /dev/null
+++ b/tests/VoiceInteraction/res/xml/interaction_service.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * 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.
+ */
+-->
+
+<voice-interaction-service xmlns:android="http://schemas.android.com/apk/res/android"
+ android:sessionService="com.android.test.voiceinteraction.MainInteractionSessionService" />
diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java
index 35702f1..008d97b 100644
--- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java
+++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java
@@ -31,8 +31,7 @@ public class MainInteractionService extends VoiceInteractionService {
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
- startVoiceActivity(new Intent(this, TestInteractionActivity.class),
- new MainInteractionSession(this));
+ startVoiceActivity(new Intent(this, TestInteractionActivity.class), null);
stopSelf(startId);
return START_NOT_STICKY;
}
diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java
index adc0df4..0fc563b 100644
--- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java
+++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java
@@ -24,8 +24,11 @@ import android.util.Log;
public class MainInteractionSession extends VoiceInteractionSession {
static final String TAG = "MainInteractionSession";
- MainInteractionSession(Context context) {
+ final Bundle mArgs;
+
+ MainInteractionSession(Context context, Bundle args) {
super(context);
+ mArgs = args;
}
@Override
@@ -42,7 +45,7 @@ public class MainInteractionSession extends VoiceInteractionSession {
@Override
public void onCommand(Caller caller, Request request, String command, Bundle extras) {
Log.i(TAG, "onCommand: command=" + command + " extras=" + extras);
- request.sendCommandResult(null);
+ request.sendCommandResult(true, null);
}
@Override
diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSessionService.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSessionService.java
new file mode 100644
index 0000000..8864d71
--- /dev/null
+++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSessionService.java
@@ -0,0 +1,28 @@
+/*
+ * 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 com.android.test.voiceinteraction;
+
+import android.os.Bundle;
+import android.service.voice.VoiceInteractionSession;
+import android.service.voice.VoiceInteractionSessionService;
+
+public class MainInteractionSessionService extends VoiceInteractionSessionService {
+ @Override
+ public VoiceInteractionSession onNewSession(Bundle args) {
+ return new MainInteractionSession(this, args);
+ }
+}
diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java
index 016a80e..9c772ff 100644
--- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java
+++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java
@@ -30,28 +30,30 @@ public class TestInteractionActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- setContentView(R.layout.test_interaction);
if (!isVoiceInteraction()) {
Log.w(TAG, "Not running as a voice interaction!");
finish();
return;
}
+ setContentView(R.layout.test_interaction);
+
mInteractor = getVoiceInteractor();
- mInteractor.startConfirmation(new VoiceInteractor.Callback() {
+ VoiceInteractor.ConfirmationRequest req = new VoiceInteractor.ConfirmationRequest(
+ "This is a confirmation", null) {
@Override
- public void onConfirmationResult(VoiceInteractor.Request request, boolean confirmed,
- Bundle result) {
- Log.i(TAG, "Confirmation result: confirmed=" + confirmed + " result=" + result);
- finish();
+ public void onCancel() {
+ Log.i(TAG, "Canceled!");
+ getActivity().finish();
}
@Override
- public void onCancel(VoiceInteractor.Request request) {
- Log.i(TAG, "Canceled!");
- finish();
+ public void onConfirmationResult(boolean confirmed, Bundle result) {
+ Log.i(TAG, "Confirmation result: confirmed=" + confirmed + " result=" + result);
+ getActivity().finish();
}
- }, "This is a confirmation", null);
+ };
+ mInteractor.submitRequest(req);
}
@Override