Merge "Ignore accessibility overlays during visible window computation" into lmp-mr1-dev
diff --git a/Android.mk b/Android.mk
index 0d93ed1..51a9846 100644
--- a/Android.mk
+++ b/Android.mk
@@ -202,6 +202,8 @@
core/java/android/os/IUpdateLock.aidl \
core/java/android/os/IUserManager.aidl \
core/java/android/os/IVibratorService.aidl \
+ core/java/android/service/carriermessaging/ICarrierMessagingCallback.aidl \
+ core/java/android/service/carriermessaging/ICarrierMessagingService.aidl \
core/java/android/service/notification/INotificationListener.aidl \
core/java/android/service/notification/IStatusBarNotificationHolder.aidl \
core/java/android/service/notification/IConditionListener.aidl \
@@ -522,6 +524,8 @@
frameworks/base/core/java/android/view/textservice/SpellCheckerInfo.aidl \
frameworks/base/core/java/android/view/textservice/SentenceSuggestionsInfo.aidl \
frameworks/base/core/java/android/view/textservice/SuggestionsInfo.aidl \
+ frameworks/base/core/java/android/service/carriermessaging/MessagePdu.aidl \
+ frameworks/base/core/java/android/service/carriermessaging/CarrierMessagingService.aidl \
frameworks/base/core/java/android/service/notification/StatusBarNotification.aidl \
frameworks/base/core/java/android/speech/tts/Voice.aidl \
frameworks/base/core/java/android/app/usage/UsageEvents.aidl \
diff --git a/api/current.txt b/api/current.txt
index e129761..7eb85d1 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -20,6 +20,7 @@
field public static final java.lang.String BATTERY_STATS = "android.permission.BATTERY_STATS";
field public static final java.lang.String BIND_ACCESSIBILITY_SERVICE = "android.permission.BIND_ACCESSIBILITY_SERVICE";
field public static final java.lang.String BIND_APPWIDGET = "android.permission.BIND_APPWIDGET";
+ field public static final java.lang.String BIND_CARRIER_MESSAGING_SERVICE = "android.permission.BIND_CARRIER_MESSAGING_SERVICE";
field public static final java.lang.String BIND_DEVICE_ADMIN = "android.permission.BIND_DEVICE_ADMIN";
field public static final java.lang.String BIND_DREAM_SERVICE = "android.permission.BIND_DREAM_SERVICE";
field public static final java.lang.String BIND_INPUT_METHOD = "android.permission.BIND_INPUT_METHOD";
@@ -2708,7 +2709,9 @@
method public void invalidateAuthToken(java.lang.String, java.lang.String);
method public static android.content.Intent newChooseAccountIntent(android.accounts.Account, java.util.ArrayList<android.accounts.Account>, java.lang.String[], boolean, java.lang.String, java.lang.String, java.lang.String[], android.os.Bundle);
method public java.lang.String peekAuthToken(android.accounts.Account, java.lang.String);
- method public android.accounts.AccountManagerFuture<java.lang.Boolean> removeAccount(android.accounts.Account, android.accounts.AccountManagerCallback<java.lang.Boolean>, android.os.Handler);
+ method public deprecated android.accounts.AccountManagerFuture<java.lang.Boolean> removeAccount(android.accounts.Account, android.accounts.AccountManagerCallback<java.lang.Boolean>, android.os.Handler);
+ method public android.accounts.AccountManagerFuture<android.os.Bundle> removeAccount(android.accounts.Account, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
+ method public boolean removeAccountExplicitly(android.accounts.Account);
method public void removeOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener);
method public android.accounts.AccountManagerFuture<android.accounts.Account> renameAccount(android.accounts.Account, java.lang.String, android.accounts.AccountManagerCallback<android.accounts.Account>, android.os.Handler);
method public void setAuthToken(android.accounts.Account, java.lang.String, java.lang.String);
@@ -10930,6 +10933,7 @@
method public boolean canClip();
method public float getAlpha();
method public boolean isEmpty();
+ method public void offset(int, int);
method public void set(android.graphics.Outline);
method public void setAlpha(float);
method public void setConvexPath(android.graphics.Path);
@@ -26891,6 +26895,83 @@
}
+package android.service.carriermessaging {
+
+ public abstract class CarrierMessagingService extends android.app.Service {
+ ctor public CarrierMessagingService();
+ method public android.os.IBinder onBind(android.content.Intent);
+ method public int onDownloadMms(android.net.Uri, java.lang.String);
+ method public boolean onFilterSms(android.service.carriermessaging.MessagePdu, java.lang.String, int);
+ method public android.service.carriermessaging.CarrierMessagingService.SendSmsResponse onSendDataSms(byte[], java.lang.String, java.lang.String, int);
+ method public android.service.carriermessaging.CarrierMessagingService.SendMmsResult onSendMms(android.net.Uri, java.lang.String);
+ method public java.util.List<android.service.carriermessaging.CarrierMessagingService.SendSmsResponse> onSendMultipartTextSms(java.util.List<java.lang.String>, java.lang.String, java.lang.String);
+ method public android.service.carriermessaging.CarrierMessagingService.SendSmsResponse onSendTextSms(java.lang.String, java.lang.String, java.lang.String);
+ field public static final int DOWNLOAD_STATUS_ERROR = 2; // 0x2
+ field public static final int DOWNLOAD_STATUS_OK = 0; // 0x0
+ field public static final int DOWNLOAD_STATUS_RETRY_ON_CARRIER_NETWORK = 1; // 0x1
+ field public static final int SEND_STATUS_ERROR = 2; // 0x2
+ field public static final int SEND_STATUS_OK = 0; // 0x0
+ field public static final int SEND_STATUS_RETRY_ON_CARRIER_NETWORK = 1; // 0x1
+ field public static final java.lang.String SERVICE_INTERFACE = "android.service.carriermessaging.CarrierMessagingService";
+ }
+
+ public static final class CarrierMessagingService.SendMmsResult {
+ ctor public CarrierMessagingService.SendMmsResult(int, byte[]);
+ method public int getResult();
+ method public byte[] getSendConfPdu();
+ }
+
+ public static final class CarrierMessagingService.SendSmsResponse implements android.os.Parcelable {
+ ctor public CarrierMessagingService.SendSmsResponse(int, byte[], int);
+ method public int describeContents();
+ method public byte[] getAckPdu();
+ method public int getErrorCode();
+ method public int getMessageRef();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.service.carriermessaging.CarrierMessagingService.SendSmsResponse> CREATOR;
+ }
+
+ public abstract interface ICarrierMessagingCallback implements android.os.IInterface {
+ method public abstract void onDownloadMmsComplete(int) throws android.os.RemoteException;
+ method public abstract void onFilterComplete(boolean) throws android.os.RemoteException;
+ method public abstract void onSendMmsComplete(int, byte[]) throws android.os.RemoteException;
+ method public abstract void onSendMultipartSmsComplete(int, java.util.List<android.service.carriermessaging.CarrierMessagingService.SendSmsResponse>) throws android.os.RemoteException;
+ method public abstract void onSendSmsComplete(int, android.service.carriermessaging.CarrierMessagingService.SendSmsResponse) throws android.os.RemoteException;
+ }
+
+ public static abstract class ICarrierMessagingCallback.Stub extends android.os.Binder implements android.service.carriermessaging.ICarrierMessagingCallback {
+ ctor public ICarrierMessagingCallback.Stub();
+ method public android.os.IBinder asBinder();
+ method public static android.service.carriermessaging.ICarrierMessagingCallback asInterface(android.os.IBinder);
+ method public boolean onTransact(int, android.os.Parcel, android.os.Parcel, int) throws android.os.RemoteException;
+ }
+
+ public abstract interface ICarrierMessagingService implements android.os.IInterface {
+ method public abstract void downloadMms(android.net.Uri, java.lang.String, android.service.carriermessaging.ICarrierMessagingCallback) throws android.os.RemoteException;
+ method public abstract void filterSms(android.service.carriermessaging.MessagePdu, java.lang.String, int, android.service.carriermessaging.ICarrierMessagingCallback) throws android.os.RemoteException;
+ method public abstract void sendDataSms(byte[], java.lang.String, java.lang.String, int, android.service.carriermessaging.ICarrierMessagingCallback) throws android.os.RemoteException;
+ method public abstract void sendMms(android.net.Uri, java.lang.String, android.service.carriermessaging.ICarrierMessagingCallback) throws android.os.RemoteException;
+ method public abstract void sendMultipartTextSms(java.util.List<java.lang.String>, java.lang.String, java.lang.String, android.service.carriermessaging.ICarrierMessagingCallback) throws android.os.RemoteException;
+ method public abstract void sendTextSms(java.lang.String, java.lang.String, java.lang.String, android.service.carriermessaging.ICarrierMessagingCallback) throws android.os.RemoteException;
+ }
+
+ public static abstract class ICarrierMessagingService.Stub extends android.os.Binder implements android.service.carriermessaging.ICarrierMessagingService {
+ ctor public ICarrierMessagingService.Stub();
+ method public android.os.IBinder asBinder();
+ method public static android.service.carriermessaging.ICarrierMessagingService asInterface(android.os.IBinder);
+ method public boolean onTransact(int, android.os.Parcel, android.os.Parcel, int) throws android.os.RemoteException;
+ }
+
+ public final class MessagePdu implements android.os.Parcelable {
+ ctor public MessagePdu(java.util.List<byte[]>);
+ method public int describeContents();
+ method public java.util.List<byte[]> getPdus();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.service.carriermessaging.MessagePdu> CREATOR;
+ }
+
+}
+
package android.service.dreams {
public class DreamService extends android.app.Service implements android.view.Window.Callback {
diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java
index 09b484b..64c2fd0 100644
--- a/core/java/android/accounts/AccountManager.java
+++ b/core/java/android/accounts/AccountManager.java
@@ -17,37 +17,37 @@
package android.accounts;
import android.app.Activity;
-import android.content.Intent;
+import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
+import android.content.Intent;
import android.content.IntentFilter;
-import android.content.BroadcastReceiver;
import android.content.res.Resources;
import android.database.SQLException;
+import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
-import android.os.RemoteException;
import android.os.Parcelable;
-import android.os.Build;
import android.os.Process;
+import android.os.RemoteException;
import android.os.UserHandle;
-import android.util.Log;
import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.internal.R;
+import com.google.android.collect.Maps;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
-import java.util.concurrent.TimeoutException;
import java.util.concurrent.TimeUnit;
-import java.util.HashMap;
-import java.util.Map;
-
-import com.android.internal.R;
-import com.google.android.collect.Maps;
+import java.util.concurrent.TimeoutException;
/**
* This class provides access to a centralized registry of the user's
@@ -747,13 +747,17 @@
* null for the main thread
* @return An {@link AccountManagerFuture} which resolves to a Boolean,
* true if the account has been successfully removed
+ * @deprecated use
+ * {@link #removeAccount(Account, Activity, AccountManagerCallback, Handler)}
+ * instead
*/
+ @Deprecated
public AccountManagerFuture<Boolean> removeAccount(final Account account,
AccountManagerCallback<Boolean> callback, Handler handler) {
if (account == null) throw new IllegalArgumentException("account is null");
return new Future2Task<Boolean>(handler, callback) {
public void doWork() throws RemoteException {
- mService.removeAccount(mResponse, account);
+ mService.removeAccount(mResponse, account, false);
}
public Boolean bundleToResult(Bundle bundle) throws AuthenticatorException {
if (!bundle.containsKey(KEY_BOOLEAN_RESULT)) {
@@ -765,9 +769,60 @@
}
/**
+ * Removes an account from the AccountManager. Does nothing if the account
+ * does not exist. Does not delete the account from the server.
+ * The authenticator may have its own policies preventing account
+ * deletion, in which case the account will not be deleted.
+ *
+ * <p>This method may be called from any thread, but the returned
+ * {@link AccountManagerFuture} must not be used on the main thread.
+ *
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#MANAGE_ACCOUNTS}.
+ *
+ * @param account The {@link Account} to remove
+ * @param activity The {@link Activity} context to use for launching a new
+ * authenticator-defined sub-Activity to prompt the user to delete an
+ * account; used only to call startActivity(); if null, the prompt
+ * will not be launched directly, but the {@link Intent} may be
+ * returned to the caller instead
+ * @param callback Callback to invoke when the request completes,
+ * null for no callback
+ * @param handler {@link Handler} identifying the callback thread,
+ * null for the main thread
+ * @return An {@link AccountManagerFuture} which resolves to a Bundle with
+ * {@link #KEY_BOOLEAN_RESULT} if activity was specified and an account
+ * was removed or if active. If no activity was specified, the returned
+ * Bundle contains only {@link #KEY_INTENT} with the {@link Intent}
+ * needed to launch the actual account removal process, if authenticator
+ * needs the activity launch. If an error occurred,
+ * {@link AccountManagerFuture#getResult()} throws:
+ * <ul>
+ * <li> {@link AuthenticatorException} if no authenticator was registered for
+ * this account type or the authenticator failed to respond
+ * <li> {@link OperationCanceledException} if the operation was canceled for
+ * any reason, including the user canceling the creation process or
+ * adding accounts (of this type) has been disabled by policy
+ * </ul>
+ */
+ public AccountManagerFuture<Bundle> removeAccount(final Account account,
+ final Activity activity, AccountManagerCallback<Bundle> callback, Handler handler) {
+ if (account == null) throw new IllegalArgumentException("account is null");
+ return new AmsTask(activity, handler, callback) {
+ public void doWork() throws RemoteException {
+ mService.removeAccount(mResponse, account, activity != null);
+ }
+ }.start();
+ }
+
+ /**
* @see #removeAccount(Account, AccountManagerCallback, Handler)
* @hide
+ * @deprecated use
+ * {@link #removeAccountAsUser(Account, Activity, AccountManagerCallback, Handler)}
+ * instead
*/
+ @Deprecated
public AccountManagerFuture<Boolean> removeAccountAsUser(final Account account,
AccountManagerCallback<Boolean> callback, Handler handler,
final UserHandle userHandle) {
@@ -775,7 +830,7 @@
if (userHandle == null) throw new IllegalArgumentException("userHandle is null");
return new Future2Task<Boolean>(handler, callback) {
public void doWork() throws RemoteException {
- mService.removeAccountAsUser(mResponse, account, userHandle.getIdentifier());
+ mService.removeAccountAsUser(mResponse, account, false, userHandle.getIdentifier());
}
public Boolean bundleToResult(Bundle bundle) throws AuthenticatorException {
if (!bundle.containsKey(KEY_BOOLEAN_RESULT)) {
@@ -787,6 +842,52 @@
}
/**
+ * @see #removeAccount(Account, Activity, AccountManagerCallback, Handler)
+ * @hide
+ */
+ public AccountManagerFuture<Bundle> removeAccountAsUser(final Account account,
+ final Activity activity, AccountManagerCallback<Bundle> callback, Handler handler,
+ final UserHandle userHandle) {
+ if (account == null)
+ throw new IllegalArgumentException("account is null");
+ if (userHandle == null)
+ throw new IllegalArgumentException("userHandle is null");
+ return new AmsTask(activity, handler, callback) {
+ public void doWork() throws RemoteException {
+ mService.removeAccountAsUser(mResponse, account, activity != null,
+ userHandle.getIdentifier());
+ }
+ }.start();
+ }
+
+ /**
+ * Removes an account directly. Normally used by authenticators, not
+ * directly by applications. Does not delete the account from the server.
+ * The authenticator may have its own policies preventing account deletion,
+ * in which case the account will not be deleted.
+ * <p>
+ * It is safe to call this method from the main thread.
+ * <p>
+ * This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#AUTHENTICATE_ACCOUNTS} and to have the
+ * same UID or signature as the account's authenticator.
+ *
+ * @param account The {@link Account} to delete.
+ * @return True if the account was successfully deleted, false if the
+ * account did not exist, the account is null, or another error
+ * occurs.
+ */
+ public boolean removeAccountExplicitly(Account account) {
+ if (account == null) throw new IllegalArgumentException("account is null");
+ try {
+ return mService.removeAccountExplicitly(account);
+ } catch (RemoteException e) {
+ // won't ever happen
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
* Removes an auth token from the AccountManager's cache. Does nothing if
* the auth token is not currently in the cache. Applications must call this
* method when the auth token is found to have expired or otherwise become
diff --git a/core/java/android/accounts/IAccountManager.aidl b/core/java/android/accounts/IAccountManager.aidl
index a133788..bc75b9b 100644
--- a/core/java/android/accounts/IAccountManager.aidl
+++ b/core/java/android/accounts/IAccountManager.aidl
@@ -37,8 +37,11 @@
void hasFeatures(in IAccountManagerResponse response, in Account account, in String[] features);
void getAccountsByFeatures(in IAccountManagerResponse response, String accountType, in String[] features);
boolean addAccountExplicitly(in Account account, String password, in Bundle extras);
- void removeAccount(in IAccountManagerResponse response, in Account account);
- void removeAccountAsUser(in IAccountManagerResponse response, in Account account, int userId);
+ void removeAccount(in IAccountManagerResponse response, in Account account,
+ boolean expectActivityLaunch);
+ void removeAccountAsUser(in IAccountManagerResponse response, in Account account,
+ boolean expectActivityLaunch, int userId);
+ boolean removeAccountExplicitly(in Account account);
void invalidateAuthToken(String accountType, String authToken);
String peekAuthToken(in Account account, String authTokenType);
void setAuthToken(in Account account, String authTokenType, String authToken);
diff --git a/core/java/android/service/carriermessaging/CarrierMessagingService.aidl b/core/java/android/service/carriermessaging/CarrierMessagingService.aidl
new file mode 100644
index 0000000..50c438a
--- /dev/null
+++ b/core/java/android/service/carriermessaging/CarrierMessagingService.aidl
@@ -0,0 +1,19 @@
+/**
+ * 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.carriermessaging;
+
+parcelable CarrierMessagingService.SendSmsResponse;
\ No newline at end of file
diff --git a/core/java/android/service/carriermessaging/CarrierMessagingService.java b/core/java/android/service/carriermessaging/CarrierMessagingService.java
new file mode 100644
index 0000000..101f69b
--- /dev/null
+++ b/core/java/android/service/carriermessaging/CarrierMessagingService.java
@@ -0,0 +1,370 @@
+/*
+ * 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.carriermessaging;
+
+import android.annotation.Nullable;
+import android.annotation.SdkConstant;
+import android.app.Service;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.RemoteException;
+
+import java.util.List;
+
+/**
+ * A service that receives calls from the system when new SMS and MMS are
+ * sent or received.
+ * <p>To extend this class, you must declare the service in your manifest file with
+ * the {@link android.Manifest.permission#BIND_CARRIER_MESSAGING_SERVICE} permission
+ * and include an intent filter with the {@link #SERVICE_INTERFACE} action. For example:</p>
+ * <pre>
+ * <service android:name=".MyMessagingService"
+ * android:label="@string/service_name"
+ * android:permission="android.permission.BIND_CARRIER_MESSAGING_SERVICE">
+ * <intent-filter>
+ * <action android:name="android.service.carriermessaging.CarrierMessagingService" />
+ * </intent-filter>
+ * </service></pre>
+ */
+public abstract class CarrierMessagingService extends Service {
+ /**
+ * The {@link android.content.Intent} that must be declared as handled by the service.
+ */
+ @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
+ public static final String SERVICE_INTERFACE
+ = "android.service.carriermessaging.CarrierMessagingService";
+
+ /**
+ * Indicates that an SMS or MMS message was successfully sent.
+ */
+ public static final int SEND_STATUS_OK = 0;
+
+ /**
+ * SMS/MMS sending failed. We should retry via the carrier network.
+ */
+ public static final int SEND_STATUS_RETRY_ON_CARRIER_NETWORK = 1;
+
+ /**
+ * SMS/MMS sending failed. We should not retry via the carrier network.
+ */
+ public static final int SEND_STATUS_ERROR = 2;
+
+ /**
+ * Successfully downloaded an MMS message.
+ */
+ public static final int DOWNLOAD_STATUS_OK = 0;
+
+ /**
+ * MMS downloading failed. We should retry via the carrier network.
+ */
+ public static final int DOWNLOAD_STATUS_RETRY_ON_CARRIER_NETWORK = 1;
+
+ /**
+ * MMS downloading failed. We should not retry via the carrier network.
+ */
+ public static final int DOWNLOAD_STATUS_ERROR = 2;
+
+ private final ICarrierMessagingWrapper mWrapper = new ICarrierMessagingWrapper();
+
+ /**
+ * Implement this method to filter SMS messages.
+ *
+ * @param pdu the PDUs of the message
+ * @param format the format of the PDUs, typically "3gpp" or "3gpp2"
+ * @param destPort the destination port of a binary SMS, this will be -1 for text SMS
+ *
+ * @return True to keep an inbound SMS message and delivered to SMS apps. False to
+ * drop the message.
+ */
+ public boolean onFilterSms(MessagePdu pdu, String format, int destPort) {
+ // optional
+ return true;
+ }
+
+ /**
+ * Implement this method to intercept text SMSs sent from the devcie.
+ *
+ * @param text the text to send
+ * @param format the format of the response PDU, typically "3gpp" or "3gpp2"
+ * @param destAddress phone number of the recipient of the message
+ *
+ * @return a {@link SendSmsResponse}.
+ */
+ public SendSmsResponse onSendTextSms(String text, String format, String destAddress) {
+ // optional
+ return null;
+ }
+
+ /**
+ * Implement this method to intercept binary SMSs sent from the device.
+ *
+ * @param data the binary content
+ * @param format format the format of the response PDU, typically "3gpp" or "3gpp2"
+ * @param destAddress phone number of the recipient of the message
+ * @param destPort the destination port
+ *
+ * @return a {@link SendSmsResponse}
+ */
+ public SendSmsResponse onSendDataSms(byte[] data, String format, String destAddress,
+ int destPort) {
+ // optional
+ return null;
+ }
+
+ /**
+ * Implement this method to intercept long SMSs sent from the device.
+ *
+ * @param parts a {@link List} of the message parts
+ * @param format format the format of the response PDU, typically "3gpp" or "3gpp2"
+ * @param destAddress phone number of the recipient of the message
+ *
+ * @return a {@link List} of {@link SendSmsResponse}, one for each message part.
+ */
+ public List<SendSmsResponse> onSendMultipartTextSms(List<String> parts, String format,
+ String destAddress) {
+ // optional
+ return null;
+ }
+
+ /**
+ * Implement this method to intercept MMSs sent from the device.
+ *
+ * @param pduUri the content provider URI of the PDU to send
+ * @param locationUrl the optional URL to send this MMS PDU. If this is not specified,
+ * the PDU should be sent to the default MMSC URL.
+ *
+ * @return a {@link SendMmsResult}.
+ */
+ public SendMmsResult onSendMms(Uri pduUri, @Nullable String locationUrl) {
+ // optional
+ return null;
+ }
+
+ /**
+ * Implement this method to download MMSs received.
+ *
+ * @param contentUri the content provider URI of the PDU to be downloaded.
+ * @param locationUrl the URL of the message to be downloaded.
+ *
+ * @return a {@link SendMmsResult}.
+ */
+ public int onDownloadMms(Uri contentUri, String locationUrl) {
+ // optional
+ return DOWNLOAD_STATUS_RETRY_ON_CARRIER_NETWORK;
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ if (!SERVICE_INTERFACE.equals(intent.getAction())) {
+ return null;
+ }
+ return mWrapper;
+ }
+
+ /**
+ * The result of sending an MMS.
+ */
+ public static final class SendMmsResult {
+ private int mResult;
+ private byte[] mSendConfPdu;
+
+ public SendMmsResult(int result, byte[] sendConfPdu) {
+ mResult = result;
+ mSendConfPdu = sendConfPdu;
+ }
+
+ /**
+ * @return the result which is one of {@link #SEND_STATUS_OK},
+ * {@link #SEND_STATUS_RETRY_ON_CARRIER_NETWORK}, and {@link #SEND_STATUS_ERROR}
+ */
+ public int getResult() {
+ return mResult;
+ }
+
+ /**
+ * @return the SendConf PDU, which confirms that the message was sent.
+ */
+ public byte[] getSendConfPdu() {
+ return mSendConfPdu;
+ }
+ }
+
+ /**
+ * Object passed in callbacks upon successful completion of
+ * {@link ICarrierMessagingService#sendTextSms},
+ * {@link ICarrierMessagingService#sendDataSms}, and
+ * {@link ICarrierMessagingService#sendMultipartTextSms}.
+ * Contains message reference and ackPdu.
+ */
+ public static final class SendSmsResponse implements Parcelable {
+ private int mMessageRef;
+ private byte[] mAckPdu;
+ private int mErrorCode;
+
+ /**
+ * @param messageRef message reference of the just-sent SMS
+ * @param ackPdu ackPdu for the just-sent SMS
+ * @param errorCode error code. See 3GPP 27.005, 3.2.5 for GSM/UMTS,
+ * 3GPP2 N.S0005 (IS-41C) Table 171 for CDMA, -1 if unknown or not applicable.
+ */
+ public SendSmsResponse(int messageRef, byte[] ackPdu, int errorCode) {
+ mMessageRef = messageRef;
+ mAckPdu = ackPdu;
+ mErrorCode = errorCode;
+ }
+
+ /**
+ * Returns the message reference of the just-sent SMS.
+ *
+ * @return the message reference
+ */
+ public int getMessageRef() {
+ return mMessageRef;
+ }
+
+ /**
+ * Returns the ackPdu for the just-sent SMS.
+ *
+ * @return the ackPdu
+ */
+ public byte[] getAckPdu() {
+ return mAckPdu;
+ }
+
+ /**
+ * Returns the error code upon encountering an error while sending the SMS, -1 if unknown or
+ * not applicable.
+ *
+ * @return errorCode the errorCode as defined in 3GPP 27.005, 3.2.5 for GSM/UMTS, and 3GPP2
+ * N.S0005 (IS-41C) Table 171 for CDMA, -1 if unknown or not applicable.
+ */
+ public int getErrorCode() {
+ return mErrorCode;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mMessageRef);
+ dest.writeByteArray(mAckPdu);
+ dest.writeInt(mErrorCode);
+ }
+
+ public static final Parcelable.Creator<SendSmsResponse> CREATOR
+ = new Parcelable.Creator<SendSmsResponse>() {
+ @Override
+ public SendSmsResponse createFromParcel(Parcel source) {
+ return new SendSmsResponse(source.readInt(),
+ source.createByteArray(),
+ source.readInt());
+ }
+
+ @Override
+ public SendSmsResponse[] newArray(int size) {
+ return new SendSmsResponse[size];
+ }
+ };
+ }
+
+ /**
+ * A wrapper around ICarrierMessagingService to enable the carrier messaging APP to implement
+ * methods it cares about in the {@link ICarrierMessagingService} interface.
+ */
+ private class ICarrierMessagingWrapper extends ICarrierMessagingService.Stub {
+ @Override
+ public void filterSms(MessagePdu pdu, String format, int destPort,
+ ICarrierMessagingCallback callback) {
+ try {
+ callback.onFilterComplete(onFilterSms(pdu, format, destPort));
+ } catch (RemoteException ex) {
+ }
+ }
+
+ @Override
+ public void sendTextSms(String text, String format, String destAddress,
+ ICarrierMessagingCallback callback) {
+ try {
+ SendSmsResponse sendSmsResponse = onSendTextSms(text, format, destAddress);
+ if (sendSmsResponse == null) {
+ callback.onSendSmsComplete(SEND_STATUS_RETRY_ON_CARRIER_NETWORK, null);
+ } else {
+ callback.onSendSmsComplete(SEND_STATUS_OK, sendSmsResponse);
+ }
+ } catch (RemoteException ex) {
+ }
+ }
+
+ @Override
+ public void sendDataSms(byte[] data, String format, String destAddress, int destPort,
+ ICarrierMessagingCallback callback) {
+ try {
+ SendSmsResponse sendSmsResponse = onSendDataSms(data, format, destAddress,
+ destPort);
+ if (sendSmsResponse == null) {
+ callback.onSendSmsComplete(SEND_STATUS_RETRY_ON_CARRIER_NETWORK, null);
+ } else {
+ callback.onSendSmsComplete(SEND_STATUS_OK, sendSmsResponse);
+ }
+ } catch (RemoteException ex) {
+ }
+ }
+
+ @Override
+ public void sendMultipartTextSms(List<String> parts, String format, String destAddress,
+ ICarrierMessagingCallback callback) {
+ try {
+ List<SendSmsResponse> sendSmsResponses =
+ onSendMultipartTextSms(parts, format, destAddress);
+ if (sendSmsResponses == null) {
+ callback.onSendMultipartSmsComplete(SEND_STATUS_RETRY_ON_CARRIER_NETWORK, null);
+ } else {
+ callback.onSendMultipartSmsComplete(SEND_STATUS_OK, sendSmsResponses);
+ }
+ } catch (RemoteException ex) {
+ }
+ }
+
+ @Override
+ public void sendMms(Uri pduUri, String locationUrl, ICarrierMessagingCallback callback) {
+ try {
+ SendMmsResult result = onSendMms(pduUri, locationUrl);
+ if (result == null) {
+ callback.onSendMmsComplete(SEND_STATUS_RETRY_ON_CARRIER_NETWORK, null);
+ } else {
+ callback.onSendMmsComplete(SEND_STATUS_OK, result.getSendConfPdu());
+ }
+ } catch (RemoteException ex) {
+ }
+ }
+
+ @Override
+ public void downloadMms(Uri contentUri, String locationUrl,
+ ICarrierMessagingCallback callback) {
+ try {
+ callback.onDownloadMmsComplete(onDownloadMms(contentUri, locationUrl));
+ } catch (RemoteException ex) {
+ }
+ }
+ }
+}
diff --git a/core/java/android/service/carriermessaging/CarrierMessagingServiceManager.java b/core/java/android/service/carriermessaging/CarrierMessagingServiceManager.java
new file mode 100644
index 0000000..56ee2c1
--- /dev/null
+++ b/core/java/android/service/carriermessaging/CarrierMessagingServiceManager.java
@@ -0,0 +1,97 @@
+/*
+ * 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.carriermessaging;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.IBinder;
+
+import com.android.internal.util.Preconditions;
+
+/**
+ * Provides basic structure for platform to connect to the carrier messaging service.
+ * <p>
+ * <code>
+ * CarrierMessagingServiceManager carrierMessagingServiceManager =
+ * new CarrierMessagingServiceManagerImpl();
+ * if (carrierMessagingServiceManager.bindToCarrierMessagingService(context, carrierPackageName)) {
+ * // wait for onServiceReady callback
+ * } else {
+ * // Unable to bind: handle error.
+ * }
+ * </code>
+ * <p> Upon completion {@link #disposeConnection} should be called to unbind the
+ * CarrierMessagingService.
+ * @hide
+ */
+public abstract class CarrierMessagingServiceManager {
+ // Populated by bindToCarrierMessagingService. bindToCarrierMessagingService must complete
+ // prior to calling disposeConnection so that mCarrierMessagingServiceConnection is initialized.
+ private volatile CarrierMessagingServiceConnection mCarrierMessagingServiceConnection;
+
+ /**
+ * Binds to the carrier messaging service under package {@code carrierPackageName}. This method
+ * should be called exactly once.
+ *
+ * @param context the context
+ * @param carrierPackageName the carrier package name
+ * @return true upon successfully binding to a carrier messaging service, false otherwise
+ */
+ public boolean bindToCarrierMessagingService(Context context, String carrierPackageName) {
+ Preconditions.checkState(mCarrierMessagingServiceConnection == null);
+
+ Intent intent = new Intent(CarrierMessagingService.SERVICE_INTERFACE);
+ intent.setPackage(carrierPackageName);
+ mCarrierMessagingServiceConnection = new CarrierMessagingServiceConnection();
+ return context.bindService(intent, mCarrierMessagingServiceConnection,
+ Context.BIND_AUTO_CREATE);
+ }
+
+ /**
+ * Unbinds the carrier messaging service. This method should be called exactly once.
+ *
+ * @param context the context
+ */
+ public void disposeConnection(Context context) {
+ Preconditions.checkNotNull(mCarrierMessagingServiceConnection);
+ context.unbindService(mCarrierMessagingServiceConnection);
+ mCarrierMessagingServiceConnection = null;
+ }
+
+ /**
+ * Implemented by subclasses to use the carrier messaging service once it is ready.
+ *
+ * @param carrierMessagingService the carirer messaing service interface
+ */
+ protected abstract void onServiceReady(ICarrierMessagingService carrierMessagingService);
+
+ /**
+ * A basic {@link ServiceConnection}.
+ */
+ private final class CarrierMessagingServiceConnection implements ServiceConnection {
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ onServiceReady(ICarrierMessagingService.Stub.asInterface(service));
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ }
+ }
+}
diff --git a/core/java/android/service/carriermessaging/ICarrierMessagingCallback.aidl b/core/java/android/service/carriermessaging/ICarrierMessagingCallback.aidl
new file mode 100644
index 0000000..da56ad1
--- /dev/null
+++ b/core/java/android/service/carriermessaging/ICarrierMessagingCallback.aidl
@@ -0,0 +1,33 @@
+/**
+ * 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.carriermessaging;
+
+import android.service.carriermessaging.CarrierMessagingService;
+
+/**
+ * Callback interface definition for the Carrier Messaging Service client to get informed of the
+ * result of various API invocations.
+ */
+oneway interface ICarrierMessagingCallback {
+ void onFilterComplete(boolean keepMessage);
+ void onSendSmsComplete(
+ int result, in CarrierMessagingService.SendSmsResponse sendSmsResponse);
+ void onSendMultipartSmsComplete(
+ int result, in List<CarrierMessagingService.SendSmsResponse> sendSmsResponses);
+ void onSendMmsComplete(int result, in byte[] sendConfPdu);
+ void onDownloadMmsComplete(int result);
+}
diff --git a/core/java/android/service/carriermessaging/ICarrierMessagingService.aidl b/core/java/android/service/carriermessaging/ICarrierMessagingService.aidl
new file mode 100644
index 0000000..6e9e3fa
--- /dev/null
+++ b/core/java/android/service/carriermessaging/ICarrierMessagingService.aidl
@@ -0,0 +1,103 @@
+/**
+ * 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.carriermessaging;
+
+import android.net.Uri;
+import android.service.carriermessaging.ICarrierMessagingCallback;
+import android.service.carriermessaging.MessagePdu;
+
+/**
+ * <p class="note"><strong>Note:</strong>
+ * This service can only be implemented by a carrier privileged app.
+ */
+oneway interface ICarrierMessagingService {
+ /**
+ * Request filtering an incoming SMS message.
+ * The service will call callback.onFilterComplete with the filtering result.
+ *
+ * @param pdu the PDUs of the message
+ * @param format the format of the PDUs, typically "3gpp" or "3gpp2"
+ * @param destPort the destination port of a data SMS. It will be -1 for text SMS
+ * @param callback the callback to notify upon completion
+ */
+ void filterSms(
+ in MessagePdu pdu, String format, int destPort, in ICarrierMessagingCallback callback);
+
+ /**
+ * Request sending a new text SMS from the device.
+ * The service will call {@link ICarrierMessagingCallback#onSendSmsComplete} with the send
+ * status.
+ *
+ * @param text the text to send
+ * @param format the format of the response PDU, typically "3gpp" or "3gpp2"
+ * @param destAddress phone number of the recipient of the message
+ * @param callback the callback to notify upon completion
+ */
+ void sendTextSms(String text, String format, String destAddress,
+ in ICarrierMessagingCallback callback);
+
+ /**
+ * Request sending a new data SMS from the device.
+ * The service will call {@link ICarrierMessagingCallback#onSendSmsComplete} with the send
+ * status.
+ *
+ * @param data the data to send
+ * @param format the format of the response PDU, typically "3gpp" or "3gpp2"
+ * @param destAddress phone number of the recipient of the message
+ * @param destPort port number of the recipient of the message
+ * @param callback the callback to notify upon completion
+ */
+ void sendDataSms(in byte[] data, String format, String destAddress, int destPort,
+ in ICarrierMessagingCallback callback);
+
+ /**
+ * Request sending a new multi-part text SMS from the device.
+ * The service will call {@link ICarrierMessagingCallback#onSendMultipartSmsComplete}
+ * with the send status.
+ *
+ * @param parts the parts of the multi-part text SMS to send
+ * @param format the format of the response PDU, typically "3gpp" or "3gpp2"
+ * @param destAddress phone number of the recipient of the message
+ * @param callback the callback to notify upon completion
+ */
+ void sendMultipartTextSms(in List<String> parts, String format, String destAddress,
+ in ICarrierMessagingCallback callback);
+
+ /**
+ * Request sending a new MMS PDU from the device.
+ * The service will call {@link ICarrierMessagingCallback#onSendMmsComplete} with the send
+ * status.
+ *
+ * @param pduUri the content provider URI of the PDU to send
+ * @param locationUrl the optional url to send this MMS PDU.
+ * If this is not specified, PDU should be sent to the default MMSC url.
+ * @param callback the callback to notify upon completion
+ */
+ void sendMms(in Uri pduUri, String locationUrl, in ICarrierMessagingCallback callback);
+
+ /**
+ * Request downloading a new MMS.
+ * The service will call {@link ICarrierMessagingCallback#onDownloadMmsComplete} with the
+ * download status.
+ *
+ * @param pduUri the content provider URI of the PDU to be downloaded.
+ * @param locationUrl the URL of the message to be downloaded.
+ * @param callback the callback to notify upon completion
+ */
+ void downloadMms(in Uri pduUri, String locationUrl, in ICarrierMessagingCallback callback);
+}
+
diff --git a/core/java/android/service/carriermessaging/MessagePdu.aidl b/core/java/android/service/carriermessaging/MessagePdu.aidl
new file mode 100644
index 0000000..82b3fb3
--- /dev/null
+++ b/core/java/android/service/carriermessaging/MessagePdu.aidl
@@ -0,0 +1,19 @@
+/**
+ * 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.carriermessaging;
+
+parcelable MessagePdu;
\ No newline at end of file
diff --git a/core/java/android/service/carriermessaging/MessagePdu.java b/core/java/android/service/carriermessaging/MessagePdu.java
new file mode 100644
index 0000000..b81719f
--- /dev/null
+++ b/core/java/android/service/carriermessaging/MessagePdu.java
@@ -0,0 +1,94 @@
+/*
+ * 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.carriermessaging;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A parcelable list of PDUs representing contents of a possibly multi-part SMS.
+ */
+public final class MessagePdu implements Parcelable {
+ private static final int NULL_LENGTH = -1;
+
+ private final List<byte[]> mPduList;
+
+ /**
+ * @param pduList the list of message PDUs
+ */
+ public MessagePdu(List<byte[]> pduList) {
+ mPduList = pduList;
+ }
+
+ /**
+ * Returns the contents of a possibly multi-part SMS.
+ *
+ * @return the list of PDUs
+ */
+ public List<byte[]> getPdus() {
+ return mPduList;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /**
+ * Writes the PDU into a {@link Parcel}.
+ */
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ if (mPduList == null) {
+ dest.writeInt(NULL_LENGTH);
+ } else {
+ dest.writeInt(mPduList.size());
+ for (byte[] messagePdu : mPduList) {
+ dest.writeByteArray(messagePdu);
+ }
+ }
+ }
+
+ /**
+ * Constructs a {@link MessagePdu} from a {@link Parcel}.
+ */
+ public static final Parcelable.Creator<MessagePdu> CREATOR
+ = new Parcelable.Creator<MessagePdu>() {
+ @Override
+ public MessagePdu createFromParcel(Parcel source) {
+ int size = source.readInt();
+ List<byte[]> pduList;
+ if (size == NULL_LENGTH) {
+ pduList = null;
+ } else {
+ pduList = new ArrayList<>(size);
+ for (int i = 0; i < size; i++) {
+ pduList.add(source.createByteArray());
+ }
+ }
+ return new MessagePdu(pduList);
+ }
+
+ @Override
+ public MessagePdu[] newArray(int size) {
+ return new MessagePdu[size];
+ }
+ };
+}
diff --git a/core/java/android/util/PathParser.java b/core/java/android/util/PathParser.java
index e5f3b2c..92b19be 100644
--- a/core/java/android/util/PathParser.java
+++ b/core/java/android/util/PathParser.java
@@ -280,7 +280,7 @@
* @param path The target Path object.
*/
public static void nodesToPath(PathDataNode[] node, Path path) {
- float[] current = new float[4];
+ float[] current = new float[6];
char previousCommand = 'm';
for (int i = 0; i < node.length; i++) {
addCommand(path, current, previousCommand, node[i].mType, node[i].mParams);
@@ -313,6 +313,8 @@
float currentY = current[1];
float ctrlPointX = current[2];
float ctrlPointY = current[3];
+ float currentSegmentStartX = current[4];
+ float currentSegmentStartY = current[5];
float reflectiveCtrlPointX;
float reflectiveCtrlPointY;
@@ -320,7 +322,15 @@
case 'z':
case 'Z':
path.close();
- return;
+ // Path is closed here, but we need to move the pen to the
+ // closed position. So we cache the segment's starting position,
+ // and restore it here.
+ currentX = currentSegmentStartX;
+ currentY = currentSegmentStartY;
+ ctrlPointX = currentSegmentStartX;
+ ctrlPointY = currentSegmentStartY;
+ path.moveTo(currentX, currentY);
+ break;
case 'm':
case 'M':
case 'l':
@@ -350,17 +360,22 @@
incr = 7;
break;
}
+
for (int k = 0; k < val.length; k += incr) {
switch (cmd) {
case 'm': // moveto - Start a new sub-path (relative)
path.rMoveTo(val[k + 0], val[k + 1]);
currentX += val[k + 0];
currentY += val[k + 1];
+ currentSegmentStartX = currentX;
+ currentSegmentStartY = currentY;
break;
case 'M': // moveto - Start a new sub-path
path.moveTo(val[k + 0], val[k + 1]);
currentX = val[k + 0];
currentY = val[k + 1];
+ currentSegmentStartX = currentX;
+ currentSegmentStartY = currentY;
break;
case 'l': // lineto - Draw a line from the current point (relative)
path.rLineTo(val[k + 0], val[k + 1]);
@@ -372,10 +387,6 @@
currentX = val[k + 0];
currentY = val[k + 1];
break;
- case 'z': // closepath - Close the current subpath
- case 'Z': // closepath - Close the current subpath
- path.close();
- break;
case 'h': // horizontal lineto - Draws a horizontal line (relative)
path.rLineTo(val[k + 0], 0);
currentX += val[k + 0];
@@ -526,6 +537,8 @@
current[1] = currentY;
current[2] = ctrlPointX;
current[3] = ctrlPointY;
+ current[4] = currentSegmentStartX;
+ current[5] = currentSegmentStartY;
}
private static void drawArc(Path p,
diff --git a/core/java/android/view/InputEvent.java b/core/java/android/view/InputEvent.java
index 1ecdf30..e2ad3ad 100644
--- a/core/java/android/view/InputEvent.java
+++ b/core/java/android/view/InputEvent.java
@@ -196,6 +196,13 @@
public abstract long getEventTimeNano();
/**
+ * Marks the input event as being canceled.
+ *
+ * @hide
+ */
+ public abstract void cancel();
+
+ /**
* Gets the unique sequence number of this event.
* Every input event that is created or received by a process has a
* unique sequence number. Moreover, a new sequence number is obtained
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index 0701b53..243a0fc 100644
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -2304,6 +2304,16 @@
}
/**
+ * Set {@link #FLAG_CANCELED} flag for the key event.
+ *
+ * @hide
+ */
+ @Override
+ public final void cancel() {
+ mFlags |= FLAG_CANCELED;
+ }
+
+ /**
* Call this during {@link Callback#onKeyDown} to have the system track
* the key through its final up (possibly including a long press). Note
* that only one key can be tracked at a time -- if another key down
diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java
index ae39b7a..1c5c41c 100644
--- a/core/java/android/view/MotionEvent.java
+++ b/core/java/android/view/MotionEvent.java
@@ -3168,6 +3168,12 @@
return ev;
}
+ /** @hide */
+ @Override
+ public final void cancel() {
+ setAction(ACTION_CANCEL);
+ }
+
public void writeToParcel(Parcel out, int flags) {
out.writeInt(PARCEL_TOKEN_MOTION_EVENT);
nativeWriteToParcel(mNativePtr, out);
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 5fc37c0..77c1d7b 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -5901,6 +5901,12 @@
region.op(interactiveRegion, Region.Op.INTERSECT);
}
+ // Take into account the window bounds.
+ final View root = getRootView();
+ if (root != null) {
+ region.op(dx, dy, root.getWidth() + dx, root.getHeight() + dy, Region.Op.INTERSECT);
+ }
+
// If the view is completely covered, done.
if (region.isEmpty()) {
return false;
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 5d2a24b..fe17417 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -3596,12 +3596,19 @@
if (mView == null || !mAdded) {
Slog.w(TAG, "Dropping event due to root view being removed: " + q.mEvent);
return true;
- } else if (!mAttachInfo.mHasWindowFocus &&
- !q.mEvent.isFromSource(InputDevice.SOURCE_CLASS_POINTER) &&
- !isTerminalInputEvent(q.mEvent)) {
- // If this is a focused event and the window doesn't currently have input focus,
- // then drop this event. This could be an event that came back from the previous
- // stage but the window has lost focus in the meantime.
+ } else if ((!mAttachInfo.mHasWindowFocus || mStopped)
+ && !q.mEvent.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) {
+ // This is a focus event and the window doesn't currently have input focus or
+ // has stopped. This could be an event that came back from the previous stage
+ // but the window has lost focus or stopped in the meantime.
+ if (isTerminalInputEvent(q.mEvent)) {
+ // Don't drop terminal input events, however mark them as canceled.
+ q.mEvent.cancel();
+ Slog.w(TAG, "Cancelling event due to no window focus: " + q.mEvent);
+ return false;
+ }
+
+ // Drop non-terminal input events.
Slog.w(TAG, "Dropping event due to no window focus: " + q.mEvent);
return true;
}
diff --git a/core/java/android/widget/AutoCompleteTextView.java b/core/java/android/widget/AutoCompleteTextView.java
index 3b16aba..e6392b9 100644
--- a/core/java/android/widget/AutoCompleteTextView.java
+++ b/core/java/android/widget/AutoCompleteTextView.java
@@ -1005,6 +1005,12 @@
@Override
protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
super.onFocusChanged(focused, direction, previouslyFocusedRect);
+
+ if (mTemporaryDetach) {
+ // If we are temporarily in the detach state, then do nothing.
+ return;
+ }
+
// Perform validation if the view is losing focus.
if (!focused) {
performValidation();
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 0917b32..5e83602 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -287,9 +287,11 @@
private int mCurTextColor;
private int mCurHintTextColor;
private boolean mFreezesText;
- private boolean mTemporaryDetach;
private boolean mDispatchTemporaryDetach;
+ /** Whether this view is temporarily detached from the parent view. */
+ boolean mTemporaryDetach;
+
private Editable.Factory mEditableFactory = Editable.Factory.getInstance();
private Spannable.Factory mSpannableFactory = Spannable.Factory.getInstance();
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index b03103e..4d6fc9c 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2895,6 +2895,12 @@
android:description="@string/permdesc_removeDrmCertificates"
android:protectionLevel="signature|system" />
+ <!-- Must be required by a {@link android.service.carriermessaging.CarrierMessagingService}.
+ Any service that filters for this intent must be a carrier privileged app. -->
+ <permission android:name="android.permission.BIND_CARRIER_MESSAGING_SERVICE"
+ android:label="@string/permlab_bindCarrierMessagingService"
+ android:description="@string/permdesc_bindCarrierMessagingService" />
+
<!-- The system process is explicitly the only one allowed to launch the
confirmation UI for full backup/restore -->
<uses-permission android:name="android.permission.CONFIRM_FULL_BACKUP"/>
diff --git a/core/res/res/drawable/vector_drawable_progress_indeterminate_horizontal.xml b/core/res/res/drawable/vector_drawable_progress_indeterminate_horizontal.xml
index aa75a7a..912b5bf 100644
--- a/core/res/res/drawable/vector_drawable_progress_indeterminate_horizontal.xml
+++ b/core/res/res/drawable/vector_drawable_progress_indeterminate_horizontal.xml
@@ -27,7 +27,7 @@
android:name="background_track"
android:pathData="M -180.0,-1.0 l 360.0,0 l 0,2.0 l -360.0,0 Z"
android:fillColor="?attr/colorControlActivated"
- android:fillAlpha="0.1"/>
+ android:fillAlpha="?attr/disabledAlpha"/>
<group
android:name="rect2_grp"
android:translateX="-197.60001"
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index d6bc38f..0cc007b 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -2344,6 +2344,11 @@
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_removeDrmCertificates">Allows an application to remove DRM certficates. Should never be needed for normal apps.</string>
+ <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permlab_bindCarrierMessagingService">bind to a carrier messaging service</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_bindCarrierMessagingService">Allows the holder to bind to the top-level interface of a carrier messaging service. Should never be needed for normal apps.</string>
+
<!-- Policy administration -->
<!-- Title of policy access to limiting the user's password choices -->
diff --git a/docs/html/google/gcm/ccs.jd b/docs/html/google/gcm/ccs.jd
index 7db7a74..6332b8d 100644
--- a/docs/html/google/gcm/ccs.jd
+++ b/docs/html/google/gcm/ccs.jd
@@ -263,6 +263,21 @@
</message>
</pre>
+<p>Device Message Rate Exceeded:</p>
+
+<pre><message id="...">
+ <gcm xmlns="google:mobile:data">
+ {
+ "message_type":"nack",
+ "message_id":"msgId1",
+ "from":"REGID",
+ "error":"DEVICE_MESSAGE_RATE_EXCEEDED",
+ "error_description":"Downstream message rate exceeded for this registration id"
+ }
+ </gcm>
+</message>
+</pre>
+
<p>The following table lists NACK error codes. Unless otherwise
indicated, a NACKed message should not be retried. Unexpected NACK error codes
should be treated the same as {@code INTERNAL_SERVER_ERROR}.</p>
@@ -303,8 +318,7 @@
<td>{@code DEVICE_MESSAGE_RATE_EXCEEDED}</td>
<td>The rate of messages to a particular device is too high. You should reduce
the number of messages sent to this device and should not immediately retry
-sending to this device. This error code replaces {@code QUOTA_EXCEEDED},
-which has been deprecated.</td>
+sending to this device. This error code is replacing {@code QUOTA_EXCEEDED}.</td>
</tr>
<tr>
<td>{@code SERVICE_UNAVAILABLE}</td>
diff --git a/docs/html/google/gcm/client.jd b/docs/html/google/gcm/client.jd
index 70109c6..d44ee3c 100644
--- a/docs/html/google/gcm/client.jd
+++ b/docs/html/google/gcm/client.jd
@@ -452,6 +452,21 @@
editor.commit();
}</pre>
+<h4 id="reg-errors">Handle registration errors</h4>
+
+<p>As stated above, an Android app must register with GCM servers and get a registration ID
+(regID) before it can receive messages. A given regID is not guaranteed to last indefinitely,
+so the first thing your app should always do is check to make sure it has a valid regID
+(as shown in the code snippets above).</p>
+
+<p>In addition to confirming that it has a valid regID, your app should be prepared to handle
+the registration error {@code TOO_MANY_REGISTRATIONS}. This error indicates that the device
+has too many apps registered with GCM. The error only occurs in cases where there are
+extreme numbers of apps, so it should not affect the average user. The remedy is to prompt
+the user to delete some of the other GCM-enabled apps from the device to make
+room for the new one.</p>
+
+
<h3 id="sample-send">Send a message</h3>
<p>When the user clicks the app's <strong>Send</strong> button, the app sends an
upstream message using the
diff --git a/docs/html/samples/new/index.jd b/docs/html/samples/new/index.jd
index 330caa3..ba75072 100644
--- a/docs/html/samples/new/index.jd
+++ b/docs/html/samples/new/index.jd
@@ -12,99 +12,229 @@
</p>
-<h3 id="BasicManagedProfile">BasicManagedProfile</h3>
-<div class="figure" style="width:220px">
- <img src="{@docRoot}samples/images/BasicManagedProfile.png"
- srcset="{@docRoot}samples/images/BasicManagedProfile@2x.png 2x"
- alt="" height="375" />
- <p class="img-caption">
- <strong>Figure 1.</strong> The BasicManagedProfile sample app.
- </p>
-</div>
+<!-- NOTE TO EDITORS: add most recent samples first -->
-<p>This sample demonstrates how to create a managed profile. You can also:</p>
-<ul>
- <li>Enable or disable other apps, and set restrictions on them.</li>
- <li>Configure intents to be forwarded between the primary account and the
- managed profile.</li>
- <li>Wipe all the data associated with the managed profile.</li>
-</ul>
+<h3 id="MediaBrowserService">Media Browser Service</h3>
-<p class="note"><strong>Note:</strong> There can be only one managed profile on
- a device at a time.</p>
+<p>
+This sample is a simple audio media app that exposes its media
+library and provides metadata and playback controls through the new
+MediaBrowserService and MediaSession APIs from API 21.
+The sample is compatible with Android Auto and also provides a basic UI
+when not connected to a car.
+</p>
-<p><a href="http://github.com/googlesamples/android-BasicManagedProfile">Get it on GitHub</a></p>
+<p class="note">
+ <strong>Note:</strong> This sample is compatible with <a
+ href="http://android.com/auto">Android Auto</a>.
+</p>
-<h3 id="Camera2Basic">Camera2Basic</h3>
+<p><a href="http://github.com/googlesamples/android-MediaBrowserService">Get it on GitHub</a></p>
+
+
+<h3 id="MessagingService">Messaging Service</h3>
+
+<p>
+This sample shows a simple service that sends notifications using
+NotificationCompat. In addition to sending a notification, it also extends
+the notification with a CarExtender to make it compatible with Android Auto.
+Each unread conversation from a user is sent as a distinct notification.
+</p>
+
+<p class="note">
+ <strong>Note:</strong> This sample is compatible with <a
+ href="http://android.com/auto">Android Auto</a>.
+</p>
+
+<p><a href="http://github.com/googlesamples/android-MessagingService">Get it on GitHub</a></p>
+
+
+<h3 id="SpeedTracker">Speed Tracker (Wear)</h3>
+
+<p>
+This sample uses the FusedLocation APIs of Google Play Services on Android Wear
+devices that have a hardware GPS built in. In those cases, this sample provides
+a simple screen that shows the current speed of the wearable device. User can
+set a speed limit and if the speed approaches that limit, it changes the color
+to yellow and if it exceeds the limit, it turns red. User can also enable
+recording of coordinates and when it pairs back with the phone, this data
+is synced with the phone component of the app and user can see a track
+made of those coordinates on a map on the phone.
+</p>
+
+<p><a href="http://github.com/googlesamples/android-SpeedTracker">Get it on GitHub</a></p>
+
+
+<h3 id="AppRestrictionSchema">AppRestrictionSchema</h3>
+
+<p>
+This sample shows how to use app restrictions. This application has one boolean
+restriction with a key "can_say_hello" that defines whether the only feature of this
+app (press the button to show "Hello" message) is enabled or disabled. Use
+AppRestrictionEnforcer sample to toggle the restriction.
+</p>
+
+<p><a href="http://github.com/googlesamples/android-AppRestrictionSchema">Get it on GitHub</a></p>
+
+
+<h3 id="AppRestrictionEnforcer">AppRestrictionEnforcer</h3>
+
+<p>
+This sample demonstrates how to set restrictions to other apps as a profile owner.
+Use AppRestrictionSchema sample as a app with available restrictions.
+</p>
+
+<p><a href="http://github.com/googlesamples/android-AppRestrictionEnforcer">Get it on GitHub</a></p>
+
+
+<h3 id="DocumentCentricRelinquishIdentity">DocumentCentricRelinquishIdentity</h3>
+
+<p>
+This sample shows how to relinquish identity to activities above it in the task stack.
+</p>
+
+<p><a href="http://github.com/googlesamples/android-DocumentCentricRelinquishIdentity">Get it on GitHub</a></p>
+
+
+<h3 id="DocumentCentricApps">DocumentCentricApps</h3>
+
+<p>
+This sample shows the basic usage of the new "Document Centric Apps" API.
+It let's you create new documents in the system overview menu and persists its
+state through reboots. If "Task per document" is checked a new task will be
+created for every new document in the overview menu.
+</p>
+
+<p><a href="http://github.com/googlesamples/android-DocumentCentricApps">Get it on GitHub</a></p>
+
+
+<h3 id="HdrViewfinder">HdrViewfinder</h3>
+
+<p>
+This demo implements a real-time high-dynamic-range camera viewfinder, by alternating
+the sensor's exposure time between two exposure values on even and odd frames, and then
+compositing together the latest two frames whenever a new frame is captured.
+</p>
+
+<p><a href="http://github.com/googlesamples/android-HdrViewfinder">Get it on GitHub</a></p>
+
+
+<h3 id="Interpolator">Interpolator</h3>
+
+<p>
+This sample demonstrates the use of animation interpolators and path animations for
+Material Design. It shows how an ObjectAnimator is used to animate two properties of a
+view (scale X and Y) along a path.
+</p>
+
+<p><a href="http://github.com/googlesamples/android-Interpolator">Get it on GitHub</a></p>
+
+
+<h3 id="DrawableTinting">DrawableTinting</h3>
+
+<p>Sample that shows applying tinting and color filters to Drawables both programmatically
+and as Drawable resources in XML.</p>
+<p>Tinting is set on a nine-patch drawable through the "tint" and "tintMode" parameters.
+A color state list is referenced as the tint color, which defines colors for different
+states of a View (for example disabled/enabled, focused, pressed or selected).</p>
+<p>Programmatically, tinting is applied to a Drawable through its "setColorFilter" method,
+with a reference to a color and a PorterDuff blend mode. The color and blend mode can be
+changed from the UI to see the effect of different options.</p>
+
+<p><a href="http://github.com/googlesamples/android-DrawableTinting">Get it on GitHub</a></p>
+
+
+<h3 id="LNotifications">LNotifications</h3>
+
+<p>
+This sample demonstrates how new features for notifications introduced in Android 5.0
+are used such as Heads-Up notifications, visibility, people, category and priority
+metadata. </p>
+<p><a href="http://github.com/googlesamples/android-LNotifications">Get it on GitHub</a></p>
+
+
+<h3 id="CardView">CardView</h3>
+
+<p>
+This sample demonstrates how to use the CardView UI widget introduced in Android 5.0, using the support library for backward compatibility.
+</p>
+
+<p><a href="http://github.com/googlesamples/android-CardView">Get it on GitHub</a></p>
+
+
+<h3 id="RecyclerView">RecyclerView</h3>
+
+<p>
+Demonstration of using RecyclerView with a LayoutManager to create a vertical ListView.
+</p>
+
+<p><a href="http://github.com/googlesamples/android-RecyclerView">Get it on GitHub</a></p>
+
+
+<h3 id="RevealEffectBasic">RevealEffectBasic</h3>
+
+<p>
+A sample demonstrating how to perform a reveal effect for UI elements within the Material Design framework.
+</p>
+
+<p><a href="http://github.com/googlesamples/android-RevealEffectBasic">Get it on GitHub</a></p>
+
+
+<h3 id="FloatingActionButtonBasic">FloatingActionButtonBasic</h3>
+
+<p>
+This sample shows the two sizes of Floating Action Buttons and how to interact with
+them.
+</p>
+
+<p><a href="http://github.com/googlesamples/android-FloatingActionButtonBasic">Get it on GitHub</a></p>
+
<!--
+<h3 id="">SampleName</h3>
+
<div class="figure" style="width:220px">
<img src="" srcset="@2x.png 2x" alt="" height="375" />
<p class="img-caption">
<strong>Figure n.</strong> Single sentence summarizing the figure.
</p>
</div>
+
+<p>
+**description**
+</p>
-->
-<p>This sample demonstrates the basic use of the Camera2 API. The sample code
-demonstrates how you can display camera preview and take pictures.</p>
-<p><a href="http://github.com/googlesamples/android-Camera2Basic">Get it on GitHub</a></p>
-
-
-<h3 id="Camera2Video">Camera2Video</h3>
+<h3 id="NavigationDrawerSample">NavigationDrawerSample</h3>
<!--
<div class="figure" style="width:220px">
-<img src="" srcset="@2x.png 2x" alt="" height="375" />
- <p class="img-caption">
- <strong>Figure n.</strong> Single sentence summarizing the figure.
- </p>
-</div>
--->
-
-<p>This sample demonstrates how to record video using the Camera2 API.</p>
-
-<p><a href="http://github.com/googlesamples/android-Camera2Video">Get it on GitHub</a></p>
-
-<h3 id="ActivitySceneTransitionBasic">ActivitySceneTransitionBasic</h3>
-<div class="figure" style="width:220px">
- <img src="{@docRoot}samples/images/ActivitySceneTransitionBasic.png"
- srcset="{@docRoot}samples/images/ActivitySceneTransitionBasic@2x.png 2x"
- alt="" height="375" />
+ <img src="" srcset="@2x.png 2x" alt="" height="375" />
<p class="img-caption">
- <strong>Figure 2.</strong> The ActivitySceneTransitionBasic sample app.
- </p>
- </div>
-
-<p> This sample demonstrates how to the use {@link android.app.Activity} scene
-transitions when transitioning from one activity to another. Uses a combination
-of <code>moveImage</code> and <code>changeBounds</code> to nicely transition
-from a grid of images to an activity with a large image and detail text. </p>
-
-<p><a href="http://github.com/googlesamples/android-ActivitySceneTransition">Get it on GitHub</a></p>
-
-<h3 id="ElevationBasic">ElevationBasic</h3>
-<!--
-<div class="figure" style="width:220px">
-<img src="" srcset="@2x.png 2x" alt="" height="375" />
- <p class="img-caption">
<strong>Figure n.</strong> Single sentence summarizing the figure.
</p>
</div>
-->
<p>
-This sample demonstrates two alternative ways to move a view in the z-axis:</p>
+This sample illustrates a common usage of the Android support library's
+{@link android.support.v4.widget.DrawerLayout} widget.
+</p>
-<ul>
- <li>With a fixed elevation, using XML.</li>
- <li>Raising the elevation when the user taps on it, using
- <code>setTranslationZ()</code>.</li>
-</ul>
+<p><a href="http://github.com/googlesamples/android-NavigationDrawer">Get it on GitHub</a></p>
-<p><a href="http://github.com/googlesamples/android-ElevationBasic">Get it on GitHub</a></p>
-<h3 id="ElevationDrag">ElevationDrag</h3>
+<h3 id="JobSchedulerSample">JobSchedulerSample</h3>
+
+<p>
+This sample app allows the user to schedule jobs through the UI, and shows
+visual cues when the jobs are executed.
+</p>
+
+<p><a href="http://github.com/googlesamples/android-JobScheduler">Get it on GitHub</a></p>
+
+
+<h3 id="AndroidTVLeanbackSample">AndroidTVLeanbackSample</h3>
<!--
<div class="figure" style="width:220px">
<img src="" srcset="@2x.png 2x" alt="" height="375" />
@@ -114,11 +244,46 @@
</div>
-->
-<p>This sample demonstrates a drag and drop action on different shapes.
-Elevation and z-translation are used to render the shadows. The views are
-clipped using different outlines.</p>
+<p>
+This sample demonstrates use of the Android TV Leanback Support Library.
+</p>
-<p><a href="http://github.com/googlesamples/android-ElevationDrag">Get it on GitHub</a></p>
+<p><a href="http://github.com/googlesamples/androidtv-Leanback">Get it on GitHub</a></p>
+
+
+<h3 id="Visual-Game-Controller">Visual-Game-Controller</h3>
+<!--
+<div class="figure" style="width:220px">
+ <img src="" srcset="@2x.png 2x" alt="" height="375" />
+ <p class="img-caption">
+ <strong>Figure n.</strong> Single sentence summarizing the figure.
+ </p>
+</div>
+-->
+
+<p>
+This sample displays events received from a game controller shown on the screen.
+</p>
+
+<p><a href="http://github.com/googlesamples/androidtv-VisualGameController">Get it on GitHub</a></p>
+
+
+<h3 id="GameControllerSample">GameControllerSample</h3>
+<!--
+<div class="figure" style="width:220px">
+ <img src="" srcset="@2x.png 2x" alt="" height="375" />
+ <p class="img-caption">
+ <strong>Figure n.</strong> Single sentence summarizing the figure.
+ </p>
+</div>
+-->
+
+<p>
+This sample implements a multi-player game, demonstrating game controller input
+handling.
+</p>
+
+<p><a href="http://github.com/googlesamples/androidtv-GameController">Get it on GitHub</a></p>
<h3 id="ClippingBasic">ClippingBasic</h3>
@@ -146,7 +311,8 @@
</p>
</div>
-<h3 id="GameControllerSample">GameControllerSample</h3>
+
+<h3 id="ElevationDrag">ElevationDrag</h3>
<!--
<div class="figure" style="width:220px">
<img src="" srcset="@2x.png 2x" alt="" height="375" />
@@ -156,15 +322,70 @@
</div>
-->
+<p>This sample demonstrates a drag and drop action on different shapes.
+Elevation and z-translation are used to render the shadows. The views are
+clipped using different outlines.</p>
+
+<p><a href="http://github.com/googlesamples/android-ElevationDrag">Get it on GitHub</a></p>
+
+
+<h3 id="ElevationBasic">ElevationBasic</h3>
+<!--
+<div class="figure" style="width:220px">
+<img src="" srcset="@2x.png 2x" alt="" height="375" />
+ <p class="img-caption">
+ <strong>Figure n.</strong> Single sentence summarizing the figure.
+ </p>
+</div>
+-->
+
<p>
-This sample implements a multi-player game, demonstrating game controller input
-handling.
-</p>
+This sample demonstrates two alternative ways to move a view in the z-axis:</p>
-<p><a href="http://github.com/googlesamples/androidtv-GameController">Get it on GitHub</a></p>
+<ul>
+ <li>With a fixed elevation, using XML.</li>
+ <li>Raising the elevation when the user taps on it, using
+ <code>setTranslationZ()</code>.</li>
+</ul>
+
+<p><a href="http://github.com/googlesamples/android-ElevationBasic">Get it on GitHub</a></p>
-<h3 id="Visual-Game-Controller">Visual-Game-Controller</h3>
+<h3 id="ActivitySceneTransitionBasic">ActivitySceneTransitionBasic</h3>
+<div class="figure" style="width:220px">
+ <img src="{@docRoot}samples/images/ActivitySceneTransitionBasic.png"
+ srcset="{@docRoot}samples/images/ActivitySceneTransitionBasic@2x.png 2x"
+ alt="" height="375" />
+ <p class="img-caption">
+ <strong>Figure 2.</strong> The ActivitySceneTransitionBasic sample app.
+ </p>
+ </div>
+
+<p> This sample demonstrates how to the use {@link android.app.Activity} scene
+transitions when transitioning from one activity to another. Uses a combination
+of <code>moveImage</code> and <code>changeBounds</code> to nicely transition
+from a grid of images to an activity with a large image and detail text. </p>
+
+<p><a href="http://github.com/googlesamples/android-ActivitySceneTransition">Get it on GitHub</a></p>
+
+
+<h3 id="Camera2Video">Camera2Video</h3>
+<!--
+<div class="figure" style="width:220px">
+<img src="" srcset="@2x.png 2x" alt="" height="375" />
+ <p class="img-caption">
+ <strong>Figure n.</strong> Single sentence summarizing the figure.
+ </p>
+</div>
+-->
+
+<p>This sample demonstrates how to record video using the Camera2 API.</p>
+
+<p><a href="http://github.com/googlesamples/android-Camera2Video">Get it on GitHub</a></p>
+
+
+<h3 id="Camera2Basic">Camera2Basic</h3>
+
<!--
<div class="figure" style="width:220px">
<img src="" srcset="@2x.png 2x" alt="" height="375" />
@@ -174,192 +395,32 @@
</div>
-->
-<p>
-This sample displays events received from a game controller shown on the screen.
-</p>
+<p>This sample demonstrates the basic use of the Camera2 API. The sample code
+demonstrates how you can display camera preview and take pictures.</p>
-<p><a href="http://github.com/googlesamples/androidtv-VisualGameController">Get it on GitHub</a></p>
+<p><a href="http://github.com/googlesamples/android-Camera2Basic">Get it on GitHub</a></p>
-<h3 id="AndroidTVLeanbackSample">AndroidTVLeanbackSample</h3>
-<!--
+
+<h3 id="BasicManagedProfile">BasicManagedProfile</h3>
<div class="figure" style="width:220px">
- <img src="" srcset="@2x.png 2x" alt="" height="375" />
+ <img src="{@docRoot}samples/images/BasicManagedProfile.png"
+ srcset="{@docRoot}samples/images/BasicManagedProfile@2x.png 2x"
+ alt="" height="375" />
<p class="img-caption">
- <strong>Figure n.</strong> Single sentence summarizing the figure.
- </p>
-</div>
--->
-
-<p>
-This sample demonstrates use of the Android TV Leanback Support Library.
-</p>
-
-<p><a href="http://github.com/googlesamples/androidtv-Leanback">Get it on GitHub</a></p>
-
-<h3 id="JobSchedulerSample">JobSchedulerSample</h3>
-
-<p>
-This sample app allows the user to schedule jobs through the UI, and shows
-visual cues when the jobs are executed.
-</p>
-
-<p><a href="http://github.com/googlesamples/android-JobScheduler">Get it on GitHub</a></p>
-
-<h3 id="NavigationDrawerSample">NavigationDrawerSample</h3>
-<!--
-<div class="figure" style="width:220px">
- <img src="" srcset="@2x.png 2x" alt="" height="375" />
- <p class="img-caption">
- <strong>Figure n.</strong> Single sentence summarizing the figure.
- </p>
-</div>
--->
-
-<p>
-This sample illustrates a common usage of the Android support library's
-{@link android.support.v4.widget.DrawerLayout} widget.
-</p>
-
-<p><a href="http://github.com/googlesamples/android-NavigationDrawer">Get it on GitHub</a></p>
-<!--
-<h3 id="">SampleName</h3>
-
-<div class="figure" style="width:220px">
- <img src="" srcset="@2x.png 2x" alt="" height="375" />
- <p class="img-caption">
- <strong>Figure n.</strong> Single sentence summarizing the figure.
+ <strong>Figure 1.</strong> The BasicManagedProfile sample app.
</p>
</div>
-<p>
-**description**
-</p>
--->
+<p>This sample demonstrates how to create a managed profile. You can also:</p>
+<ul>
+ <li>Enable or disable other apps, and set restrictions on them.</li>
+ <li>Configure intents to be forwarded between the primary account and the
+ managed profile.</li>
+ <li>Wipe all the data associated with the managed profile.</li>
+</ul>
-<h3 id="FloatingActionButtonBasic">FloatingActionButtonBasic</h3>
+<p class="note"><strong>Note:</strong> There can be only one managed profile on
+ a device at a time.</p>
-<p>
-This sample shows the two sizes of Floating Action Buttons and how to interact with
-them.
-</p>
+<p><a href="http://github.com/googlesamples/android-BasicManagedProfile">Get it on GitHub</a></p>
-<p><a href="http://github.com/googlesamples/android-FloatingActionButtonBasic">Get it on GitHub</a></p>
-
-<h3 id="RevealEffectBasic">RevealEffectBasic</h3>
-
-<p>
-A sample demonstrating how to perform a reveal effect for UI elements within the Material Design framework.
-</p>
-
-<p><a href="http://github.com/googlesamples/android-RevealEffectBasic">Get it on GitHub</a></p>
-
-<h3 id="RecyclerView">RecyclerView</h3>
-
-<p>
-Demonstration of using RecyclerView with a LayoutManager to create a vertical ListView.
-</p>
-
-<p><a href="http://github.com/googlesamples/android-RecyclerView">Get it on GitHub</a></p>
-
-<h3 id="CardView">CardView</h3>
-
-<p>
-This sample demonstrates how to use the CardView UI widget introduced in Android 5.0, using the support library for backward compatibility.
-</p>
-
-<p><a href="http://github.com/googlesamples/android-CardView">Get it on GitHub</a></p>
-
-<h3 id="LNotifications">LNotifications</h3>
-
-<p>
-This sample demonstrates how new features for notifications introduced in Android 5.0
-are used such as Heads-Up notifications, visibility, people, category and priority
-metadata. </p>
-<p><a href="http://github.com/googlesamples/android-LNotifications">Get it on GitHub</a></p>
-
-<h3 id="DrawableTinting">DrawableTinting</h3>
-
-<p>Sample that shows applying tinting and color filters to Drawables both programmatically
-and as Drawable resources in XML.</p>
-<p>Tinting is set on a nine-patch drawable through the "tint" and "tintMode" parameters.
-A color state list is referenced as the tint color, which defines colors for different
-states of a View (for example disabled/enabled, focused, pressed or selected).</p>
-<p>Programmatically, tinting is applied to a Drawable through its "setColorFilter" method,
-with a reference to a color and a PorterDuff blend mode. The color and blend mode can be
-changed from the UI to see the effect of different options.</p>
-
-<p><a href="http://github.com/googlesamples/android-DrawableTinting">Get it on GitHub</a></p>
-
-<h3 id="Interpolator">Interpolator</h3>
-
-<p>
-This sample demonstrates the use of animation interpolators and path animations for
-Material Design. It shows how an ObjectAnimator is used to animate two properties of a
-view (scale X and Y) along a path.
-</p>
-
-<p><a href="http://github.com/googlesamples/android-Interpolator">Get it on GitHub</a></p>
-
-<h3 id="HdrViewfinder">HdrViewfinder</h3>
-
-<p>
-This demo implements a real-time high-dynamic-range camera viewfinder, by alternating
-the sensor's exposure time between two exposure values on even and odd frames, and then
-compositing together the latest two frames whenever a new frame is captured.
-</p>
-
-<p><a href="http://github.com/googlesamples/android-HdrViewfinder">Get it on GitHub</a></p>
-
-<h3 id="DocumentCentricApps">DocumentCentricApps</h3>
-
-<p>
-This sample shows the basic usage of the new "Document Centric Apps" API.
-It let's you create new documents in the system overview menu and persists its
-state through reboots. If "Task per document" is checked a new task will be
-created for every new document in the overview menu.
-</p>
-
-<p><a href="http://github.com/googlesamples/android-DocumentCentricApps">Get it on GitHub</a></p>
-
-<h3 id="DocumentCentricRelinquishIdentity">DocumentCentricRelinquishIdentity</h3>
-
-<p>
-This sample shows how to relinquish identity to activities above it in the task stack.
-</p>
-
-<p><a href="http://github.com/googlesamples/android-DocumentCentricRelinquishIdentity">Get it on GitHub</a></p>
-
-<h3 id="AppRestrictionEnforcer">AppRestrictionEnforcer</h3>
-
-<p>
-This sample demonstrates how to set restrictions to other apps as a profile owner.
-Use AppRestrictionSchema sample as a app with available restrictions.
-</p>
-
-<p><a href="http://github.com/googlesamples/android-AppRestrictionEnforcer">Get it on GitHub</a></p>
-
-<h3 id="AppRestrictionSchema">AppRestrictionSchema</h3>
-
-<p>
-This sample shows how to use app restrictions. This application has one boolean
-restriction with a key "can_say_hello" that defines whether the only feature of this
-app (press the button to show "Hello" message) is enabled or disabled. Use
-AppRestrictionEnforcer sample to toggle the restriction.
-</p>
-
-<p><a href="http://github.com/googlesamples/android-AppRestrictionSchema">Get it on GitHub</a></p>
-
-<h3 id="SpeedTracker">Speed Tracker (Wear)</h3>
-
-<p>
-This sample uses the FusedLocation APIs of Google Play Services on Android Wear
-devices that have a hardware GPS built in. In those cases, this sample provides
-a simple screen that shows the current speed of the wearable device. User can
-set a speed limit and if the speed approaches that limit, it changes the color
-to yellow and if it exceeds the limit, it turns red. User can also enable
-recording of coordinates and when it pairs back with the phone, this data
-is synced with the phone component of the app and user can see a track
-made of those coordinates on a map on the phone.
-</p>
-
-<p><a href="http://github.com/googlesamples/android-SpeedTracker">Get it on GitHub</a></p>
diff --git a/docs/html/training/location/index.jd b/docs/html/training/location/index.jd
index 249c42d..f0024e2 100644
--- a/docs/html/training/location/index.jd
+++ b/docs/html/training/location/index.jd
@@ -21,7 +21,8 @@
<h2>You should also read</h2>
<ul>
<li>
- <a href="{@docRoot}google/play-services/setup.html">Setup Google Play Services SDK</a>
+ <a href="{@docRoot}google/play-services/setup.html">Set Up Google Play
+ Services SDK</a>
</li>
</ul>
@@ -29,68 +30,75 @@
</div>
<p>
- One of the unique features of mobile applications is location awareness. Mobile users bring
- their devices with them everywhere, and adding location awareness to your app offers users a
- more contextual experience. The new Location Services API available in Google Play services
- facilitates adding location awareness to your app with automated location tracking,
- geofencing, and activity recognition. This API adds significant advantages over the plaform's
- location API.
+ One of the unique features of mobile applications is location awareness.
+ Mobile users take their devices with them everywhere, and adding location
+ awareness to your app offers users a more contextual experience. The location
+ APIs available in Google Play services facilitate adding location awareness to
+ your app with automated location tracking, geofencing, and activity
+ recognition.
</p>
+
+<p>The
+ <a href="{@docRoot}reference/com/google/android/gms/location/package-summary.html">Google
+ Play services location APIs</a> are preferred over the Android framework
+ location APIs
+ (<a href="{@docRoot}reference/android/location/package-summary.html">android.location</a>)
+ as a way of adding location awareness to your app. If you are currently using
+ the Android framework location APIs, you are strongly encouraged to switch to
+ the Google Play services location APIs as soon as possible.
+</p>
+
<p>
- This class shows you how to use Location Services in your app to get the current location,
- get periodic location updates, look up addresses, create and monitor geofences, and
- detect user activities. The class includes sample apps and code snippets that you can use as a
- starting point for adding location awareness to your own app.
+ This class shows you how to use the Google Play services location APIs in your
+ app to get the current location, get periodic location updates, look up
+ addresses, create and monitor geofences, and detect user activities. The class
+ includes sample apps and code snippets that you can use as a starting point
+ for adding location awareness to your app.
</p>
+
<p class="note">
- <strong>Note:</strong> Since this class is based on the Google Play services client library,
- make sure you install the latest version before using the sample apps or code snippets. To learn
- how to set up the client library with the latest version, see
- <a href="{@docRoot}google/play-services/setup.html">Setup</a> in the Google Play services guide.
+ <strong>Note:</strong> Since this class is based on the Google Play services
+ client library, make sure you install the latest version before using the
+ sample apps or code snippets. To learn how to set up the client library with
+ the latest version, see
+ <a href="{@docRoot}google/play-services/setup.html">Setup</a> in the Google
+ Play services guide.
</p>
<h2>Lessons</h2>
<dl>
- <dt>
- <b><a href="retrieve-current.html">Retrieving the Current Location</a></b>
- </dt>
- <dd>
- Learn how to retrieve the user's current location.
- </dd>
- <dt>
- <b><a href="receive-location-updates.html">Receiving Location Updates</a></b>
- </dt>
- <dd>
- Learn how to request and receive periodic location updates.
- </dd>
- <dt>
- <b><a href="display-address.html">Displaying a Location Address</a></b>
- </dt>
- <dd>
- Learn how to convert a location's latitude and longitude into an address (reverse
- geocoding).
- </dd>
- <dt>
- <b>
- <a href="geofencing.html">Creating and Monitoring Geofences</a>
- </b>
- </dt>
- <dd>
- Learn how to define one or more geographic areas as locations of interest, called geofences,
- and detect when the user is close to or inside a geofence.
- </dd>
- <dt>
- <b><a href="activity-recognition.html">Recognizing the User's Current Activity</a></b>
- </dt>
- <dd>
- Learn how to recognize the user's current activity, such as walking, bicycling,
- or driving a car, and how to use this information to modify your app's location strategy.
- </dd>
- <dt>
- <b><a href="location-testing.html">Testing Using Mock Locations</a></b>
- </dt>
- <dd>
- Learn how to test a location-aware app by injecting mock locations into Location
- Services. In mock mode, Location Services sends out mock locations that you inject instead
- of sensor-based locations.
- </dd>
+ <dt>
+ <b><a href="retrieve-current.html">Retrieving the Current Location</a></b>
+ </dt> <dd>
+ Learn how to retrieve the user's current location.
+ </dd> <dt>
+ <b><a href="receive-location-updates.html">Receiving Location
+ Updates</a></b>
+ </dt> <dd>
+ Learn how to request and receive periodic location updates.
+ </dd> <dt>
+ <b><a href="display-address.html">Displaying a Location Address</a></b>
+ </dt> <dd>
+ Learn how to convert a location's latitude and longitude into an address
+ (reverse geocoding).
+ </dd> <dt>
+ <b>
+ <a href="geofencing.html">Creating and Monitoring Geofences</a>
+ </b>
+ </dt> <dd>
+ Learn how to define one or more geographic areas as locations of interest,
+ called geofences, and detect when the user is close to or inside a geofence.
+ </dd> <dt>
+ <b><a href="activity-recognition.html">Recognizing the User's Current
+ Activity</a></b>
+ </dt> <dd>
+ Learn how to recognize the user's current activity, such as walking,
+ bicycling, or driving a car, and how to use this information to modify your
+ app's location strategy.
+ </dd> <dt>
+ <b><a href="location-testing.html">Testing Using Mock Locations</a></b>
+ </dt> <dd>
+ Learn how to test a location-aware app by injecting mock locations into
+ Location Services. In mock mode, Location Services sends out mock locations
+ that you inject instead of sensor-based locations.
+ </dd>
</dl>
diff --git a/graphics/java/android/graphics/Outline.java b/graphics/java/android/graphics/Outline.java
index 4bf0b71..f76184f 100644
--- a/graphics/java/android/graphics/Outline.java
+++ b/graphics/java/android/graphics/Outline.java
@@ -221,4 +221,15 @@
mRect = null;
mRadius = -1.0f;
}
+
+ /**
+ * Offsets the Outline by (dx,dy)
+ */
+ public void offset(int dx, int dy) {
+ if (mRect != null) {
+ mRect.offset(dx, dy);
+ } else if (mPath != null) {
+ mPath.offset(dx, dy);
+ }
+ }
}
diff --git a/graphics/java/android/graphics/Path.java b/graphics/java/android/graphics/Path.java
index c40a66d..0e9823d 100644
--- a/graphics/java/android/graphics/Path.java
+++ b/graphics/java/android/graphics/Path.java
@@ -678,7 +678,7 @@
}
/**
- * Offset the path by (dx,dy), returning true on success
+ * Offset the path by (dx,dy)
*
* @param dx The amount in the X direction to offset the entire path
* @param dy The amount in the Y direction to offset the entire path
@@ -695,7 +695,7 @@
}
/**
- * Offset the path by (dx,dy), returning true on success
+ * Offset the path by (dx,dy)
*
* @param dx The amount in the X direction to offset the entire path
* @param dy The amount in the Y direction to offset the entire path
diff --git a/graphics/java/android/graphics/drawable/RotateDrawable.java b/graphics/java/android/graphics/drawable/RotateDrawable.java
index 3304b33..1ee44fb 100644
--- a/graphics/java/android/graphics/drawable/RotateDrawable.java
+++ b/graphics/java/android/graphics/drawable/RotateDrawable.java
@@ -497,6 +497,7 @@
state.mFromDegrees = a.getFloat(R.styleable.RotateDrawable_fromDegrees, state.mFromDegrees);
state.mToDegrees = a.getFloat(R.styleable.RotateDrawable_toDegrees, state.mToDegrees);
+ state.mCurrentDegrees = state.mFromDegrees;
final Drawable dr = a.getDrawable(R.styleable.RotateDrawable_drawable);
if (dr != null) {
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index afa0b6e..91b1018 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -37,6 +37,7 @@
import android.os.PowerManager;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.provider.Settings;
import android.system.ErrnoException;
import android.system.OsConstants;
import android.util.Log;
@@ -968,11 +969,16 @@
* @throws IllegalStateException if it is called in an invalid state
*/
public void setDataSource(Context context, Uri uri, Map<String, String> headers)
- throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
- String scheme = uri.getScheme();
- if(scheme == null || scheme.equals("file")) {
+ throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
+ final String scheme = uri.getScheme();
+ if (ContentResolver.SCHEME_FILE.equals(scheme)) {
setDataSource(uri.getPath());
return;
+ } else if (ContentResolver.SCHEME_CONTENT.equals(scheme)
+ && Settings.AUTHORITY.equals(uri.getAuthority())) {
+ // Redirect ringtones to go directly to underlying provider
+ uri = RingtoneManager.getActualDefaultRingtoneUri(context,
+ RingtoneManager.getDefaultType(uri));
}
AssetFileDescriptor fd = null;
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 34e57bc..6828301 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -37,13 +37,11 @@
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
-import android.content.res.AssetFileDescriptor;
import android.database.AbstractCursor;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteQueryBuilder;
-import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
@@ -54,7 +52,6 @@
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
-import android.provider.MediaStore;
import android.provider.Settings;
import android.provider.Settings.Secure;
import android.text.TextUtils;
@@ -1228,77 +1225,8 @@
@Override
public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
-
- /*
- * When a client attempts to openFile the default ringtone or
- * notification setting Uri, we will proxy the call to the current
- * default ringtone's Uri (if it is in the media provider).
- */
- int ringtoneType = RingtoneManager.getDefaultType(uri);
- // Above call returns -1 if the Uri doesn't match a default type
- if (ringtoneType != -1) {
- Context context = getContext();
-
- // Get the current value for the default sound
- Uri soundUri = RingtoneManager.getActualDefaultRingtoneUri(context, ringtoneType);
-
- if (soundUri != null) {
- // Proxy the openFile call to media provider
- String authority = soundUri.getAuthority();
- if (authority.equals(MediaStore.AUTHORITY)) {
- return context.getContentResolver().openFileDescriptor(soundUri, mode);
- }
- }
- }
-
- return super.openFile(uri, mode);
- }
-
- @Override
- public AssetFileDescriptor openAssetFile(Uri uri, String mode) throws FileNotFoundException {
-
- /*
- * When a client attempts to openFile the default ringtone or
- * notification setting Uri, we will proxy the call to the current
- * default ringtone's Uri (if it is in the media provider).
- */
- int ringtoneType = RingtoneManager.getDefaultType(uri);
- // Above call returns -1 if the Uri doesn't match a default type
- if (ringtoneType != -1) {
- Context context = getContext();
-
- // Get the current value for the default sound
- Uri soundUri = RingtoneManager.getActualDefaultRingtoneUri(context, ringtoneType);
-
- if (soundUri != null) {
- // Proxy the openFile call to media provider
- String authority = soundUri.getAuthority();
- if (authority.equals(MediaStore.AUTHORITY)) {
- ParcelFileDescriptor pfd = null;
- try {
- pfd = context.getContentResolver().openFileDescriptor(soundUri, mode);
- return new AssetFileDescriptor(pfd, 0, -1);
- } catch (FileNotFoundException ex) {
- // fall through and open the fallback ringtone below
- }
- }
-
- try {
- return super.openAssetFile(soundUri, mode);
- } catch (FileNotFoundException ex) {
- // Since a non-null Uri was specified, but couldn't be opened,
- // fall back to the built-in ringtone.
- return context.getResources().openRawResourceFd(
- com.android.internal.R.raw.fallbackring);
- }
- }
- // no need to fall through and have openFile() try again, since we
- // already know that will fail.
- throw new FileNotFoundException(); // or return null ?
- }
-
- // Note that this will end up calling openFile() above.
- return super.openAssetFile(uri, mode);
+ throw new FileNotFoundException("Direct file access no longer supported; "
+ + "ringtone playback is available through android.media.Ringtone");
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
index b325653..ed6ddd2 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
@@ -244,7 +244,7 @@
}
private void setExitCondition(Condition exitCondition) {
- if (sameConditionId(mExitCondition, exitCondition)) return;
+ if (Objects.equals(mExitCondition, exitCondition)) return;
mExitCondition = exitCondition;
refreshExitConditionText();
updateWidgets();
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index b670584..f9a6359 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -998,6 +998,10 @@
}
break;
case MULTI_PRESS_POWER_BRIGHTNESS_BOOST:
+ Slog.i(TAG, "Starting brightness boost.");
+ if (!interactive) {
+ wakeUpFromPowerKey(eventTime);
+ }
mPowerManager.boostScreenBrightness(eventTime);
break;
}
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index d480f68..85eed859 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -77,7 +77,6 @@
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.FgThread;
-
import com.google.android.collect.Lists;
import com.google.android.collect.Sets;
@@ -1043,7 +1042,8 @@
}
@Override
- public void removeAccount(IAccountManagerResponse response, Account account) {
+ public void removeAccount(IAccountManagerResponse response, Account account,
+ boolean expectActivityLaunch) {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "removeAccount: " + account
+ ", response " + response
@@ -1088,7 +1088,7 @@
}
try {
- new RemoveAccountSession(accounts, response, account).bind();
+ new RemoveAccountSession(accounts, response, account, expectActivityLaunch).bind();
} finally {
restoreCallingIdentity(identityToken);
}
@@ -1096,7 +1096,7 @@
@Override
public void removeAccountAsUser(IAccountManagerResponse response, Account account,
- int userId) {
+ boolean expectActivityLaunch, int userId) {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "removeAccount: " + account
+ ", response " + response
@@ -1145,7 +1145,30 @@
}
try {
- new RemoveAccountSession(accounts, response, account).bind();
+ new RemoveAccountSession(accounts, response, account, expectActivityLaunch).bind();
+ } finally {
+ restoreCallingIdentity(identityToken);
+ }
+ }
+
+ @Override
+ public boolean removeAccountExplicitly(Account account) {
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ Log.v(TAG, "removeAccountExplicitly: " + account
+ + ", caller's uid " + Binder.getCallingUid()
+ + ", pid " + Binder.getCallingPid());
+ }
+ if (account == null) throw new IllegalArgumentException("account is null");
+ checkAuthenticateAccountsPermission(account);
+
+ UserAccounts accounts = getUserAccountsForCaller();
+ int userId = Binder.getCallingUserHandle().getIdentifier();
+ if (!canUserModifyAccounts(userId) || !canUserModifyAccountsForType(userId, account.type)) {
+ return false;
+ }
+ long identityToken = clearCallingIdentity();
+ try {
+ return removeAccountInternal(accounts, account);
} finally {
restoreCallingIdentity(identityToken);
}
@@ -1154,8 +1177,8 @@
private class RemoveAccountSession extends Session {
final Account mAccount;
public RemoveAccountSession(UserAccounts accounts, IAccountManagerResponse response,
- Account account) {
- super(accounts, response, account.type, false /* expectActivityLaunch */,
+ Account account, boolean expectActivityLaunch) {
+ super(accounts, response, account.type, expectActivityLaunch,
true /* stripAuthTokenFromResult */);
mAccount = account;
}
@@ -1203,10 +1226,12 @@
removeAccountInternal(getUserAccountsForCaller(), account);
}
- private void removeAccountInternal(UserAccounts accounts, Account account) {
+ private boolean removeAccountInternal(UserAccounts accounts, Account account) {
+ int deleted;
synchronized (accounts.cacheLock) {
final SQLiteDatabase db = accounts.openHelper.getWritableDatabase();
- db.delete(TABLE_ACCOUNTS, ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?",
+ deleted = db.delete(TABLE_ACCOUNTS, ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE
+ + "=?",
new String[]{account.name, account.type});
removeAccountFromCacheLocked(accounts, account);
sendAccountsChangedBroadcast(accounts.userId);
@@ -1226,6 +1251,7 @@
Binder.restoreCallingIdentity(id);
}
}
+ return (deleted > 0);
}
@Override
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 81cd94b..8cfb4b3 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -582,11 +582,8 @@
state = mPowerState.getScreenState();
// Use zero brightness when screen is off.
- // Use full brightness when screen brightness is boosted.
if (state == Display.STATE_OFF) {
brightness = PowerManager.BRIGHTNESS_OFF;
- } else if (mPowerRequest.boostScreenBrightness) {
- brightness = PowerManager.BRIGHTNESS_ON;
}
// Configure auto-brightness.
@@ -601,6 +598,16 @@
mPowerRequest.screenAutoBrightnessAdjustment, state != Display.STATE_ON);
}
+ // Apply brightness boost.
+ // We do this here after configuring auto-brightness so that we don't
+ // disable the light sensor during this temporary state. That way when
+ // boost ends we will be able to resume normal auto-brightness behavior
+ // without any delay.
+ if (mPowerRequest.boostScreenBrightness
+ && brightness != PowerManager.BRIGHTNESS_OFF) {
+ brightness = PowerManager.BRIGHTNESS_ON;
+ }
+
// Apply auto-brightness.
boolean slowChange = false;
if (brightness < 0) {
diff --git a/services/core/java/com/android/server/notification/ConditionProviders.java b/services/core/java/com/android/server/notification/ConditionProviders.java
index a1085d3..5de1a64 100644
--- a/services/core/java/com/android/server/notification/ConditionProviders.java
+++ b/services/core/java/com/android/server/notification/ConditionProviders.java
@@ -260,9 +260,11 @@
for (int i = 0; i < N; i++) {
final Condition c = conditions[i];
final ConditionRecord r = getRecordLocked(c.id, info.component);
+ final Condition oldCondition = r.condition;
+ final boolean conditionUpdate = oldCondition != null && !oldCondition.equals(c);
r.info = info;
r.condition = c;
- // if manual, exit zen if false (or failed)
+ // if manual, exit zen if false (or failed), update if true (and changed)
if (r.isManual) {
if (c.state == Condition.STATE_FALSE || c.state == Condition.STATE_ERROR) {
final boolean failed = c.state == Condition.STATE_ERROR;
@@ -275,6 +277,10 @@
"manualConditionExit");
unsubscribeLocked(r);
r.isManual = false;
+ } else if (c.state == Condition.STATE_TRUE && conditionUpdate) {
+ if (DEBUG) Slog.d(TAG, "Current condition updated, still true. old="
+ + oldCondition + " new=" + c);
+ setZenModeCondition(c, "conditionUpdate");
}
}
// if automatic, exit zen if false (or failed), enter zen if true
@@ -559,7 +565,7 @@
// enter downtime, or update mode if reconfigured during an active downtime
if (inDowntime && (mode == Global.ZEN_MODE_OFF || downtimeCurrent) && config != null) {
final Condition condition = mDowntime.createCondition(config.toDowntimeInfo(),
- Condition.STATE_TRUE);
+ config.sleepNone, Condition.STATE_TRUE);
mZenModeHelper.setZenMode(downtimeMode, "downtimeEnter");
setZenModeCondition(condition, "downtime");
}
diff --git a/services/core/java/com/android/server/notification/DowntimeConditionProvider.java b/services/core/java/com/android/server/notification/DowntimeConditionProvider.java
index 0fb5732..097589a 100644
--- a/services/core/java/com/android/server/notification/DowntimeConditionProvider.java
+++ b/services/core/java/com/android/server/notification/DowntimeConditionProvider.java
@@ -122,7 +122,8 @@
if (DEBUG) Slog.d(TAG, "onRequestConditions relevance=" + relevance);
if ((relevance & Condition.FLAG_RELEVANT_NOW) != 0) {
if (isInDowntime() && mConfig != null) {
- notifyCondition(createCondition(mConfig.toDowntimeInfo(), Condition.STATE_TRUE));
+ notifyCondition(createCondition(mConfig.toDowntimeInfo(), mConfig.sleepNone,
+ Condition.STATE_TRUE));
}
}
}
@@ -135,7 +136,7 @@
final int state = mConfig.toDowntimeInfo().equals(downtime) && isInDowntime()
? Condition.STATE_TRUE : Condition.STATE_FALSE;
if (DEBUG) Slog.d(TAG, "notify condition state: " + Condition.stateToString(state));
- notifyCondition(createCondition(downtime, state));
+ notifyCondition(createCondition(downtime, mConfig.sleepNone, state));
}
}
@@ -157,14 +158,22 @@
return mDowntimeMode != Global.ZEN_MODE_OFF;
}
- public Condition createCondition(DowntimeInfo downtime, int state) {
+ public Condition createCondition(DowntimeInfo downtime, boolean orAlarm, int state) {
if (downtime == null) return null;
final Uri id = ZenModeConfig.toDowntimeConditionId(downtime);
final String skeleton = DateFormat.is24HourFormat(mContext) ? "Hm" : "hma";
final Locale locale = Locale.getDefault();
final String pattern = DateFormat.getBestDateTimePattern(locale, skeleton);
- final long time = getTime(System.currentTimeMillis(), downtime.endHour, downtime.endMinute);
- final String formatted = new SimpleDateFormat(pattern, locale).format(new Date(time));
+ final long now = System.currentTimeMillis();
+ long endTime = getTime(now, downtime.endHour, downtime.endMinute);
+ if (orAlarm) {
+ final AlarmClockInfo nextAlarm = mTracker.getNextAlarm();
+ final long nextAlarmTime = nextAlarm != null ? nextAlarm.getTriggerTime() : 0;
+ if (nextAlarmTime > now && nextAlarmTime < endTime) {
+ endTime = nextAlarmTime;
+ }
+ }
+ final String formatted = new SimpleDateFormat(pattern, locale).format(new Date(endTime));
final String summary = mContext.getString(R.string.downtime_condition_summary, formatted);
final String line1 = mContext.getString(R.string.downtime_condition_line_one);
return new Condition(id, summary, line1, formatted, 0, state, Condition.FLAG_RELEVANT_NOW);
@@ -302,6 +311,11 @@
private void onEvaluateNextAlarm(AlarmClockInfo nextAlarm, long wakeupTime, boolean booted) {
if (!booted) return; // we don't know yet
+ // update condition description if we're in downtime (mode = none)
+ if (isInDowntime() && mConfig != null && mConfig.sleepNone) {
+ notifyCondition(createCondition(mConfig.toDowntimeInfo(), true /*orAlarm*/,
+ Condition.STATE_TRUE));
+ }
if (nextAlarm == null) return; // not fireable
if (DEBUG) Slog.d(TAG, "onEvaluateNextAlarm " + mTracker.formatAlarmDebug(nextAlarm));
if (System.currentTimeMillis() > wakeupTime) {
@@ -336,6 +350,10 @@
} else if (Intent.ACTION_TIMEZONE_CHANGED.equals(action)) {
if (DEBUG) Slog.d(TAG, "timezone changed to " + TimeZone.getDefault());
mCalendar.setTimeZone(TimeZone.getDefault());
+ mFiredAlarms.clear();
+ } else if (Intent.ACTION_TIME_CHANGED.equals(action)) {
+ if (DEBUG) Slog.d(TAG, "time changed to " + now);
+ mFiredAlarms.clear();
} else {
if (DEBUG) Slog.d(TAG, action + " fired at " + now);
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 9a2451e..b1ff398 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -8982,6 +8982,7 @@
&& isVerificationEnabled(userIdentifier, installFlags)) {
final Intent verification = new Intent(
Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
+ verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
PACKAGE_MIME_TYPE);
verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index c054e6c..4d8b98f 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -1234,6 +1234,7 @@
// Phase 0: Basic state updates.
updateIsPoweredLocked(mDirty);
updateStayOnLocked(mDirty);
+ updateScreenBrightnessBoostLocked(mDirty);
// Phase 1: Update wakefulness.
// Loop because the wake lock and user activity computations are influenced
@@ -1641,7 +1642,8 @@
|| mProximityPositive
|| (mWakeLockSummary & WAKE_LOCK_STAY_AWAKE) != 0
|| (mUserActivitySummary & (USER_ACTIVITY_SCREEN_BRIGHT
- | USER_ACTIVITY_SCREEN_DIM)) != 0;
+ | USER_ACTIVITY_SCREEN_DIM)) != 0
+ || mScreenBrightnessBoostInProgress;
}
/**
@@ -1828,9 +1830,6 @@
| DIRTY_SETTINGS | DIRTY_SCREEN_BRIGHTNESS_BOOST)) != 0) {
mDisplayPowerRequest.policy = getDesiredScreenPolicyLocked();
- // Handle screen brightness boost timeout.
- updateScreenBrightnessBoostLocked();
-
// Determine appropriate screen brightness and auto-brightness adjustments.
int screenBrightness = mScreenBrightnessSettingDefault;
float screenAutoBrightnessAdjustment = 0.0f;
@@ -1879,7 +1878,7 @@
}
mDisplayReady = mDisplayManagerInternal.requestPowerState(mDisplayPowerRequest,
- mRequestWaitForNegativeProximity) && !mScreenBrightnessBoostInProgress;
+ mRequestWaitForNegativeProximity);
mRequestWaitForNegativeProximity = false;
if (DEBUG_SPEW) {
@@ -1896,20 +1895,25 @@
return mDisplayReady && !oldDisplayReady;
}
- private void updateScreenBrightnessBoostLocked() {
- if (mScreenBrightnessBoostInProgress) {
- mHandler.removeMessages(MSG_SCREEN_BRIGHTNESS_BOOST_TIMEOUT);
- if (mLastScreenBrightnessBoostTime > mLastSleepTime) {
- final long boostTimeout = mLastScreenBrightnessBoostTime +
- SCREEN_BRIGHTNESS_BOOST_TIMEOUT;
- if (boostTimeout > SystemClock.uptimeMillis()) {
- Message msg = mHandler.obtainMessage(MSG_SCREEN_BRIGHTNESS_BOOST_TIMEOUT);
- msg.setAsynchronous(true);
- mHandler.sendMessageAtTime(msg, boostTimeout);
- return;
+ private void updateScreenBrightnessBoostLocked(int dirty) {
+ if ((dirty & DIRTY_SCREEN_BRIGHTNESS_BOOST) != 0) {
+ if (mScreenBrightnessBoostInProgress) {
+ final long now = SystemClock.uptimeMillis();
+ mHandler.removeMessages(MSG_SCREEN_BRIGHTNESS_BOOST_TIMEOUT);
+ if (mLastScreenBrightnessBoostTime > mLastSleepTime) {
+ final long boostTimeout = mLastScreenBrightnessBoostTime +
+ SCREEN_BRIGHTNESS_BOOST_TIMEOUT;
+ if (boostTimeout > now) {
+ Message msg = mHandler.obtainMessage(MSG_SCREEN_BRIGHTNESS_BOOST_TIMEOUT);
+ msg.setAsynchronous(true);
+ mHandler.sendMessageAtTime(msg, boostTimeout);
+ return;
+ }
}
+ mScreenBrightnessBoostInProgress = false;
+ userActivityNoUpdateLocked(now,
+ PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
}
- mScreenBrightnessBoostInProgress = false;
}
}
@@ -1940,7 +1944,8 @@
if ((mWakeLockSummary & WAKE_LOCK_SCREEN_BRIGHT) != 0
|| (mUserActivitySummary & USER_ACTIVITY_SCREEN_BRIGHT) != 0
- || !mBootCompleted) {
+ || !mBootCompleted
+ || mScreenBrightnessBoostInProgress) {
return DisplayPowerRequest.POLICY_BRIGHT;
}
@@ -2037,15 +2042,13 @@
final boolean needWakeLockSuspendBlocker = ((mWakeLockSummary & WAKE_LOCK_CPU) != 0);
final boolean needDisplaySuspendBlocker = needDisplaySuspendBlockerLocked();
final boolean autoSuspend = !needDisplaySuspendBlocker;
+ final boolean interactive = mDisplayPowerRequest.isBrightOrDim();
// Disable auto-suspend if needed.
- if (!autoSuspend) {
- if (mDecoupleHalAutoSuspendModeFromDisplayConfig) {
- setHalAutoSuspendModeLocked(false);
- }
- if (mDecoupleHalInteractiveModeFromDisplayConfig) {
- setHalInteractiveModeLocked(true);
- }
+ // FIXME We should consider just leaving auto-suspend enabled forever since
+ // we already hold the necessary wakelocks.
+ if (!autoSuspend && mDecoupleHalAutoSuspendModeFromDisplayConfig) {
+ setHalAutoSuspendModeLocked(false);
}
// First acquire suspend blockers if needed.
@@ -2058,6 +2061,22 @@
mHoldingDisplaySuspendBlocker = true;
}
+ // Inform the power HAL about interactive mode.
+ // Although we could set interactive strictly based on the wakefulness
+ // as reported by isInteractive(), it is actually more desirable to track
+ // the display policy state instead so that the interactive state observed
+ // by the HAL more accurately tracks transitions between AWAKE and DOZING.
+ // Refer to getDesiredScreenPolicyLocked() for details.
+ if (mDecoupleHalInteractiveModeFromDisplayConfig) {
+ // When becoming non-interactive, we want to defer sending this signal
+ // until the display is actually ready so that all transitions have
+ // completed. This is probably a good sign that things have gotten
+ // too tangled over here...
+ if (interactive || mDisplayReady) {
+ setHalInteractiveModeLocked(interactive);
+ }
+ }
+
// Then release suspend blockers if needed.
if (!needWakeLockSuspendBlocker && mHoldingWakeLockSuspendBlocker) {
mWakeLockSuspendBlocker.release();
@@ -2069,13 +2088,8 @@
}
// Enable auto-suspend if needed.
- if (autoSuspend) {
- if (mDecoupleHalInteractiveModeFromDisplayConfig) {
- setHalInteractiveModeLocked(false);
- }
- if (mDecoupleHalAutoSuspendModeFromDisplayConfig) {
- setHalAutoSuspendModeLocked(true);
- }
+ if (autoSuspend && mDecoupleHalAutoSuspendModeFromDisplayConfig) {
+ setHalAutoSuspendModeLocked(true);
}
}
@@ -2097,6 +2111,9 @@
return true;
}
}
+ if (mScreenBrightnessBoostInProgress) {
+ return true;
+ }
// Let the system suspend if the screen is off or dozing.
return false;
}
diff --git a/services/usb/java/com/android/server/usb/UsbDebuggingManager.java b/services/usb/java/com/android/server/usb/UsbDebuggingManager.java
index cc5d004..1cf00d2 100644
--- a/services/usb/java/com/android/server/usb/UsbDebuggingManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDebuggingManager.java
@@ -207,7 +207,12 @@
case MESSAGE_ADB_CONFIRM: {
String key = (String)msg.obj;
- mFingerprints = getFingerprints(key);
+ String fingerprints = getFingerprints(key);
+ if ("".equals(fingerprints)) {
+ sendResponse("NO");
+ break;
+ }
+ mFingerprints = fingerprints;
startConfirmation(key, mFingerprints);
break;
}
@@ -224,16 +229,25 @@
StringBuilder sb = new StringBuilder();
MessageDigest digester;
+ if (key == null) {
+ return "";
+ }
+
try {
digester = MessageDigest.getInstance("MD5");
} catch (Exception ex) {
- Slog.e(TAG, "Error getting digester: " + ex);
+ Slog.e(TAG, "Error getting digester", ex);
return "";
}
byte[] base64_data = key.split("\\s+")[0].getBytes();
- byte[] digest = digester.digest(Base64.decode(base64_data, Base64.DEFAULT));
-
+ byte[] digest;
+ try {
+ digest = digester.digest(Base64.decode(base64_data, Base64.DEFAULT));
+ } catch (IllegalArgumentException e) {
+ Slog.e(TAG, "error doing base64 decoding", e);
+ return "";
+ }
for (int i = 0; i < digest.length; i++) {
sb.append(hex.charAt((digest[i] >> 4) & 0xf));
sb.append(hex.charAt(digest[i] & 0xf));
diff --git a/tests/VectorDrawableTest/res/drawable/vector_drawable30.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable30.xml
new file mode 100644
index 0000000..3dff196
--- /dev/null
+++ b/tests/VectorDrawableTest/res/drawable/vector_drawable30.xml
@@ -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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="48dp"
+ android:width="48dp"
+ android:viewportHeight="48"
+ android:viewportWidth="48" >
+
+ <group>
+ <path
+ android:name="plus1"
+ android:pathData="M20 16h-4v8h-8v4h8v8h4v-8h8v-4h-8zm9-3.84v3.64l5-1v21.2h4v-26z"
+ android:fillColor="#ff00ff00"/>
+ </group>
+</vector>
diff --git a/tests/VectorDrawableTest/src/com/android/test/dynamic/VectorDrawablePerformance.java b/tests/VectorDrawableTest/src/com/android/test/dynamic/VectorDrawablePerformance.java
index 1cd6533..5a2e5a7 100644
--- a/tests/VectorDrawableTest/src/com/android/test/dynamic/VectorDrawablePerformance.java
+++ b/tests/VectorDrawableTest/src/com/android/test/dynamic/VectorDrawablePerformance.java
@@ -57,6 +57,7 @@
R.drawable.vector_drawable27,
R.drawable.vector_drawable28,
R.drawable.vector_drawable29,
+ R.drawable.vector_drawable30,
};
@Override