summaryrefslogtreecommitdiffstats
path: root/core/java
diff options
context:
space:
mode:
Diffstat (limited to 'core/java')
-rw-r--r--core/java/android/accounts/AbstractAccountAuthenticator.java61
-rw-r--r--core/java/android/app/ActivityManagerNative.java10
-rw-r--r--core/java/android/app/ActivityThread.java16
-rw-r--r--core/java/android/app/AssistContent.java44
-rw-r--r--core/java/android/app/AssistStructure.java40
-rw-r--r--core/java/android/app/FragmentManager.java89
-rw-r--r--core/java/android/app/IActivityManager.java3
-rw-r--r--core/java/android/app/VoiceInteractor.java47
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java458
-rw-r--r--core/java/android/app/usage/IUsageStatsManager.aidl1
-rw-r--r--core/java/android/app/usage/UsageStatsManager.java22
-rw-r--r--core/java/android/bluetooth/BluetoothAdapter.java26
-rw-r--r--core/java/android/bluetooth/BluetoothDevice.java4
-rw-r--r--core/java/android/bluetooth/BluetoothPan.java21
-rw-r--r--core/java/android/content/Intent.java5
-rw-r--r--core/java/android/content/pm/ApplicationInfo.java15
-rw-r--r--core/java/android/content/pm/PackageParser.java4
-rw-r--r--core/java/android/content/res/ColorStateList.java14
-rw-r--r--core/java/android/content/res/TypedArray.java4
-rw-r--r--core/java/android/database/DatabaseUtils.java4
-rw-r--r--core/java/android/hardware/SensorEvent.java4
-rw-r--r--core/java/android/hardware/SensorManager.java59
-rw-r--r--core/java/android/hardware/camera2/CameraCaptureSession.java24
-rw-r--r--core/java/android/hardware/camera2/CameraCharacteristics.java39
-rw-r--r--core/java/android/hardware/camera2/CameraManager.java5
-rw-r--r--core/java/android/hardware/camera2/CameraMetadata.java8
-rw-r--r--core/java/android/hardware/camera2/CaptureResult.java43
-rw-r--r--core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java44
-rw-r--r--core/java/android/hardware/camera2/impl/CameraDeviceImpl.java3
-rw-r--r--core/java/android/hardware/camera2/impl/CameraMetadataNative.java7
-rw-r--r--core/java/android/hardware/camera2/legacy/CameraDeviceState.java2
-rw-r--r--core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java2
-rw-r--r--core/java/android/hardware/camera2/legacy/CaptureCollector.java2
-rw-r--r--core/java/android/hardware/camera2/legacy/GLThreadManager.java2
-rw-r--r--core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java3
-rw-r--r--core/java/android/hardware/camera2/legacy/LegacyFaceDetectMapper.java10
-rw-r--r--core/java/android/hardware/camera2/legacy/LegacyFocusStateMapper.java14
-rw-r--r--core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java27
-rw-r--r--core/java/android/hardware/camera2/legacy/LegacyRequestMapper.java14
-rw-r--r--core/java/android/hardware/camera2/legacy/LegacyResultMapper.java12
-rw-r--r--core/java/android/hardware/camera2/legacy/ParameterUtils.java12
-rw-r--r--core/java/android/hardware/camera2/legacy/RequestThreadManager.java5
-rw-r--r--core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java2
-rw-r--r--core/java/android/hardware/camera2/marshal/impl/MarshalQueryableArray.java4
-rw-r--r--core/java/android/hardware/camera2/marshal/impl/MarshalQueryableEnum.java6
-rw-r--r--core/java/android/hardware/camera2/marshal/impl/MarshalQueryableParcelable.java10
-rw-r--r--core/java/android/hardware/camera2/marshal/impl/MarshalQueryableString.java4
-rw-r--r--core/java/android/hardware/camera2/utils/ArrayUtils.java4
-rw-r--r--core/java/android/hardware/camera2/utils/TaskDrainer.java12
-rw-r--r--core/java/android/inputmethodservice/InputMethodService.java35
-rw-r--r--core/java/android/net/IpReachabilityMonitor.java5
-rw-r--r--core/java/android/os/BatteryStats.java223
-rw-r--r--core/java/android/os/IDeviceIdleController.aidl4
-rw-r--r--core/java/android/os/PowerManager.java8
-rw-r--r--core/java/android/os/PowerManagerInternal.java2
-rw-r--r--core/java/android/os/RecoverySystem.java14
-rw-r--r--core/java/android/os/UserManager.java14
-rw-r--r--core/java/android/provider/VoicemailContract.java16
-rw-r--r--core/java/android/service/carrier/CarrierService.java (renamed from core/java/android/service/carrier/CarrierConfigService.java)33
-rw-r--r--core/java/android/service/carrier/ICarrierService.aidl (renamed from core/java/android/service/carrier/ICarrierConfigService.aidl)8
-rw-r--r--core/java/android/service/gatekeeper/GateKeeperResponse.aidl24
-rw-r--r--core/java/android/service/gatekeeper/GateKeeperResponse.java120
-rw-r--r--core/java/android/service/gatekeeper/IGateKeeperService.aidl16
-rw-r--r--core/java/android/service/notification/ZenModeConfig.java164
-rw-r--r--core/java/android/service/voice/IVoiceInteractionSession.aidl4
-rw-r--r--core/java/android/service/voice/VoiceInteractionService.java23
-rw-r--r--core/java/android/service/voice/VoiceInteractionSession.java548
-rw-r--r--core/java/android/service/wallpaper/WallpaperService.java34
-rw-r--r--core/java/android/speech/RecognitionService.java26
-rw-r--r--core/java/android/text/Layout.java1
-rw-r--r--core/java/android/text/TextLine.java10
-rw-r--r--core/java/android/text/format/DateUtils.java4
-rw-r--r--core/java/android/view/AccessibilityInteractionController.java5
-rw-r--r--core/java/android/view/GestureDetector.java82
-rw-r--r--core/java/android/view/IWindow.aidl2
-rw-r--r--core/java/android/view/IWindowSession.aidl6
-rw-r--r--core/java/android/view/ScaleGestureDetector.java4
-rw-r--r--core/java/android/view/SurfaceView.java6
-rw-r--r--core/java/android/view/View.java163
-rw-r--r--core/java/android/view/ViewGroup.java35
-rw-r--r--core/java/android/view/ViewRootImpl.java33
-rw-r--r--core/java/android/view/ViewStructure.java9
-rw-r--r--core/java/android/view/WindowManager.java1
-rw-r--r--core/java/android/view/WindowManagerGlobal.java4
-rw-r--r--core/java/android/view/WindowManagerPolicy.java29
-rw-r--r--core/java/android/view/accessibility/AccessibilityNodeInfo.java4
-rw-r--r--core/java/android/view/inputmethod/InputMethodManager.java16
-rw-r--r--core/java/android/webkit/ViewAssistStructure.java208
-rw-r--r--core/java/android/webkit/WebView.java3
-rw-r--r--core/java/android/webkit/WebViewProvider.java2
-rw-r--r--core/java/android/widget/AbsListView.java66
-rw-r--r--core/java/android/widget/AbsSeekBar.java26
-rw-r--r--core/java/android/widget/AdapterView.java13
-rw-r--r--core/java/android/widget/Editor.java39
-rw-r--r--core/java/android/widget/ListView.java49
-rw-r--r--core/java/android/widget/RemoteViews.java6
-rw-r--r--core/java/android/widget/ScrollView.java44
-rw-r--r--core/java/android/widget/Switch.java4
-rw-r--r--core/java/android/widget/TextView.java35
-rw-r--r--core/java/com/android/internal/app/ChooserActivity.java25
-rw-r--r--core/java/com/android/internal/app/IBatteryStats.aidl8
-rw-r--r--core/java/com/android/internal/app/ResolverActivity.java14
-rw-r--r--core/java/com/android/internal/os/BatteryStatsImpl.java244
-rw-r--r--core/java/com/android/internal/os/SomeArgs.java2
-rw-r--r--core/java/com/android/internal/policy/IKeyguardService.aidl24
-rw-r--r--core/java/com/android/internal/policy/PhoneWindow.java103
-rw-r--r--core/java/com/android/internal/util/ScreenShapeHelper.java12
-rw-r--r--core/java/com/android/internal/view/BaseIWindow.java4
-rw-r--r--core/java/com/android/internal/widget/ButtonBarLayout.java39
-rw-r--r--core/java/com/android/internal/widget/FloatingToolbar.java46
-rw-r--r--core/java/com/android/internal/widget/ILockSettings.aidl10
-rw-r--r--core/java/com/android/internal/widget/LockPatternChecker.java54
-rw-r--r--core/java/com/android/internal/widget/LockPatternUtils.java96
-rw-r--r--core/java/com/android/internal/widget/SwipeDismissLayout.java31
-rw-r--r--core/java/com/android/internal/widget/VerifyCredentialResponse.aidl24
-rw-r--r--core/java/com/android/internal/widget/VerifyCredentialResponse.java126
116 files changed, 2931 insertions, 1432 deletions
diff --git a/core/java/android/accounts/AbstractAccountAuthenticator.java b/core/java/android/accounts/AbstractAccountAuthenticator.java
index dbc9051..3e4a66d 100644
--- a/core/java/android/accounts/AbstractAccountAuthenticator.java
+++ b/core/java/android/accounts/AbstractAccountAuthenticator.java
@@ -108,6 +108,14 @@ import java.util.Arrays;
public abstract class AbstractAccountAuthenticator {
private static final String TAG = "AccountAuthenticator";
+ /**
+ * Bundle key used for the {@code long} expiration time (in millis from the unix epoch) of the
+ * associated auth token.
+ *
+ * @see #getAuthToken
+ */
+ public static final String KEY_CUSTOM_TOKEN_EXPIRY = "android.accounts.expiry";
+
private final Context mContext;
public AbstractAccountAuthenticator(Context context) {
@@ -115,6 +123,7 @@ public abstract class AbstractAccountAuthenticator {
}
private class Transport extends IAccountAuthenticator.Stub {
+ @Override
public void addAccount(IAccountAuthenticatorResponse response, String accountType,
String authTokenType, String[] features, Bundle options)
throws RemoteException {
@@ -140,6 +149,7 @@ public abstract class AbstractAccountAuthenticator {
}
}
+ @Override
public void confirmCredentials(IAccountAuthenticatorResponse response,
Account account, Bundle options) throws RemoteException {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
@@ -162,6 +172,7 @@ public abstract class AbstractAccountAuthenticator {
}
}
+ @Override
public void getAuthTokenLabel(IAccountAuthenticatorResponse response,
String authTokenType)
throws RemoteException {
@@ -184,6 +195,7 @@ public abstract class AbstractAccountAuthenticator {
}
}
+ @Override
public void getAuthToken(IAccountAuthenticatorResponse response,
Account account, String authTokenType, Bundle loginOptions)
throws RemoteException {
@@ -209,6 +221,7 @@ public abstract class AbstractAccountAuthenticator {
}
}
+ @Override
public void updateCredentials(IAccountAuthenticatorResponse response, Account account,
String authTokenType, Bundle loginOptions) throws RemoteException {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
@@ -234,6 +247,7 @@ public abstract class AbstractAccountAuthenticator {
}
}
+ @Override
public void editProperties(IAccountAuthenticatorResponse response,
String accountType) throws RemoteException {
checkBinderPermission();
@@ -248,6 +262,7 @@ public abstract class AbstractAccountAuthenticator {
}
}
+ @Override
public void hasFeatures(IAccountAuthenticatorResponse response,
Account account, String[] features) throws RemoteException {
checkBinderPermission();
@@ -262,6 +277,7 @@ public abstract class AbstractAccountAuthenticator {
}
}
+ @Override
public void getAccountRemovalAllowed(IAccountAuthenticatorResponse response,
Account account) throws RemoteException {
checkBinderPermission();
@@ -276,6 +292,7 @@ public abstract class AbstractAccountAuthenticator {
}
}
+ @Override
public void getAccountCredentialsForCloning(IAccountAuthenticatorResponse response,
Account account) throws RemoteException {
checkBinderPermission();
@@ -291,6 +308,7 @@ public abstract class AbstractAccountAuthenticator {
}
}
+ @Override
public void addAccountFromCredentials(IAccountAuthenticatorResponse response,
Account account,
Bundle accountCredentials) throws RemoteException {
@@ -410,21 +428,42 @@ public abstract class AbstractAccountAuthenticator {
public abstract Bundle confirmCredentials(AccountAuthenticatorResponse response,
Account account, Bundle options)
throws NetworkErrorException;
+
/**
- * Gets the authtoken for an account.
+ * Gets an authtoken for an account.
+ *
+ * If not {@code null}, the resultant {@link Bundle} will contain different sets of keys
+ * depending on whether a token was successfully issued and, if not, whether one
+ * could be issued via some {@link android.app.Activity}.
+ * <p>
+ * If a token cannot be provided without some additional activity, the Bundle should contain
+ * {@link AccountManager#KEY_INTENT} with an associated {@link Intent}. On the other hand, if
+ * there is no such activity, then a Bundle containing
+ * {@link AccountManager#KEY_ERROR_CODE} and {@link AccountManager#KEY_ERROR_MESSAGE} should be
+ * returned.
+ * <p>
+ * If a token can be successfully issued, the implementation should return the
+ * {@link AccountManager#KEY_ACCOUNT_NAME} and {@link AccountManager#KEY_ACCOUNT_TYPE} of the
+ * account associated with the token as well as the {@link AccountManager#KEY_AUTHTOKEN}. In
+ * addition {@link AbstractAccountAuthenticator} implementations that declare themselves
+ * {@code android:customTokens=true} may also provide a non-negative {@link
+ * #KEY_CUSTOM_TOKEN_EXPIRY} long value containing the expiration timestamp of the expiration
+ * time (in millis since the unix epoch).
+ * <p>
+ * Implementers should assume that tokens will be cached on the basis of account and
+ * authTokenType. The system may ignore the contents of the supplied options Bundle when
+ * determining to re-use a cached token. Furthermore, implementers should assume a supplied
+ * expiration time will be treated as non-binding advice.
+ * <p>
+ * Finally, note that for android:customTokens=false authenticators, tokens are cached
+ * indefinitely until some client calls {@link
+ * AccountManager#invalidateAuthToken(String,String)}.
+ *
* @param response to send the result back to the AccountManager, will never be null
* @param account the account whose credentials are to be retrieved, will never be null
* @param authTokenType the type of auth token to retrieve, will never be null
* @param options a Bundle of authenticator-specific options, may be null
- * @return a Bundle result or null if the result is to be returned via the response. The result
- * will contain either:
- * <ul>
- * <li> {@link AccountManager#KEY_INTENT}, or
- * <li> {@link AccountManager#KEY_ACCOUNT_NAME}, {@link AccountManager#KEY_ACCOUNT_TYPE},
- * and {@link AccountManager#KEY_AUTHTOKEN}, or
- * <li> {@link AccountManager#KEY_ERROR_CODE} and {@link AccountManager#KEY_ERROR_MESSAGE} to
- * indicate an error
- * </ul>
+ * @return a Bundle result or null if the result is to be returned via the response.
* @throws NetworkErrorException if the authenticator could not honor the request due to a
* network error
*/
@@ -518,6 +557,7 @@ public abstract class AbstractAccountAuthenticator {
public Bundle getAccountCredentialsForCloning(final AccountAuthenticatorResponse response,
final Account account) throws NetworkErrorException {
new Thread(new Runnable() {
+ @Override
public void run() {
Bundle result = new Bundle();
result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, false);
@@ -543,6 +583,7 @@ public abstract class AbstractAccountAuthenticator {
Account account,
Bundle accountCredentials) throws NetworkErrorException {
new Thread(new Runnable() {
+ @Override
public void run() {
Bundle result = new Bundle();
result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, false);
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 02e0d5b..e4def1e 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -2193,7 +2193,9 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
data.enforceInterface(IActivityManager.descriptor);
IBinder token = data.readStrongBinder();
Bundle extras = data.readBundle();
- reportAssistContextExtras(token, extras);
+ AssistStructure structure = AssistStructure.CREATOR.createFromParcel(data);
+ AssistContent content = AssistContent.CREATOR.createFromParcel(data);
+ reportAssistContextExtras(token, extras, structure, content);
reply.writeNoException();
return true;
}
@@ -5359,13 +5361,15 @@ class ActivityManagerProxy implements IActivityManager
reply.recycle();
}
- public void reportAssistContextExtras(IBinder token, Bundle extras)
- throws RemoteException {
+ public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
+ AssistContent content) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeStrongBinder(token);
data.writeBundle(extras);
+ structure.writeToParcel(data, 0);
+ content.writeToParcel(data, 0);
mRemote.transact(REPORT_ASSIST_CONTEXT_EXTRAS_TRANSACTION, data, reply, 0);
reply.readException();
data.recycle();
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index cb436b5..2a98b6c 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -2562,15 +2562,18 @@ public final class ActivityThread {
public void handleRequestAssistContextExtras(RequestAssistContextExtras cmd) {
Bundle data = new Bundle();
+ AssistStructure structure = null;
+ AssistContent content = new AssistContent();
ActivityClientRecord r = mActivities.get(cmd.activityToken);
if (r != null) {
r.activity.getApplication().dispatchOnProvideAssistData(r.activity, data);
r.activity.onProvideAssistData(data);
if (cmd.requestType == ActivityManager.ASSIST_CONTEXT_FULL) {
- data.putParcelable(AssistStructure.ASSIST_KEY, new AssistStructure(r.activity));
- AssistContent content = new AssistContent();
+ structure = new AssistStructure(r.activity);
Intent activityIntent = r.activity.getIntent();
- if (activityIntent != null) {
+ if (activityIntent != null && (r.window == null ||
+ (r.window.getAttributes().flags
+ & WindowManager.LayoutParams.FLAG_SECURE) == 0)) {
Intent intent = new Intent(activityIntent);
intent.setFlags(intent.getFlags() & ~(Intent.FLAG_GRANT_WRITE_URI_PERMISSION
| Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION));
@@ -2580,15 +2583,14 @@ public final class ActivityThread {
content.setIntent(new Intent());
}
r.activity.onProvideAssistContent(content);
- data.putParcelable(AssistContent.ASSIST_KEY, content);
}
}
- if (data.isEmpty()) {
- data = null;
+ if (structure == null) {
+ structure = new AssistStructure();
}
IActivityManager mgr = ActivityManagerNative.getDefault();
try {
- mgr.reportAssistContextExtras(cmd.requestToken, data);
+ mgr.reportAssistContextExtras(cmd.requestToken, data, structure, content);
} catch (RemoteException e) {
}
}
diff --git a/core/java/android/app/AssistContent.java b/core/java/android/app/AssistContent.java
index cb1a3f5..f271af1 100644
--- a/core/java/android/app/AssistContent.java
+++ b/core/java/android/app/AssistContent.java
@@ -18,6 +18,7 @@ package android.app;
import android.content.ClipData;
import android.content.Intent;
+import android.net.Uri;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
@@ -30,14 +31,17 @@ import android.os.Parcelable;
public class AssistContent implements Parcelable {
private Intent mIntent;
private ClipData mClipData;
+ private Uri mUri;
/**
+ * @hide
* Key name this data structure is stored in the Bundle generated by
* {@link Activity#onProvideAssistData}.
*/
public static final String ASSIST_KEY = "android:assist_content";
/**
+ * @hide
* Retrieve the framework-generated AssistContent that is stored within
* the Bundle filled in by {@link Activity#onProvideAssistContent}.
*/
@@ -56,6 +60,13 @@ public class AssistContent implements Parcelable {
*/
public void setIntent(Intent intent) {
mIntent = intent;
+ setWebUri(null);
+ if (intent != null && Intent.ACTION_VIEW.equals(intent.getAction())) {
+ Uri uri = intent.getData();
+ if ("http".equals(uri.getScheme()) || "https".equals(uri.getScheme())) {
+ setWebUri(uri);
+ }
+ }
}
/**
@@ -81,6 +92,30 @@ public class AssistContent implements Parcelable {
return mClipData;
}
+ /**
+ * Set a web URI associated with the current data being shown to the user.
+ * This URI could be opened in a web browser, or in the app as an
+ * {@link Intent#ACTION_VIEW} Intent, to show the same data that is currently
+ * being displayed by it. The URI here should be something that is transportable
+ * off the device into other environments to acesss the same data as is currently
+ * being shown in the app; if the app does not have such a representation, it should
+ * leave the null and only report the local intent and clip data.
+ *
+ * <p>This will be automatically populated for you from {@link #setIntent} if that Intent
+ * is an {@link Intent#ACTION_VIEW} of a web (http or https scheme) URI.</p>
+ */
+ public void setWebUri(Uri uri) {
+ mUri = uri;
+ }
+
+ /**
+ * Return the content's web URI as per {@link #setWebUri(android.net.Uri)}, or null if
+ * there is none.
+ */
+ public Uri getWebUri() {
+ return mUri;
+ }
+
AssistContent(Parcel in) {
if (in.readInt() != 0) {
mIntent = Intent.CREATOR.createFromParcel(in);
@@ -88,6 +123,9 @@ public class AssistContent implements Parcelable {
if (in.readInt() != 0) {
mClipData = ClipData.CREATOR.createFromParcel(in);
}
+ if (in.readInt() != 0) {
+ mUri = Uri.CREATOR.createFromParcel(in);
+ }
}
@Override
@@ -109,6 +147,12 @@ public class AssistContent implements Parcelable {
} else {
dest.writeInt(0);
}
+ if (mUri != null) {
+ dest.writeInt(1);
+ mUri.writeToParcel(dest, flags);
+ } else {
+ dest.writeInt(0);
+ }
}
public static final Parcelable.Creator<AssistContent> CREATOR
diff --git a/core/java/android/app/AssistStructure.java b/core/java/android/app/AssistStructure.java
index b703b0e..ca47a5e 100644
--- a/core/java/android/app/AssistStructure.java
+++ b/core/java/android/app/AssistStructure.java
@@ -42,13 +42,13 @@ import java.util.ArrayList;
/**
* Assist data automatically created by the platform's implementation
- * of {@link Activity#onProvideAssistData}. Retrieve it from the assist
- * data with {@link #getAssistStructure(android.os.Bundle)}.
+ * of {@link Activity#onProvideAssistData}.
*/
final public class AssistStructure implements Parcelable {
static final String TAG = "AssistStructure";
/**
+ * @hide
* Key name this data structure is stored in the Bundle generated by
* {@link Activity#onProvideAssistData}.
*/
@@ -607,35 +607,7 @@ final public class AssistStructure implements Parcelable {
}
@Override
- public void setTextPaint(TextPaint paint) {
- ViewNodeText t = getNodeText();
- t.mTextColor = paint.getColor();
- t.mTextBackgroundColor = paint.bgColor;
- t.mTextSize = paint.getTextSize();
- t.mTextStyle = 0;
- Typeface tf = paint.getTypeface();
- if (tf != null) {
- if (tf.isBold()) {
- t.mTextStyle |= ViewNode.TEXT_STYLE_BOLD;
- }
- if (tf.isItalic()) {
- t.mTextStyle |= ViewNode.TEXT_STYLE_ITALIC;
- }
- }
- int pflags = paint.getFlags();
- if ((pflags& Paint.FAKE_BOLD_TEXT_FLAG) != 0) {
- t.mTextStyle |= ViewNode.TEXT_STYLE_BOLD;
- }
- if ((pflags& Paint.UNDERLINE_TEXT_FLAG) != 0) {
- t.mTextStyle |= ViewNode.TEXT_STYLE_UNDERLINE;
- }
- if ((pflags& Paint.STRIKE_THRU_TEXT_FLAG) != 0) {
- t.mTextStyle |= ViewNode.TEXT_STYLE_STRIKE_THRU;
- }
- }
-
- @Override
- public void setTextStyle(int size, int fgColor, int bgColor, int style) {
+ public void setTextStyle(float size, int fgColor, int bgColor, int style) {
ViewNodeText t = getNodeText();
t.mTextColor = fgColor;
t.mTextBackgroundColor = bgColor;
@@ -741,6 +713,11 @@ final public class AssistStructure implements Parcelable {
}
}
+ AssistStructure() {
+ mHaveData = true;
+ mActivityComponent = null;
+ }
+
AssistStructure(Parcel in) {
mReceiveChannel = in.readStrongBinder();
}
@@ -811,6 +788,7 @@ final public class AssistStructure implements Parcelable {
}
/**
+ * @hide
* Retrieve the framework-generated AssistStructure that is stored within
* the Bundle filled in by {@link Activity#onProvideAssistData}.
*/
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index e0a30ad..3b026d2 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -19,6 +19,9 @@ package android.app;
import android.animation.Animator;
import android.animation.AnimatorInflater;
import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.PropertyValuesHolder;
+import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.TypedArray;
@@ -403,6 +406,44 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
static final String VIEW_STATE_TAG = "android:view_state";
static final String USER_VISIBLE_HINT_TAG = "android:user_visible_hint";
+ static class AnimateOnHWLayerIfNeededListener implements Animator.AnimatorListener {
+ private boolean mShouldRunOnHWLayer = false;
+ private View mView;
+ public AnimateOnHWLayerIfNeededListener(final View v) {
+ if (v == null) {
+ return;
+ }
+ mView = v;
+ }
+
+ @Override
+ public void onAnimationStart(Animator animation) {
+ mShouldRunOnHWLayer = shouldRunOnHWLayer(mView, animation);
+ if (mShouldRunOnHWLayer) {
+ mView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+ }
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ if (mShouldRunOnHWLayer) {
+ mView.setLayerType(View.LAYER_TYPE_NONE, null);
+ }
+ mView = null;
+ animation.removeListener(this);
+ }
+
+ @Override
+ public void onAnimationCancel(Animator animation) {
+
+ }
+
+ @Override
+ public void onAnimationRepeat(Animator animation) {
+
+ }
+ }
+
ArrayList<Runnable> mPendingActions;
Runnable[] mTmpActions;
boolean mExecutingActions;
@@ -467,6 +508,50 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
throw ex;
}
+ static boolean modifiesAlpha(Animator anim) {
+ if (anim == null) {
+ return false;
+ }
+ if (anim instanceof ValueAnimator) {
+ ValueAnimator valueAnim = (ValueAnimator) anim;
+ PropertyValuesHolder[] values = valueAnim.getValues();
+ for (int i = 0; i < values.length; i++) {
+ if (("alpha").equals(values[i].getPropertyName())) {
+ return true;
+ }
+ }
+ } else if (anim instanceof AnimatorSet) {
+ List<Animator> animList = ((AnimatorSet) anim).getChildAnimations();
+ for (int i = 0; i < animList.size(); i++) {
+ if (modifiesAlpha(animList.get(i))) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ static boolean shouldRunOnHWLayer(View v, Animator anim) {
+ if (v == null || anim == null) {
+ return false;
+ }
+ return v.getLayerType() == View.LAYER_TYPE_NONE
+ && v.hasOverlappingRendering()
+ && modifiesAlpha(anim);
+ }
+
+ /**
+ * Sets the to be animated view on hardware layer during the animation.
+ */
+ private void setHWLayerAnimListenerIfAlpha(final View v, Animator anim) {
+ if (v == null || anim == null) {
+ return;
+ }
+ if (shouldRunOnHWLayer(v, anim)) {
+ anim.addListener(new AnimateOnHWLayerIfNeededListener(v));
+ }
+ }
+
@Override
public FragmentTransaction beginTransaction() {
return new BackStackRecord(this);
@@ -894,6 +979,7 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
transitionStyle);
if (anim != null) {
anim.setTarget(f.mView);
+ setHWLayerAnimListenerIfAlpha(f.mView, anim);
anim.start();
}
container.addView(f.mView);
@@ -975,6 +1061,7 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
}
});
anim.setTarget(f.mView);
+ setHWLayerAnimListenerIfAlpha(f.mView, anim);
anim.start();
}
@@ -1188,6 +1275,7 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
}
}
});
+ setHWLayerAnimListenerIfAlpha(finalFragment.mView, anim);
anim.start();
} else {
fragment.mView.setVisibility(View.GONE);
@@ -1209,6 +1297,7 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
transitionStyle);
if (anim != null) {
anim.setTarget(fragment.mView);
+ setHWLayerAnimListenerIfAlpha(fragment.mView, anim);
anim.start();
}
fragment.mView.setVisibility(View.VISIBLE);
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index c42719b..0a425ae 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -433,7 +433,8 @@ public interface IActivityManager extends IInterface {
public void requestAssistContextExtras(int requestType, IResultReceiver receiver)
throws RemoteException;
- public void reportAssistContextExtras(IBinder token, Bundle extras) throws RemoteException;
+ public void reportAssistContextExtras(IBinder token, Bundle extras,
+ AssistStructure structure, AssistContent content) throws RemoteException;
public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle)
throws RemoteException;
diff --git a/core/java/android/app/VoiceInteractor.java b/core/java/android/app/VoiceInteractor.java
index 022a62c..ba27c54 100644
--- a/core/java/android/app/VoiceInteractor.java
+++ b/core/java/android/app/VoiceInteractor.java
@@ -262,9 +262,9 @@ public class VoiceInteractor {
/**
* Create a new confirmation request.
- * @param prompt Optional confirmation text to read to the user as the action being
- * confirmed.
- * @param extras Additional optional information.
+ * @param prompt Optional confirmation to speak to the user or null if nothing
+ * should be spoken.
+ * @param extras Additional optional information or null.
*/
public ConfirmationRequest(CharSequence prompt, Bundle extras) {
mPrompt = prompt;
@@ -305,7 +305,7 @@ public class VoiceInteractor {
* Creates an option that a user can select with their voice by matching the label
* or one of several synonyms.
* @param label The label that will both be matched against what the user speaks
- * and displayed visually.
+ * and displayed visually.
*/
public Option(CharSequence label) {
mLabel = label;
@@ -316,10 +316,10 @@ public class VoiceInteractor {
* Creates an option that a user can select with their voice by matching the label
* or one of several synonyms.
* @param label The label that will both be matched against what the user speaks
- * and displayed visually.
+ * and displayed visually.
* @param index The location of this option within the overall set of options.
- * Can be used to help identify the option when it is returned from the
- * voice interactor.
+ * Can be used to help identify the option when it is returned from the
+ * voice interactor.
*/
public Option(CharSequence label, int index) {
mLabel = label;
@@ -330,7 +330,7 @@ public class VoiceInteractor {
* Add a synonym term to the option to indicate an alternative way the content
* may be matched.
* @param synonym The synonym that will be matched against what the user speaks,
- * but not displayed.
+ * but not displayed.
*/
public Option addSynonym(CharSequence synonym) {
if (mSynonyms == null) {
@@ -412,9 +412,10 @@ public class VoiceInteractor {
/**
* Create a new pick option request.
- * @param prompt Optional question to be spoken to the user via text to speech.
+ * @param prompt Optional question to be asked of the user when the options are
+ * presented or null if nothing should be asked.
* @param options The set of {@link Option}s the user is selecting from.
- * @param extras Additional optional information.
+ * @param extras Additional optional information or null.
*/
public PickOptionRequest(CharSequence prompt, Option[] options, Bundle extras) {
mPrompt = prompt;
@@ -425,10 +426,10 @@ public class VoiceInteractor {
/**
* Called when a single option is confirmed or narrowed to one of several options.
* @param finished True if the voice interaction has finished making a selection, in
- * which case {@code selections} contains the final result. If false, this request is
- * still active and you will continue to get calls on it.
+ * which case {@code selections} contains the final result. If false, this request is
+ * still active and you will continue to get calls on it.
* @param selections Either a single {@link Option} or one of several {@link Option}s the
- * user has narrowed the choices down to.
+ * user has narrowed the choices down to.
* @param result Additional optional information.
*/
public void onPickOptionResult(boolean finished, Option[] selections, Bundle result) {
@@ -455,8 +456,9 @@ public class VoiceInteractor {
/**
* Create a new completed voice interaction request.
- * @param message Optional message to tell user about the completion status of the task.
- * @param extras Additional optional information.
+ * @param message Optional message to speak to the user about the completion status of
+ * the task or null if nothing should be spoken.
+ * @param extras Additional optional information or null.
*/
public CompleteVoiceRequest(CharSequence message, Bundle extras) {
mMessage = message;
@@ -489,9 +491,9 @@ public class VoiceInteractor {
/**
* Create a new voice abort request.
- * @param message Optional message to tell user about not being able to complete
- * the interaction with voice.
- * @param extras Additional optional information.
+ * @param message Optional message to speak to the user indicating why the task could
+ * not be completed by voice or null if nothing should be spoken.
+ * @param extras Additional optional information or null.
*/
public AbortVoiceRequest(CharSequence message, Bundle extras) {
mMessage = message;
@@ -508,7 +510,7 @@ public class VoiceInteractor {
}
/**
- * Execute an extended command using the trusted system VoiceInteractionService.
+ * Execute a vendor-specific command using the trusted system VoiceInteractionService.
* This allows an Activity to request additional information from the user needed to
* complete an action (e.g. booking a table might have several possible times that the
* user could select from or an app might need the user to agree to a terms of service).
@@ -631,10 +633,11 @@ public class VoiceInteractor {
/**
* Queries the supported commands available from the VoiceinteractionService.
* The command is a string that describes the generic operation to be performed.
- * An example might be "com.google.voice.commands.REQUEST_NUMBER_BAGS" to request the number
- * of bags as part of airline check-in. (This is not an actual working example.)
+ * An example might be "org.example.commands.PICK_DATE" to ask the user to pick
+ * a date. (Note: This is not an actual working example.)
*
- * @param commands
+ * @param commands The array of commands to query for support.
+ * @return Array of booleans indicating whether each command is supported or not.
*/
public boolean[] supportsCommands(String[] commands) {
try {
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 52ccd7b..a0b95b6 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -16,6 +16,8 @@
package android.app.admin;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SystemApi;
@@ -76,7 +78,7 @@ import java.util.List;
* <h3>Developer Guides</h3>
* <p>For more information about managing policies for device administration, read the
* <a href="{@docRoot}guide/topics/admin/device-admin.html">Device Administration</a>
- * developer guide.</p>
+ * developer guide.
* </div>
*/
public class DevicePolicyManager {
@@ -122,9 +124,6 @@ public class DevicePolicyManager {
*
* <p> If provisioning fails, the managedProfile is removed so the device returns to its
* previous state.
- *
- * <p>Input: Nothing.</p>
- * <p>Output: Nothing</p>
*/
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
public static final String ACTION_PROVISION_MANAGED_PROFILE
@@ -155,7 +154,7 @@ public class DevicePolicyManager {
* message containing an NFC record with MIME type {@link #MIME_TYPE_PROVISIONING_NFC}.
*
* <p> When this extra is set, the application must have exactly one device admin receiver.
- * This receiver will be set as the profile or device owner and active admin.</p>
+ * This receiver will be set as the profile or device owner and active admin.
* @see DeviceAdminReceiver
* @deprecated Use {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME}. This extra is still
@@ -212,7 +211,7 @@ public class DevicePolicyManager {
/**
* A Boolean extra that can be used by the mobile device management application to skip the
- * disabling of system apps during provisioning when set to <code>true</code>.
+ * disabling of system apps during provisioning when set to {@code true}.
*
* <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
* provisioning via an NFC bump.
@@ -644,9 +643,6 @@ public class DevicePolicyManager {
*
* <p>
* If provisioning fails, the device is factory reset.
- *
- * <p>Input: Nothing.</p>
- * <p>Output: Nothing</p>
*/
public static final String MIME_TYPE_PROVISIONING_NFC_V2
= "application/com.android.managedprovisioning.v2";
@@ -847,18 +843,18 @@ public class DevicePolicyManager {
* Return true if the given administrator component is currently
* active (enabled) in the system.
*/
- public boolean isAdminActive(ComponentName who) {
- return isAdminActiveAsUser(who, UserHandle.myUserId());
+ public boolean isAdminActive(@NonNull ComponentName admin) {
+ return isAdminActiveAsUser(admin, UserHandle.myUserId());
}
/**
* @see #isAdminActive(ComponentName)
* @hide
*/
- public boolean isAdminActiveAsUser(ComponentName who, int userId) {
+ public boolean isAdminActiveAsUser(@NonNull ComponentName admin, int userId) {
if (mService != null) {
try {
- return mService.isAdminActive(who, userId);
+ return mService.isAdminActive(admin, userId);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
@@ -870,10 +866,10 @@ public class DevicePolicyManager {
* for the user.
* @hide
*/
- public boolean isRemovingAdmin(ComponentName who, int userId) {
+ public boolean isRemovingAdmin(@NonNull ComponentName admin, int userId) {
if (mService != null) {
try {
- return mService.isRemovingAdmin(who, userId);
+ return mService.isRemovingAdmin(admin, userId);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
@@ -883,8 +879,8 @@ public class DevicePolicyManager {
/**
- * Return a list of all currently active device administrator's component
- * names. Note that if there are no administrators than null may be
+ * Return a list of all currently active device administrators' component
+ * names. If there are no administrators {@code null} may be
* returned.
*/
public List<ComponentName> getActiveAdmins() {
@@ -928,10 +924,10 @@ public class DevicePolicyManager {
* try to remove someone else's component, a security exception will be
* thrown.
*/
- public void removeActiveAdmin(ComponentName who) {
+ public void removeActiveAdmin(@NonNull ComponentName admin) {
if (mService != null) {
try {
- mService.removeActiveAdmin(who, UserHandle.myUserId());
+ mService.removeActiveAdmin(admin, UserHandle.myUserId());
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
@@ -940,14 +936,14 @@ public class DevicePolicyManager {
/**
* Returns true if an administrator has been granted a particular device policy. This can
- * be used to check if the administrator was activated under an earlier set of policies,
+ * be used to check whether the administrator was activated under an earlier set of policies,
* but requires additional policies after an upgrade.
*
* @param admin Which {@link DeviceAdminReceiver} this request is associated with. Must be
* an active administrator, or an exception will be thrown.
* @param usesPolicy Which uses-policy to check, as defined in {@link DeviceAdminInfo}.
*/
- public boolean hasGrantedPolicy(ComponentName admin, int usesPolicy) {
+ public boolean hasGrantedPolicy(@NonNull ComponentName admin, int usesPolicy) {
if (mService != null) {
try {
return mService.hasGrantedPolicy(admin, usesPolicy, UserHandle.myUserId());
@@ -1048,7 +1044,7 @@ public class DevicePolicyManager {
* {@link #PASSWORD_QUALITY_ALPHABETIC}, {@link #PASSWORD_QUALITY_ALPHANUMERIC}
* or {@link #PASSWORD_QUALITY_COMPLEX}.
*/
- public void setPasswordQuality(ComponentName admin, int quality) {
+ public void setPasswordQuality(@NonNull ComponentName admin, int quality) {
if (mService != null) {
try {
mService.setPasswordQuality(admin, quality);
@@ -1061,15 +1057,15 @@ public class DevicePolicyManager {
/**
* Retrieve the current minimum password quality for all admins of this user
* and its profiles or a particular one.
- * @param admin The name of the admin component to check, or null to aggregate
+ * @param admin The name of the admin component to check, or {@code null} to aggregate
* all admins.
*/
- public int getPasswordQuality(ComponentName admin) {
+ public int getPasswordQuality(@Nullable ComponentName admin) {
return getPasswordQuality(admin, UserHandle.myUserId());
}
/** @hide per-user version */
- public int getPasswordQuality(ComponentName admin, int userHandle) {
+ public int getPasswordQuality(@Nullable ComponentName admin, int userHandle) {
if (mService != null) {
try {
return mService.getPasswordQuality(admin, userHandle);
@@ -1101,7 +1097,7 @@ public class DevicePolicyManager {
* @param length The new desired minimum password length. A value of 0
* means there is no restriction.
*/
- public void setPasswordMinimumLength(ComponentName admin, int length) {
+ public void setPasswordMinimumLength(@NonNull ComponentName admin, int length) {
if (mService != null) {
try {
mService.setPasswordMinimumLength(admin, length);
@@ -1114,15 +1110,15 @@ public class DevicePolicyManager {
/**
* Retrieve the current minimum password length for all admins of this
* user and its profiles or a particular one.
- * @param admin The name of the admin component to check, or null to aggregate
+ * @param admin The name of the admin component to check, or {@code null} to aggregate
* all admins.
*/
- public int getPasswordMinimumLength(ComponentName admin) {
+ public int getPasswordMinimumLength(@Nullable ComponentName admin) {
return getPasswordMinimumLength(admin, UserHandle.myUserId());
}
/** @hide per-user version */
- public int getPasswordMinimumLength(ComponentName admin, int userHandle) {
+ public int getPasswordMinimumLength(@Nullable ComponentName admin, int userHandle) {
if (mService != null) {
try {
return mService.getPasswordMinimumLength(admin, userHandle);
@@ -1155,7 +1151,7 @@ public class DevicePolicyManager {
* required in the password. A value of 0 means there is no
* restriction.
*/
- public void setPasswordMinimumUpperCase(ComponentName admin, int length) {
+ public void setPasswordMinimumUpperCase(@NonNull ComponentName admin, int length) {
if (mService != null) {
try {
mService.setPasswordMinimumUpperCase(admin, length);
@@ -1173,17 +1169,17 @@ public class DevicePolicyManager {
* and only applies when the password quality is
* {@link #PASSWORD_QUALITY_COMPLEX}.
*
- * @param admin The name of the admin component to check, or null to
+ * @param admin The name of the admin component to check, or {@code null} to
* aggregate all admins.
* @return The minimum number of upper case letters required in the
* password.
*/
- public int getPasswordMinimumUpperCase(ComponentName admin) {
+ public int getPasswordMinimumUpperCase(@Nullable ComponentName admin) {
return getPasswordMinimumUpperCase(admin, UserHandle.myUserId());
}
/** @hide per-user version */
- public int getPasswordMinimumUpperCase(ComponentName admin, int userHandle) {
+ public int getPasswordMinimumUpperCase(@Nullable ComponentName admin, int userHandle) {
if (mService != null) {
try {
return mService.getPasswordMinimumUpperCase(admin, userHandle);
@@ -1216,7 +1212,7 @@ public class DevicePolicyManager {
* required in the password. A value of 0 means there is no
* restriction.
*/
- public void setPasswordMinimumLowerCase(ComponentName admin, int length) {
+ public void setPasswordMinimumLowerCase(@NonNull ComponentName admin, int length) {
if (mService != null) {
try {
mService.setPasswordMinimumLowerCase(admin, length);
@@ -1234,17 +1230,17 @@ public class DevicePolicyManager {
* and only applies when the password quality is
* {@link #PASSWORD_QUALITY_COMPLEX}.
*
- * @param admin The name of the admin component to check, or null to
+ * @param admin The name of the admin component to check, or {@code null} to
* aggregate all admins.
* @return The minimum number of lower case letters required in the
* password.
*/
- public int getPasswordMinimumLowerCase(ComponentName admin) {
+ public int getPasswordMinimumLowerCase(@Nullable ComponentName admin) {
return getPasswordMinimumLowerCase(admin, UserHandle.myUserId());
}
/** @hide per-user version */
- public int getPasswordMinimumLowerCase(ComponentName admin, int userHandle) {
+ public int getPasswordMinimumLowerCase(@Nullable ComponentName admin, int userHandle) {
if (mService != null) {
try {
return mService.getPasswordMinimumLowerCase(admin, userHandle);
@@ -1276,7 +1272,7 @@ public class DevicePolicyManager {
* @param length The new desired minimum number of letters required in the
* password. A value of 0 means there is no restriction.
*/
- public void setPasswordMinimumLetters(ComponentName admin, int length) {
+ public void setPasswordMinimumLetters(@NonNull ComponentName admin, int length) {
if (mService != null) {
try {
mService.setPasswordMinimumLetters(admin, length);
@@ -1293,16 +1289,16 @@ public class DevicePolicyManager {
* and only applies when the password quality is
* {@link #PASSWORD_QUALITY_COMPLEX}.
*
- * @param admin The name of the admin component to check, or null to
+ * @param admin The name of the admin component to check, or {@code null} to
* aggregate all admins.
* @return The minimum number of letters required in the password.
*/
- public int getPasswordMinimumLetters(ComponentName admin) {
+ public int getPasswordMinimumLetters(@Nullable ComponentName admin) {
return getPasswordMinimumLetters(admin, UserHandle.myUserId());
}
/** @hide per-user version */
- public int getPasswordMinimumLetters(ComponentName admin, int userHandle) {
+ public int getPasswordMinimumLetters(@Nullable ComponentName admin, int userHandle) {
if (mService != null) {
try {
return mService.getPasswordMinimumLetters(admin, userHandle);
@@ -1334,7 +1330,7 @@ public class DevicePolicyManager {
* @param length The new desired minimum number of numerical digits required
* in the password. A value of 0 means there is no restriction.
*/
- public void setPasswordMinimumNumeric(ComponentName admin, int length) {
+ public void setPasswordMinimumNumeric(@NonNull ComponentName admin, int length) {
if (mService != null) {
try {
mService.setPasswordMinimumNumeric(admin, length);
@@ -1352,16 +1348,16 @@ public class DevicePolicyManager {
* and only applies when the password quality is
* {@link #PASSWORD_QUALITY_COMPLEX}.
*
- * @param admin The name of the admin component to check, or null to
+ * @param admin The name of the admin component to check, or {@code null} to
* aggregate all admins.
* @return The minimum number of numerical digits required in the password.
*/
- public int getPasswordMinimumNumeric(ComponentName admin) {
+ public int getPasswordMinimumNumeric(@Nullable ComponentName admin) {
return getPasswordMinimumNumeric(admin, UserHandle.myUserId());
}
/** @hide per-user version */
- public int getPasswordMinimumNumeric(ComponentName admin, int userHandle) {
+ public int getPasswordMinimumNumeric(@Nullable ComponentName admin, int userHandle) {
if (mService != null) {
try {
return mService.getPasswordMinimumNumeric(admin, userHandle);
@@ -1393,7 +1389,7 @@ public class DevicePolicyManager {
* @param length The new desired minimum number of symbols required in the
* password. A value of 0 means there is no restriction.
*/
- public void setPasswordMinimumSymbols(ComponentName admin, int length) {
+ public void setPasswordMinimumSymbols(@NonNull ComponentName admin, int length) {
if (mService != null) {
try {
mService.setPasswordMinimumSymbols(admin, length);
@@ -1410,16 +1406,16 @@ public class DevicePolicyManager {
* and only applies when the password quality is
* {@link #PASSWORD_QUALITY_COMPLEX}.
*
- * @param admin The name of the admin component to check, or null to
+ * @param admin The name of the admin component to check, or {@code null} to
* aggregate all admins.
* @return The minimum number of symbols required in the password.
*/
- public int getPasswordMinimumSymbols(ComponentName admin) {
+ public int getPasswordMinimumSymbols(@Nullable ComponentName admin) {
return getPasswordMinimumSymbols(admin, UserHandle.myUserId());
}
/** @hide per-user version */
- public int getPasswordMinimumSymbols(ComponentName admin, int userHandle) {
+ public int getPasswordMinimumSymbols(@Nullable ComponentName admin, int userHandle) {
if (mService != null) {
try {
return mService.getPasswordMinimumSymbols(admin, userHandle);
@@ -1451,7 +1447,7 @@ public class DevicePolicyManager {
* @param length The new desired minimum number of letters required in the
* password. A value of 0 means there is no restriction.
*/
- public void setPasswordMinimumNonLetter(ComponentName admin, int length) {
+ public void setPasswordMinimumNonLetter(@NonNull ComponentName admin, int length) {
if (mService != null) {
try {
mService.setPasswordMinimumNonLetter(admin, length);
@@ -1469,16 +1465,16 @@ public class DevicePolicyManager {
* and only applies when the password quality is
* {@link #PASSWORD_QUALITY_COMPLEX}.
*
- * @param admin The name of the admin component to check, or null to
+ * @param admin The name of the admin component to check, or {@code null} to
* aggregate all admins.
* @return The minimum number of letters required in the password.
*/
- public int getPasswordMinimumNonLetter(ComponentName admin) {
+ public int getPasswordMinimumNonLetter(@Nullable ComponentName admin) {
return getPasswordMinimumNonLetter(admin, UserHandle.myUserId());
}
/** @hide per-user version */
- public int getPasswordMinimumNonLetter(ComponentName admin, int userHandle) {
+ public int getPasswordMinimumNonLetter(@Nullable ComponentName admin, int userHandle) {
if (mService != null) {
try {
return mService.getPasswordMinimumNonLetter(admin, userHandle);
@@ -1511,7 +1507,7 @@ public class DevicePolicyManager {
* @param length The new desired length of password history. A value of 0
* means there is no restriction.
*/
- public void setPasswordHistoryLength(ComponentName admin, int length) {
+ public void setPasswordHistoryLength(@NonNull ComponentName admin, int length) {
if (mService != null) {
try {
mService.setPasswordHistoryLength(admin, length);
@@ -1543,7 +1539,7 @@ public class DevicePolicyManager {
* @param timeout The limit (in ms) that a password can remain in effect. A value of 0
* means there is no restriction (unlimited).
*/
- public void setPasswordExpirationTimeout(ComponentName admin, long timeout) {
+ public void setPasswordExpirationTimeout(@NonNull ComponentName admin, long timeout) {
if (mService != null) {
try {
mService.setPasswordExpirationTimeout(admin, timeout);
@@ -1557,12 +1553,12 @@ public class DevicePolicyManager {
* Get the password expiration timeout for the given admin. The expiration timeout is the
* recurring expiration timeout provided in the call to
* {@link #setPasswordExpirationTimeout(ComponentName, long)} for the given admin or the
- * aggregate of all policy administrators if admin is null.
+ * aggregate of all policy administrators if {@code admin} is null.
*
- * @param admin The name of the admin component to check, or null to aggregate all admins.
+ * @param admin The name of the admin component to check, or {@code null} to aggregate all admins.
* @return The timeout for the given admin or the minimum of all timeouts
*/
- public long getPasswordExpirationTimeout(ComponentName admin) {
+ public long getPasswordExpirationTimeout(@Nullable ComponentName admin) {
if (mService != null) {
try {
return mService.getPasswordExpirationTimeout(admin, UserHandle.myUserId());
@@ -1580,10 +1576,10 @@ public class DevicePolicyManager {
* If admin is null, then a composite of all expiration timeouts is returned
* - which will be the minimum of all timeouts.
*
- * @param admin The name of the admin component to check, or null to aggregate all admins.
+ * @param admin The name of the admin component to check, or {@code null} to aggregate all admins.
* @return The password expiration time, in ms.
*/
- public long getPasswordExpiration(ComponentName admin) {
+ public long getPasswordExpiration(@Nullable ComponentName admin) {
if (mService != null) {
try {
return mService.getPasswordExpiration(admin, UserHandle.myUserId());
@@ -1597,16 +1593,16 @@ public class DevicePolicyManager {
/**
* Retrieve the current password history length for all admins of this
* user and its profiles or a particular one.
- * @param admin The name of the admin component to check, or null to aggregate
+ * @param admin The name of the admin component to check, or {@code null} to aggregate
* all admins.
* @return The length of the password history
*/
- public int getPasswordHistoryLength(ComponentName admin) {
+ public int getPasswordHistoryLength(@Nullable ComponentName admin) {
return getPasswordHistoryLength(admin, UserHandle.myUserId());
}
/** @hide per-user version */
- public int getPasswordHistoryLength(ComponentName admin, int userHandle) {
+ public int getPasswordHistoryLength(@Nullable ComponentName admin, int userHandle) {
if (mService != null) {
try {
return mService.getPasswordHistoryLength(admin, userHandle);
@@ -1705,7 +1701,7 @@ public class DevicePolicyManager {
* @param num The number of failed password attempts at which point the
* device will wipe its data.
*/
- public void setMaximumFailedPasswordsForWipe(ComponentName admin, int num) {
+ public void setMaximumFailedPasswordsForWipe(@NonNull ComponentName admin, int num) {
if (mService != null) {
try {
mService.setMaximumFailedPasswordsForWipe(admin, num);
@@ -1719,15 +1715,15 @@ public class DevicePolicyManager {
* Retrieve the current maximum number of login attempts that are allowed
* before the device wipes itself, for all admins of this user and its profiles
* or a particular one.
- * @param admin The name of the admin component to check, or null to aggregate
+ * @param admin The name of the admin component to check, or {@code null} to aggregate
* all admins.
*/
- public int getMaximumFailedPasswordsForWipe(ComponentName admin) {
+ public int getMaximumFailedPasswordsForWipe(@Nullable ComponentName admin) {
return getMaximumFailedPasswordsForWipe(admin, UserHandle.myUserId());
}
/** @hide per-user version */
- public int getMaximumFailedPasswordsForWipe(ComponentName admin, int userHandle) {
+ public int getMaximumFailedPasswordsForWipe(@Nullable ComponentName admin, int userHandle) {
if (mService != null) {
try {
return mService.getMaximumFailedPasswordsForWipe(admin, userHandle);
@@ -1824,7 +1820,7 @@ public class DevicePolicyManager {
* @param timeMs The new desired maximum time to lock in milliseconds.
* A value of 0 means there is no restriction.
*/
- public void setMaximumTimeToLock(ComponentName admin, long timeMs) {
+ public void setMaximumTimeToLock(@NonNull ComponentName admin, long timeMs) {
if (mService != null) {
try {
mService.setMaximumTimeToLock(admin, timeMs);
@@ -1837,17 +1833,17 @@ public class DevicePolicyManager {
/**
* Retrieve the current maximum time to unlock for all admins of this user
* and its profiles or a particular one.
- * @param admin The name of the admin component to check, or null to aggregate
+ * @param admin The name of the admin component to check, or {@code null} to aggregate
* all admins.
* @return time in milliseconds for the given admin or the minimum value (strictest) of
* all admins if admin is null. Returns 0 if there are no restrictions.
*/
- public long getMaximumTimeToLock(ComponentName admin) {
+ public long getMaximumTimeToLock(@Nullable ComponentName admin) {
return getMaximumTimeToLock(admin, UserHandle.myUserId());
}
/** @hide per-user version */
- public long getMaximumTimeToLock(ComponentName admin, int userHandle) {
+ public long getMaximumTimeToLock(@Nullable ComponentName admin, int userHandle) {
if (mService != null) {
try {
return mService.getMaximumTimeToLock(admin, userHandle);
@@ -1922,21 +1918,20 @@ public class DevicePolicyManager {
* this method; if it has not, a security exception will be thrown.
* Only the first device admin can set the proxy. If a second admin attempts
* to set the proxy, the {@link ComponentName} of the admin originally setting the
- * proxy will be returned. If successful in setting the proxy, null will
+ * proxy will be returned. If successful in setting the proxy, {@code null} will
* be returned.
* The method can be called repeatedly by the device admin alrady setting the
* proxy to update the proxy and exclusion list.
*
- * @param admin Which {@link DeviceAdminReceiver} this request is associated
- * with.
+ * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @param proxySpec the global proxy desired. Must be an HTTP Proxy.
* Pass Proxy.NO_PROXY to reset the proxy.
* @param exclusionList a list of domains to be excluded from the global proxy.
- * @return returns null if the proxy was successfully set, or a {@link ComponentName}
- * of the device admin that sets thew proxy otherwise.
+ * @return {@code null} if the proxy was successfully set, or otherwise a {@link ComponentName}
+ * of the device admin that sets the proxy.
* @hide
*/
- public ComponentName setGlobalProxy(ComponentName admin, Proxy proxySpec,
+ public ComponentName setGlobalProxy(@NonNull ComponentName admin, Proxy proxySpec,
List<String> exclusionList ) {
if (proxySpec == null) {
throw new NullPointerException();
@@ -2001,7 +1996,8 @@ public class DevicePolicyManager {
* @param proxyInfo The a {@link ProxyInfo} object defining the new global
* HTTP proxy. A {@code null} value will clear the global HTTP proxy.
*/
- public void setRecommendedGlobalProxy(ComponentName admin, ProxyInfo proxyInfo) {
+ public void setRecommendedGlobalProxy(@NonNull ComponentName admin, @Nullable ProxyInfo
+ proxyInfo) {
if (mService != null) {
try {
mService.setRecommendedGlobalProxy(admin, proxyInfo);
@@ -2013,8 +2009,8 @@ public class DevicePolicyManager {
/**
* Returns the component name setting the global proxy.
- * @return ComponentName object of the device admin that set the global proxy, or
- * null if no admin has set the proxy.
+ * @return ComponentName object of the device admin that set the global proxy, or {@code null}
+ * if no admin has set the proxy.
* @hide
*/
public ComponentName getGlobalProxyAdmin() {
@@ -2147,7 +2143,7 @@ public class DevicePolicyManager {
* {@link #ENCRYPTION_STATUS_ACTIVE}. This is the value of the requests; Use
* {@link #getStorageEncryptionStatus()} to query the actual device state.
*/
- public int setStorageEncryption(ComponentName admin, boolean encrypt) {
+ public int setStorageEncryption(@NonNull ComponentName admin, boolean encrypt) {
if (mService != null) {
try {
return mService.setStorageEncryption(admin, encrypt);
@@ -2167,7 +2163,7 @@ public class DevicePolicyManager {
* administrators.
* @return true if the admin(s) are requesting encryption, false if not.
*/
- public boolean getStorageEncryption(ComponentName admin) {
+ public boolean getStorageEncryption(@Nullable ComponentName admin) {
if (mService != null) {
try {
return mService.getStorageEncryption(admin, UserHandle.myUserId());
@@ -2216,14 +2212,14 @@ public class DevicePolicyManager {
/**
* Installs the given certificate as a user CA.
*
- * @param admin Which {@link DeviceAdminReceiver} this request is associated with. Use
- * <code>null</code> if calling from a delegated certificate installer.
+ * @param admin Which {@link DeviceAdminReceiver} this request is associated with, or
+ * {@code null} if calling from a delegated certificate installer.
* @param certBuffer encoded form of the certificate to install.
*
* @return false if the certBuffer cannot be parsed or installation is
* interrupted, true otherwise.
*/
- public boolean installCaCert(ComponentName admin, byte[] certBuffer) {
+ public boolean installCaCert(@Nullable ComponentName admin, byte[] certBuffer) {
if (mService != null) {
try {
return mService.installCaCert(admin, certBuffer);
@@ -2237,11 +2233,11 @@ public class DevicePolicyManager {
/**
* Uninstalls the given certificate from trusted user CAs, if present.
*
- * @param admin Which {@link DeviceAdminReceiver} this request is associated with. Use
- * <code>null</code> if calling from a delegated certificate installer.
+ * @param admin Which {@link DeviceAdminReceiver} this request is associated with, or
+ * {@code null} if calling from a delegated certificate installer.
* @param certBuffer encoded form of the certificate to remove.
*/
- public void uninstallCaCert(ComponentName admin, byte[] certBuffer) {
+ public void uninstallCaCert(@Nullable ComponentName admin, byte[] certBuffer) {
if (mService != null) {
try {
final String alias = getCaCertAlias(certBuffer);
@@ -2259,11 +2255,11 @@ public class DevicePolicyManager {
* If a user has installed any certificates by other means than device policy these will be
* included too.
*
- * @param admin Which {@link DeviceAdminReceiver} this request is associated with. Use
- * <code>null</code> if calling from a delegated certificate installer.
+ * @param admin Which {@link DeviceAdminReceiver} this request is associated with, or
+ * {@code null} if calling from a delegated certificate installer.
* @return a List of byte[] arrays, each encoding one user CA certificate.
*/
- public List<byte[]> getInstalledCaCerts(ComponentName admin) {
+ public List<byte[]> getInstalledCaCerts(@Nullable ComponentName admin) {
List<byte[]> certs = new ArrayList<byte[]>();
if (mService != null) {
try {
@@ -2287,10 +2283,10 @@ public class DevicePolicyManager {
* Uninstalls all custom trusted CA certificates from the profile. Certificates installed by
* means other than device policy will also be removed, except for system CA certificates.
*
- * @param admin Which {@link DeviceAdminReceiver} this request is associated with. Use
- * <code>null</code> if calling from a delegated certificate installer.
+ * @param admin Which {@link DeviceAdminReceiver} this request is associated with, or
+ * {@code null} if calling from a delegated certificate installer.
*/
- public void uninstallAllUserCaCerts(ComponentName admin) {
+ public void uninstallAllUserCaCerts(@Nullable ComponentName admin) {
if (mService != null) {
for (String alias : new TrustedCertificateStore().userAliases()) {
try {
@@ -2305,11 +2301,11 @@ public class DevicePolicyManager {
/**
* Returns whether this certificate is installed as a trusted CA.
*
- * @param admin Which {@link DeviceAdminReceiver} this request is associated with. Use
- * <code>null</code> if calling from a delegated certificate installer.
+ * @param admin Which {@link DeviceAdminReceiver} this request is associated with, or
+ * {@code null} if calling from a delegated certificate installer.
* @param certBuffer encoded form of the certificate to look up.
*/
- public boolean hasCaCertInstalled(ComponentName admin, byte[] certBuffer) {
+ public boolean hasCaCertInstalled(@Nullable ComponentName admin, byte[] certBuffer) {
if (mService != null) {
try {
mService.enforceCanManageCaCerts(admin);
@@ -2327,21 +2323,21 @@ public class DevicePolicyManager {
* Called by a device or profile owner to install a certificate and private key pair. The
* keypair will be visible to all apps within the profile.
*
- * @param who Which {@link DeviceAdminReceiver} this request is associated with. Use
- * <code>null</code> if calling from a delegated certificate installer.
+ * @param admin Which {@link DeviceAdminReceiver} this request is associated with, or
+ * {@code null} if calling from a delegated certificate installer.
* @param privKey The private key to install.
* @param cert The certificate to install.
* @param alias The private key alias under which to install the certificate. If a certificate
* with that alias already exists, it will be overwritten.
* @return {@code true} if the keys were installed, {@code false} otherwise.
*/
- public boolean installKeyPair(ComponentName who, PrivateKey privKey, Certificate cert,
+ public boolean installKeyPair(@Nullable ComponentName admin, PrivateKey privKey, Certificate cert,
String alias) {
try {
final byte[] pemCert = Credentials.convertToPem(cert);
final byte[] pkcs8Key = KeyFactory.getInstance(privKey.getAlgorithm())
.getKeySpec(privKey, PKCS8EncodedKeySpec.class).getEncoded();
- return mService.installKeyPair(who, pkcs8Key, pemCert, alias);
+ return mService.installKeyPair(admin, pkcs8Key, pemCert, alias);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
} catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
@@ -2353,7 +2349,7 @@ public class DevicePolicyManager {
}
/**
- * Returns the alias of a given CA certificate in the certificate store, or null if it
+ * @return the alias of a given CA certificate in the certificate store, or {@code null} if it
* doesn't exist.
*/
private static String getCaCertAlias(byte[] certBuffer) throws CertificateException {
@@ -2373,15 +2369,15 @@ public class DevicePolicyManager {
* it is later cleared by calling this method with a null value or uninstallling the certificate
* installer.
*
- * @param who Which {@link DeviceAdminReceiver} this request is associated with.
+ * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @param installerPackage The package name of the certificate installer which will be given
- * access. If <code>null</code> is given the current package will be cleared.
+ * access. If {@code null} is given the current package will be cleared.
*/
- public void setCertInstallerPackage(ComponentName who, String installerPackage)
- throws SecurityException {
+ public void setCertInstallerPackage(@NonNull ComponentName admin, @Nullable String
+ installerPackage) throws SecurityException {
if (mService != null) {
try {
- mService.setCertInstallerPackage(who, installerPackage);
+ mService.setCertInstallerPackage(admin, installerPackage);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
@@ -2392,14 +2388,14 @@ public class DevicePolicyManager {
* Called by a profile owner or device owner to retrieve the certificate installer for the
* current user. null if none is set.
*
- * @param who Which {@link DeviceAdminReceiver} this request is associated with.
- * @return The package name of the current delegated certificate installer. <code>null</code>
+ * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+ * @return The package name of the current delegated certificate installer, or {@code null}
* if none is set.
*/
- public String getCertInstallerPackage(ComponentName who) throws SecurityException {
+ public String getCertInstallerPackage(@NonNull ComponentName admin) throws SecurityException {
if (mService != null) {
try {
- return mService.getCertInstallerPackage(who);
+ return mService.getCertInstallerPackage(admin);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
@@ -2419,7 +2415,7 @@ public class DevicePolicyManager {
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @param disabled Whether or not the camera should be disabled.
*/
- public void setCameraDisabled(ComponentName admin, boolean disabled) {
+ public void setCameraDisabled(@NonNull ComponentName admin, boolean disabled) {
if (mService != null) {
try {
mService.setCameraDisabled(admin, disabled);
@@ -2432,15 +2428,15 @@ public class DevicePolicyManager {
/**
* Determine whether or not the device's cameras have been disabled for this user,
* either by the current admin, if specified, or all admins.
- * @param admin The name of the admin component to check, or null to check if any admins
+ * @param admin The name of the admin component to check, or {@code null} to check whether any admins
* have disabled the camera
*/
- public boolean getCameraDisabled(ComponentName admin) {
+ public boolean getCameraDisabled(@Nullable ComponentName admin) {
return getCameraDisabled(admin, UserHandle.myUserId());
}
/** @hide per-user version */
- public boolean getCameraDisabled(ComponentName admin, int userHandle) {
+ public boolean getCameraDisabled(@Nullable ComponentName admin, int userHandle) {
if (mService != null) {
try {
return mService.getCameraDisabled(admin, userHandle);
@@ -2463,7 +2459,7 @@ public class DevicePolicyManager {
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @param disabled Whether screen capture is disabled or not.
*/
- public void setScreenCaptureDisabled(ComponentName admin, boolean disabled) {
+ public void setScreenCaptureDisabled(@NonNull ComponentName admin, boolean disabled) {
if (mService != null) {
try {
mService.setScreenCaptureDisabled(admin, disabled);
@@ -2476,15 +2472,15 @@ public class DevicePolicyManager {
/**
* Determine whether or not screen capture has been disabled by the current
* admin, if specified, or all admins.
- * @param admin The name of the admin component to check, or null to check if any admins
+ * @param admin The name of the admin component to check, or {@code null} to check whether any admins
* have disabled screen capture.
*/
- public boolean getScreenCaptureDisabled(ComponentName admin) {
+ public boolean getScreenCaptureDisabled(@Nullable ComponentName admin) {
return getScreenCaptureDisabled(admin, UserHandle.myUserId());
}
/** @hide per-user version */
- public boolean getScreenCaptureDisabled(ComponentName admin, int userHandle) {
+ public boolean getScreenCaptureDisabled(@Nullable ComponentName admin, int userHandle) {
if (mService != null) {
try {
return mService.getScreenCaptureDisabled(admin, userHandle);
@@ -2507,7 +2503,7 @@ public class DevicePolicyManager {
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @param required Whether auto time is set required or not.
*/
- public void setAutoTimeRequired(ComponentName admin, boolean required) {
+ public void setAutoTimeRequired(@NonNull ComponentName admin, boolean required) {
if (mService != null) {
try {
mService.setAutoTimeRequired(admin, required);
@@ -2561,7 +2557,7 @@ public class DevicePolicyManager {
* {@link #KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS}, {@link #KEYGUARD_DISABLE_FINGERPRINT},
* {@link #KEYGUARD_DISABLE_FEATURES_ALL}
*/
- public void setKeyguardDisabledFeatures(ComponentName admin, int which) {
+ public void setKeyguardDisabledFeatures(@NonNull ComponentName admin, int which) {
if (mService != null) {
try {
mService.setKeyguardDisabledFeatures(admin, which);
@@ -2574,17 +2570,17 @@ public class DevicePolicyManager {
/**
* Determine whether or not features have been disabled in keyguard either by the current
* admin, if specified, or all admins.
- * @param admin The name of the admin component to check, or null to check if any admins
+ * @param admin The name of the admin component to check, or {@code null} to check whether any admins
* have disabled features in keyguard.
* @return bitfield of flags. See {@link #setKeyguardDisabledFeatures(ComponentName, int)}
* for a list.
*/
- public int getKeyguardDisabledFeatures(ComponentName admin) {
+ public int getKeyguardDisabledFeatures(@Nullable ComponentName admin) {
return getKeyguardDisabledFeatures(admin, UserHandle.myUserId());
}
/** @hide per-user version */
- public int getKeyguardDisabledFeatures(ComponentName admin, int userHandle) {
+ public int getKeyguardDisabledFeatures(@Nullable ComponentName admin, int userHandle) {
if (mService != null) {
try {
return mService.getKeyguardDisabledFeatures(admin, userHandle);
@@ -2598,7 +2594,8 @@ public class DevicePolicyManager {
/**
* @hide
*/
- public void setActiveAdmin(ComponentName policyReceiver, boolean refreshing, int userHandle) {
+ public void setActiveAdmin(@NonNull ComponentName policyReceiver, boolean refreshing,
+ int userHandle) {
if (mService != null) {
try {
mService.setActiveAdmin(policyReceiver, refreshing, userHandle);
@@ -2611,15 +2608,15 @@ public class DevicePolicyManager {
/**
* @hide
*/
- public void setActiveAdmin(ComponentName policyReceiver, boolean refreshing) {
+ public void setActiveAdmin(@NonNull ComponentName policyReceiver, boolean refreshing) {
setActiveAdmin(policyReceiver, refreshing, UserHandle.myUserId());
}
/**
- * Returns the DeviceAdminInfo as defined by the administrator's package info & meta-data
+ * Returns the DeviceAdminInfo as defined by the administrator's package info &amp; meta-data
* @hide
*/
- public DeviceAdminInfo getAdminInfo(ComponentName cn) {
+ public DeviceAdminInfo getAdminInfo(@NonNull ComponentName cn) {
ActivityInfo ai;
try {
ai = mContext.getPackageManager().getReceiverInfo(cn,
@@ -2646,7 +2643,7 @@ public class DevicePolicyManager {
/**
* @hide
*/
- public void getRemoveWarning(ComponentName admin, RemoteCallback result) {
+ public void getRemoveWarning(@Nullable ComponentName admin, RemoteCallback result) {
if (mService != null) {
try {
mService.getRemoveWarning(admin, result, UserHandle.myUserId());
@@ -2740,10 +2737,10 @@ public class DevicePolicyManager {
/**
* Used to determine if a particular package has been registered as a Device Owner app.
* A device owner app is a special device admin that cannot be deactivated by the user, once
- * activated as a device admin. It also cannot be uninstalled. To check if a particular
+ * activated as a device admin. It also cannot be uninstalled. To check whether a particular
* package is currently registered as the device owner app, pass in the package name from
* {@link Context#getPackageName()} to this method.<p/>This is useful for device
- * admin apps that want to check if they are also registered as the device owner app. The
+ * admin apps that want to check whether they are also registered as the device owner app. The
* exact mechanism by which a device admin app is registered as a device owner app is defined by
* the setup process.
* @param packageName the package name of the app, to compare with the registered device owner
@@ -2820,19 +2817,20 @@ public class DevicePolicyManager {
* MANAGE_DEVICE_ADMINS permission before the device is provisioned or by a device owner app. A
* device initializer app is granted device owner privileges during device initialization and
* profile owner privileges during secondary user initialization.
- * @param who Which {@link DeviceAdminReceiver} this request is associated with, or null if not
- * called by the device owner.
+ * @param admin Which {@link DeviceAdminReceiver} this request is associated with, or
+ * {@code null} if not called by the device owner.
* @param initializer Which {@link DeviceAdminReceiver} to make device initializer.
* @return whether the component was successfully registered as the device initializer.
* @throws IllegalArgumentException if the componentname is null or invalid
* @throws IllegalStateException if the caller is not device owner or the device has
* already been provisioned or a device initializer already exists.
*/
- public boolean setDeviceInitializer(ComponentName who, ComponentName initializer)
+ public boolean setDeviceInitializer(@Nullable ComponentName admin,
+ @NonNull ComponentName initializer)
throws IllegalArgumentException, IllegalStateException {
if (mService != null) {
try {
- return mService.setDeviceInitializer(who, initializer);
+ return mService.setDeviceInitializer(admin, initializer);
} catch (RemoteException re) {
Log.w(TAG, "Failed to set device initializer");
}
@@ -2863,12 +2861,12 @@ public class DevicePolicyManager {
* subsequently created users. This method can be called by either the device owner or device
* initializer itself. The caller must be an active administrator.
*
- * @param who Which {@link DeviceAdminReceiver} this request is associated with.
+ * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
*/
- public void clearDeviceInitializerApp(ComponentName who) {
+ public void clearDeviceInitializerApp(@NonNull ComponentName admin) {
if (mService != null) {
try {
- mService.clearDeviceInitializer(who);
+ mService.clearDeviceInitializer(admin);
} catch (RemoteException re) {
Log.w(TAG, "Failed to clear device initializer");
}
@@ -2927,7 +2925,7 @@ public class DevicePolicyManager {
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @return whether the user is now enabled.
*/
- public boolean setUserEnabled(ComponentName admin) {
+ public boolean setUserEnabled(@NonNull ComponentName admin) {
if (mService != null) {
try {
return mService.setUserEnabled(admin);
@@ -2955,7 +2953,7 @@ public class DevicePolicyManager {
* the user has already been set up.
*/
@SystemApi
- public boolean setActiveProfileOwner(ComponentName admin, @Deprecated String ownerName)
+ public boolean setActiveProfileOwner(@NonNull ComponentName admin, @Deprecated String ownerName)
throws IllegalArgumentException {
if (mService != null) {
try {
@@ -2980,7 +2978,7 @@ public class DevicePolicyManager {
* @return
*/
@SystemApi
- public void clearProfileOwner(ComponentName admin) {
+ public void clearProfileOwner(@NonNull ComponentName admin) {
if (mService != null) {
try {
mService.clearProfileOwner(admin);
@@ -2992,14 +2990,14 @@ public class DevicePolicyManager {
/**
* @hide
- * Checks if the user was already setup.
+ * Checks whether the user was already setup.
*/
public boolean hasUserSetupCompleted() {
if (mService != null) {
try {
return mService.hasUserSetupCompleted();
} catch (RemoteException re) {
- Log.w(TAG, "Failed to check if user setup has completed");
+ Log.w(TAG, "Failed to check whether user setup has completed");
}
}
return true;
@@ -3021,7 +3019,7 @@ public class DevicePolicyManager {
* @throws IllegalArgumentException if admin is null, the package isn't installed, or the
* preconditions mentioned are not met.
*/
- public boolean setProfileOwner(ComponentName admin, @Deprecated String ownerName,
+ public boolean setProfileOwner(@NonNull ComponentName admin, @Deprecated String ownerName,
int userHandle) throws IllegalArgumentException {
if (admin == null) {
throw new NullPointerException("admin cannot be null");
@@ -3048,7 +3046,7 @@ public class DevicePolicyManager {
*
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
*/
- public void setProfileEnabled(ComponentName admin) {
+ public void setProfileEnabled(@NonNull ComponentName admin) {
if (mService != null) {
try {
mService.setProfileEnabled(admin);
@@ -3066,17 +3064,18 @@ public class DevicePolicyManager {
* @see #isProfileOwnerApp
* @see #isDeviceOwnerApp
*
+ * @param admin Which {@link DeviceAdminReceiver} this request is associate with.
* @param profileName The name of the profile.
*/
- public void setProfileName(ComponentName who, String profileName) {
+ public void setProfileName(@NonNull ComponentName admin, String profileName) {
if (mService != null) {
try {
- mService.setProfileName(who, profileName);
- } catch (RemoteException e) {
- Log.w(TAG, "Failed talking with device policy service", e);
+ mService.setProfileName(admin, profileName);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed talking with device policy service", e);
+ }
}
}
-}
/**
* Used to determine if a particular package is registered as the profile owner for the
@@ -3102,7 +3101,7 @@ public class DevicePolicyManager {
/**
* @hide
- * @return the packageName of the owner of the given user profile or null if no profile
+ * @return the packageName of the owner of the given user profile or {@code null} if no profile
* owner has been set for that user.
* @throws IllegalArgumentException if the userId is invalid.
*/
@@ -3130,8 +3129,8 @@ public class DevicePolicyManager {
/**
* @hide
- * @return the human readable name of the organisation associated with this DPM or null if
- * one is not set.
+ * @return the human readable name of the organisation associated with this DPM or {@code null}
+ * if one is not set.
* @throws IllegalArgumentException if the userId is invalid.
*/
public String getProfileOwnerName() throws IllegalArgumentException {
@@ -3185,8 +3184,8 @@ public class DevicePolicyManager {
* @param filter The IntentFilter for which a default handler is added.
* @param activity The Activity that is added as default intent handler.
*/
- public void addPersistentPreferredActivity(ComponentName admin, IntentFilter filter,
- ComponentName activity) {
+ public void addPersistentPreferredActivity(@NonNull ComponentName admin, IntentFilter filter,
+ @NonNull ComponentName activity) {
if (mService != null) {
try {
mService.addPersistentPreferredActivity(admin, filter, activity);
@@ -3206,7 +3205,7 @@ public class DevicePolicyManager {
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @param packageName The name of the package for which preferences are removed.
*/
- public void clearPackagePersistentPreferredActivities(ComponentName admin,
+ public void clearPackagePersistentPreferredActivities(@NonNull ComponentName admin,
String packageName) {
if (mService != null) {
try {
@@ -3241,7 +3240,7 @@ public class DevicePolicyManager {
*
* @see UserManager#KEY_RESTRICTIONS_PENDING
*/
- public void setApplicationRestrictions(ComponentName admin, String packageName,
+ public void setApplicationRestrictions(@NonNull ComponentName admin, String packageName,
Bundle settings) {
if (mService != null) {
try {
@@ -3271,8 +3270,8 @@ public class DevicePolicyManager {
* then it's up to the TrustAgent itself to aggregate the values from all device admins.
* <p>Consult documentation for the specific TrustAgent to determine legal options parameters.
*/
- public void setTrustAgentConfiguration(ComponentName admin, ComponentName target,
- PersistableBundle configuration) {
+ public void setTrustAgentConfiguration(@NonNull ComponentName admin,
+ @NonNull ComponentName target, PersistableBundle configuration) {
if (mService != null) {
try {
mService.setTrustAgentConfiguration(admin, target, configuration);
@@ -3296,14 +3295,14 @@ public class DevicePolicyManager {
* @param agent Which component to get enabled features for.
* @return configuration for the given trust agent.
*/
- public List<PersistableBundle> getTrustAgentConfiguration(ComponentName admin,
- ComponentName agent) {
+ public List<PersistableBundle> getTrustAgentConfiguration(@Nullable ComponentName admin,
+ @NonNull ComponentName agent) {
return getTrustAgentConfiguration(admin, agent, UserHandle.myUserId());
}
/** @hide per-user version */
- public List<PersistableBundle> getTrustAgentConfiguration(ComponentName admin,
- ComponentName agent, int userHandle) {
+ public List<PersistableBundle> getTrustAgentConfiguration(@Nullable ComponentName admin,
+ @NonNull ComponentName agent, int userHandle) {
if (mService != null) {
try {
return mService.getTrustAgentConfiguration(admin, agent, userHandle);
@@ -3321,13 +3320,13 @@ public class DevicePolicyManager {
* <p>The calling device admin must be a profile owner. If it is not, a
* security exception will be thrown.
*
- * @param who Which {@link DeviceAdminReceiver} this request is associated with.
+ * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @param disabled If true caller-Id information in the managed profile is not displayed.
*/
- public void setCrossProfileCallerIdDisabled(ComponentName who, boolean disabled) {
+ public void setCrossProfileCallerIdDisabled(@NonNull ComponentName admin, boolean disabled) {
if (mService != null) {
try {
- mService.setCrossProfileCallerIdDisabled(who, disabled);
+ mService.setCrossProfileCallerIdDisabled(admin, disabled);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
@@ -3341,12 +3340,12 @@ public class DevicePolicyManager {
* <p>The calling device admin must be a profile owner. If it is not, a
* security exception will be thrown.
*
- * @param who Which {@link DeviceAdminReceiver} this request is associated with.
+ * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
*/
- public boolean getCrossProfileCallerIdDisabled(ComponentName who) {
+ public boolean getCrossProfileCallerIdDisabled(@NonNull ComponentName admin) {
if (mService != null) {
try {
- return mService.getCrossProfileCallerIdDisabled(who);
+ return mService.getCrossProfileCallerIdDisabled(admin);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
@@ -3396,15 +3395,15 @@ public class DevicePolicyManager {
* <p>
* This API works on managed profile only.
*
- * @param who Which {@link DeviceAdminReceiver} this request is associated
+ * @param admin Which {@link DeviceAdminReceiver} this request is associated
* with.
* @param disabled If true, bluetooth devices cannot access enterprise
* contacts.
*/
- public void setBluetoothContactSharingDisabled(ComponentName who, boolean disabled) {
+ public void setBluetoothContactSharingDisabled(@NonNull ComponentName admin, boolean disabled) {
if (mService != null) {
try {
- mService.setBluetoothContactSharingDisabled(who, disabled);
+ mService.setBluetoothContactSharingDisabled(admin, disabled);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
@@ -3420,13 +3419,13 @@ public class DevicePolicyManager {
* <p>
* This API works on managed profile only.
*
- * @param who Which {@link DeviceAdminReceiver} this request is associated
+ * @param admin Which {@link DeviceAdminReceiver} this request is associated
* with.
*/
- public boolean getBluetoothContactSharingDisabled(ComponentName who) {
+ public boolean getBluetoothContactSharingDisabled(@NonNull ComponentName admin) {
if (mService != null) {
try {
- return mService.getBluetoothContactSharingDisabled(who);
+ return mService.getBluetoothContactSharingDisabled(admin);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
@@ -3465,7 +3464,7 @@ public class DevicePolicyManager {
* @param flags {@link DevicePolicyManager#FLAG_MANAGED_CAN_ACCESS_PARENT} and
* {@link DevicePolicyManager#FLAG_PARENT_CAN_ACCESS_MANAGED} are supported.
*/
- public void addCrossProfileIntentFilter(ComponentName admin, IntentFilter filter, int flags) {
+ public void addCrossProfileIntentFilter(@NonNull ComponentName admin, IntentFilter filter, int flags) {
if (mService != null) {
try {
mService.addCrossProfileIntentFilter(admin, filter, flags);
@@ -3481,7 +3480,7 @@ public class DevicePolicyManager {
* Only removes those that have been set by the profile owner.
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
*/
- public void clearCrossProfileIntentFilters(ComponentName admin) {
+ public void clearCrossProfileIntentFilters(@NonNull ComponentName admin) {
if (mService != null) {
try {
mService.clearCrossProfileIntentFilters(admin);
@@ -3512,7 +3511,7 @@ public class DevicePolicyManager {
* @return true if setting the restriction succeeded. It fail if there is
* one or more non-system accessibility services enabled, that are not in the list.
*/
- public boolean setPermittedAccessibilityServices(ComponentName admin,
+ public boolean setPermittedAccessibilityServices(@NonNull ComponentName admin,
List<String> packageNames) {
if (mService != null) {
try {
@@ -3533,7 +3532,7 @@ public class DevicePolicyManager {
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @return List of accessiblity service package names.
*/
- public List<String> getPermittedAccessibilityServices(ComponentName admin) {
+ public List<String> getPermittedAccessibilityServices(@NonNull ComponentName admin) {
if (mService != null) {
try {
return mService.getPermittedAccessibilityServices(admin);
@@ -3591,7 +3590,7 @@ public class DevicePolicyManager {
* one or more non-system input methods currently enabled that are not in
* the packageNames list.
*/
- public boolean setPermittedInputMethods(ComponentName admin, List<String> packageNames) {
+ public boolean setPermittedInputMethods(@NonNull ComponentName admin, List<String> packageNames) {
if (mService != null) {
try {
return mService.setPermittedInputMethods(admin, packageNames);
@@ -3612,7 +3611,7 @@ public class DevicePolicyManager {
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @return List of input method package names.
*/
- public List<String> getPermittedInputMethods(ComponentName admin) {
+ public List<String> getPermittedInputMethods(@NonNull ComponentName admin) {
if (mService != null) {
try {
return mService.getPermittedInputMethods(admin);
@@ -3655,9 +3654,10 @@ public class DevicePolicyManager {
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @param name the user's name
* @see UserHandle
- * @return the UserHandle object for the created user, or null if the user could not be created.
+ * @return the {@link android.os.UserHandle} object for the created user, or {@code null} if the
+ * user could not be created.
*/
- public UserHandle createUser(ComponentName admin, String name) {
+ public UserHandle createUser(@NonNull ComponentName admin, String name) {
try {
return mService.createUser(admin, name);
} catch (RemoteException re) {
@@ -3688,10 +3688,11 @@ public class DevicePolicyManager {
* @param adminExtras Extras that will be passed to onEnable of the admin receiver
* on the new user.
* @see UserHandle
- * @return the UserHandle object for the created user, or null if the user could not be created.
+ * @return the {@link android.os.UserHandle} object for the created user, or {@code null} if the
+ * user could not be created.
*/
- public UserHandle createAndInitializeUser(ComponentName admin, String name, String ownerName,
- ComponentName profileOwnerComponent, Bundle adminExtras) {
+ public UserHandle createAndInitializeUser(@NonNull ComponentName admin, String name,
+ String ownerName, @NonNull ComponentName profileOwnerComponent, Bundle adminExtras) {
try {
return mService.createAndInitializeUser(admin, name, ownerName, profileOwnerComponent,
adminExtras);
@@ -3709,7 +3710,7 @@ public class DevicePolicyManager {
* @param userHandle the user to remove.
* @return {@code true} if the user was removed, {@code false} otherwise.
*/
- public boolean removeUser(ComponentName admin, UserHandle userHandle) {
+ public boolean removeUser(@NonNull ComponentName admin, UserHandle userHandle) {
try {
return mService.removeUser(admin, userHandle);
} catch (RemoteException re) {
@@ -3727,7 +3728,7 @@ public class DevicePolicyManager {
*
* @see Intent#ACTION_USER_FOREGROUND
*/
- public boolean switchUser(ComponentName admin, UserHandle userHandle) {
+ public boolean switchUser(@NonNull ComponentName admin, @Nullable UserHandle userHandle) {
try {
return mService.switchUser(admin, userHandle);
} catch (RemoteException re) {
@@ -3749,7 +3750,7 @@ public class DevicePolicyManager {
* {@link DevicePolicyManager#setApplicationRestrictions} was called, or an empty {@link Bundle}
* if no restrictions have been set.
*/
- public Bundle getApplicationRestrictions(ComponentName admin, String packageName) {
+ public Bundle getApplicationRestrictions(@NonNull ComponentName admin, String packageName) {
if (mService != null) {
try {
return mService.getApplicationRestrictions(admin, packageName);
@@ -3771,7 +3772,7 @@ public class DevicePolicyManager {
* @param key The key of the restriction. See the constants in
* {@link android.os.UserManager} for the list of keys.
*/
- public void addUserRestriction(ComponentName admin, String key) {
+ public void addUserRestriction(@NonNull ComponentName admin, String key) {
if (mService != null) {
try {
mService.setUserRestriction(admin, key, true);
@@ -3792,7 +3793,7 @@ public class DevicePolicyManager {
* @param key The key of the restriction. See the constants in
* {@link android.os.UserManager} for the list of keys.
*/
- public void clearUserRestriction(ComponentName admin, String key) {
+ public void clearUserRestriction(@NonNull ComponentName admin, String key) {
if (mService != null) {
try {
mService.setUserRestriction(admin, key, false);
@@ -3812,7 +3813,7 @@ public class DevicePolicyManager {
* unhidden.
* @return boolean Whether the hidden setting of the package was successfully updated.
*/
- public boolean setApplicationHidden(ComponentName admin, String packageName,
+ public boolean setApplicationHidden(@NonNull ComponentName admin, String packageName,
boolean hidden) {
if (mService != null) {
try {
@@ -3831,7 +3832,7 @@ public class DevicePolicyManager {
* @param packageName The name of the package to retrieve the hidden status of.
* @return boolean {@code true} if the package is hidden, {@code false} otherwise.
*/
- public boolean isApplicationHidden(ComponentName admin, String packageName) {
+ public boolean isApplicationHidden(@NonNull ComponentName admin, String packageName) {
if (mService != null) {
try {
return mService.isApplicationHidden(admin, packageName);
@@ -3849,7 +3850,7 @@ public class DevicePolicyManager {
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @param packageName The package to be re-enabled in the current profile.
*/
- public void enableSystemApp(ComponentName admin, String packageName) {
+ public void enableSystemApp(@NonNull ComponentName admin, String packageName) {
if (mService != null) {
try {
mService.enableSystemApp(admin, packageName);
@@ -3868,7 +3869,7 @@ public class DevicePolicyManager {
* intent will be re-enabled in the current profile.
* @return int The number of activities that matched the intent and were installed.
*/
- public int enableSystemApp(ComponentName admin, Intent intent) {
+ public int enableSystemApp(@NonNull ComponentName admin, Intent intent) {
if (mService != null) {
try {
return mService.enableSystemAppWithIntent(admin, intent);
@@ -3894,7 +3895,7 @@ public class DevicePolicyManager {
* @param disabled The boolean indicating that account management will be disabled (true) or
* enabled (false).
*/
- public void setAccountManagementDisabled(ComponentName admin, String accountType,
+ public void setAccountManagementDisabled(@NonNull ComponentName admin, String accountType,
boolean disabled) {
if (mService != null) {
try {
@@ -3950,7 +3951,7 @@ public class DevicePolicyManager {
* @see DeviceAdminReceiver#onLockTaskModeExiting(Context, Intent)
* @see UserManager#DISALLOW_CREATE_WINDOWS
*/
- public void setLockTaskPackages(ComponentName admin, String[] packages)
+ public void setLockTaskPackages(@NonNull ComponentName admin, String[] packages)
throws SecurityException {
if (mService != null) {
try {
@@ -3967,7 +3968,7 @@ public class DevicePolicyManager {
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @hide
*/
- public String[] getLockTaskPackages(ComponentName admin) {
+ public String[] getLockTaskPackages(@NonNull ComponentName admin) {
if (mService != null) {
try {
return mService.getLockTaskPackages(admin);
@@ -4024,7 +4025,7 @@ public class DevicePolicyManager {
* @param setting The name of the setting to update.
* @param value The value to update the setting to.
*/
- public void setGlobalSetting(ComponentName admin, String setting, String value) {
+ public void setGlobalSetting(@NonNull ComponentName admin, String setting, String value) {
if (mService != null) {
try {
mService.setGlobalSetting(admin, setting, value);
@@ -4052,7 +4053,7 @@ public class DevicePolicyManager {
* @param setting The name of the setting to update.
* @param value The value to update the setting to.
*/
- public void setSecureSetting(ComponentName admin, String setting, String value) {
+ public void setSecureSetting(@NonNull ComponentName admin, String setting, String value) {
if (mService != null) {
try {
mService.setSecureSetting(admin, setting, value);
@@ -4072,7 +4073,8 @@ public class DevicePolicyManager {
* {@link RestrictionsReceiver}. If this param is null,
* it removes the restrictions provider previously assigned.
*/
- public void setRestrictionsProvider(ComponentName admin, ComponentName provider) {
+ public void setRestrictionsProvider(@NonNull ComponentName admin,
+ @Nullable ComponentName provider) {
if (mService != null) {
try {
mService.setRestrictionsProvider(admin, provider);
@@ -4088,7 +4090,7 @@ public class DevicePolicyManager {
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @param on {@code true} to mute master volume, {@code false} to turn mute off.
*/
- public void setMasterVolumeMuted(ComponentName admin, boolean on) {
+ public void setMasterVolumeMuted(@NonNull ComponentName admin, boolean on) {
if (mService != null) {
try {
mService.setMasterVolumeMuted(admin, on);
@@ -4104,7 +4106,7 @@ public class DevicePolicyManager {
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @return {@code true} if master volume is muted, {@code false} if it's not.
*/
- public boolean isMasterVolumeMuted(ComponentName admin) {
+ public boolean isMasterVolumeMuted(@NonNull ComponentName admin) {
if (mService != null) {
try {
return mService.isMasterVolumeMuted(admin);
@@ -4123,7 +4125,7 @@ public class DevicePolicyManager {
* @param packageName package to change.
* @param uninstallBlocked true if the user shouldn't be able to uninstall the package.
*/
- public void setUninstallBlocked(ComponentName admin, String packageName,
+ public void setUninstallBlocked(@NonNull ComponentName admin, String packageName,
boolean uninstallBlocked) {
if (mService != null) {
try {
@@ -4139,16 +4141,16 @@ public class DevicePolicyManager {
* Requires the caller to be the profile owner if checking a specific admin's policy.
* <p>
* <strong>Note:</strong> Starting from {@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1}, the
- * behavior of this API is changed such that passing <code>null</code> as the <code>admin</code>
+ * behavior of this API is changed such that passing {@code null} as the {@code admin}
* parameter will return if any admin has blocked the uninstallation. Before L MR1, passing
- * <code>null</code> will cause a NullPointerException to be raised.
+ * {@code null} will cause a NullPointerException to be raised.
*
- * @param admin The name of the admin component whose blocking policy will be checked, or null
- * to check if any admin has blocked the uninstallation.
+ * @param admin The name of the admin component whose blocking policy will be checked, or
+ * {@code null} to check whether any admin has blocked the uninstallation.
* @param packageName package to check.
* @return true if uninstallation is blocked.
*/
- public boolean isUninstallBlocked(ComponentName admin, String packageName) {
+ public boolean isUninstallBlocked(@Nullable ComponentName admin, String packageName) {
if (mService != null) {
try {
return mService.isUninstallBlocked(admin, packageName);
@@ -4168,7 +4170,6 @@ public class DevicePolicyManager {
* provides a different widget type.
* <p>
* <strong>Note:</strong> By default no widget provider package is white-listed.
- * </p>
*
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @param packageName The package from which widget providers are white-listed.
@@ -4177,7 +4178,7 @@ public class DevicePolicyManager {
* @see #removeCrossProfileWidgetProvider(android.content.ComponentName, String)
* @see #getCrossProfileWidgetProviders(android.content.ComponentName)
*/
- public boolean addCrossProfileWidgetProvider(ComponentName admin, String packageName) {
+ public boolean addCrossProfileWidgetProvider(@NonNull ComponentName admin, String packageName) {
if (mService != null) {
try {
return mService.addCrossProfileWidgetProvider(admin, packageName);
@@ -4195,7 +4196,6 @@ public class DevicePolicyManager {
* android.content.ComponentName, String)}.
* <p>
* <strong>Note:</strong> By default no widget provider package is white-listed.
- * </p>
*
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @param packageName The package from which widget providers are no longer
@@ -4205,7 +4205,7 @@ public class DevicePolicyManager {
* @see #addCrossProfileWidgetProvider(android.content.ComponentName, String)
* @see #getCrossProfileWidgetProviders(android.content.ComponentName)
*/
- public boolean removeCrossProfileWidgetProvider(ComponentName admin, String packageName) {
+ public boolean removeCrossProfileWidgetProvider(@NonNull ComponentName admin, String packageName) {
if (mService != null) {
try {
return mService.removeCrossProfileWidgetProvider(admin, packageName);
@@ -4226,7 +4226,7 @@ public class DevicePolicyManager {
* @see #addCrossProfileWidgetProvider(android.content.ComponentName, String)
* @see #removeCrossProfileWidgetProvider(android.content.ComponentName, String)
*/
- public List<String> getCrossProfileWidgetProviders(ComponentName admin) {
+ public List<String> getCrossProfileWidgetProviders(@NonNull ComponentName admin) {
if (mService != null) {
try {
List<String> providers = mService.getCrossProfileWidgetProviders(admin);
@@ -4246,7 +4246,7 @@ public class DevicePolicyManager {
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @param icon the bitmap to set as the photo.
*/
- public void setUserIcon(ComponentName admin, Bitmap icon) {
+ public void setUserIcon(@NonNull ComponentName admin, Bitmap icon) {
try {
mService.setUserIcon(admin, icon);
} catch (RemoteException re) {
@@ -4273,16 +4273,17 @@ public class DevicePolicyManager {
* Called by device owners to set a local system update policy. When a new policy is set,
* {@link #ACTION_SYSTEM_UPDATE_POLICY_CHANGED} is broadcasted.
*
- * @param who Which {@link DeviceAdminReceiver} this request is associated with. All components
- * in the device owner package can set system update policies and the most recent policy takes
+ * @param admin Which {@link DeviceAdminReceiver} this request is associated with. All
+ * components in the device owner package can set system update policies and the
+ * most recent policy takes
* effect.
- * @param policy the new policy, or null to clear the current policy.
+ * @param policy the new policy, or {@code null} to clear the current policy.
* @see SystemUpdatePolicy
*/
- public void setSystemUpdatePolicy(ComponentName who, SystemUpdatePolicy policy) {
+ public void setSystemUpdatePolicy(@NonNull ComponentName admin, SystemUpdatePolicy policy) {
if (mService != null) {
try {
- mService.setSystemUpdatePolicy(who, policy);
+ mService.setSystemUpdatePolicy(admin, policy);
} catch (RemoteException re) {
Log.w(TAG, "Error calling setSystemUpdatePolicy", re);
}
@@ -4292,7 +4293,7 @@ public class DevicePolicyManager {
/**
* Retrieve a local system update policy set previously by {@link #setSystemUpdatePolicy}.
*
- * @return The current policy object, or null if no policy is set.
+ * @return The current policy object, or {@code null} if no policy is set.
*/
public SystemUpdatePolicy getSystemUpdatePolicy() {
if (mService != null) {
@@ -4319,7 +4320,7 @@ public class DevicePolicyManager {
* @return {@code false} if attempting to disable the keyguard while a lock password was in
* place. {@code true} otherwise.
*/
- public boolean setKeyguardDisabled(ComponentName admin, boolean disabled) {
+ public boolean setKeyguardDisabled(@NonNull ComponentName admin, boolean disabled) {
try {
return mService.setKeyguardDisabled(admin, disabled);
} catch (RemoteException re) {
@@ -4339,7 +4340,7 @@ public class DevicePolicyManager {
* @return {@code false} if attempting to disable the status bar failed.
* {@code true} otherwise.
*/
- public boolean setStatusBarDisabled(ComponentName admin, boolean disabled) {
+ public boolean setStatusBarDisabled(@NonNull ComponentName admin, boolean disabled) {
try {
return mService.setStatusBarDisabled(admin, disabled);
} catch (RemoteException re) {
@@ -4377,7 +4378,8 @@ public class DevicePolicyManager {
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @param activity The Activity to be started by default during user setup.
*/
- public void setPreferredSetupActivity(ComponentName admin, ComponentName activity) {
+ public void setPreferredSetupActivity(@NonNull ComponentName admin,
+ @NonNull ComponentName activity) {
try {
mService.setPreferredSetupActivity(admin, activity);
} catch (RemoteException re) {
@@ -4395,7 +4397,7 @@ public class DevicePolicyManager {
* @param policy One of the policy constants {@link #PERMISSION_POLICY_PROMPT},
* {@link #PERMISSION_POLICY_AUTO_GRANT} and {@link #PERMISSION_POLICY_AUTO_DENY}.
*/
- public void setPermissionPolicy(ComponentName admin, int policy) {
+ public void setPermissionPolicy(@NonNull ComponentName admin, int policy) {
try {
mService.setPermissionPolicy(admin, policy);
} catch (RemoteException re) {
@@ -4409,7 +4411,7 @@ public class DevicePolicyManager {
* @param admin Which profile or device owner this request is associated with.
* @return the current policy for future permission requests.
*/
- public int getPermissionPolicy(ComponentName admin) {
+ public int getPermissionPolicy(@NonNull ComponentName admin) {
try {
return mService.getPermissionPolicy(admin);
} catch (RemoteException re) {
@@ -4439,7 +4441,7 @@ public class DevicePolicyManager {
* @see #PERMISSION_GRANT_STATE_DEFAULT
* @see #PERMISSION_GRANT_STATE_GRANTED
*/
- public boolean setPermissionGrantState(ComponentName admin, String packageName,
+ public boolean setPermissionGrantState(@NonNull ComponentName admin, String packageName,
String permission, int grantState) {
try {
return mService.setPermissionGrantState(admin, packageName, permission, grantState);
@@ -4466,7 +4468,7 @@ public class DevicePolicyManager {
* @see #setPermissionGrantState(ComponentName, String, String, int)
* @see PackageManager#checkPermission(String, String)
*/
- public int getPermissionGrantState(ComponentName admin, String packageName,
+ public int getPermissionGrantState(@NonNull ComponentName admin, String packageName,
String permission) {
try {
return mService.getPermissionGrantState(admin, packageName, permission);
diff --git a/core/java/android/app/usage/IUsageStatsManager.aidl b/core/java/android/app/usage/IUsageStatsManager.aidl
index 254408a..a9328bc 100644
--- a/core/java/android/app/usage/IUsageStatsManager.aidl
+++ b/core/java/android/app/usage/IUsageStatsManager.aidl
@@ -32,4 +32,5 @@ interface IUsageStatsManager {
UsageEvents queryEvents(long beginTime, long endTime, String callingPackage);
void setAppInactive(String packageName, boolean inactive, int userId);
boolean isAppInactive(String packageName, int userId);
+ void whitelistAppTemporarily(String packageName, long duration, int userId);
}
diff --git a/core/java/android/app/usage/UsageStatsManager.java b/core/java/android/app/usage/UsageStatsManager.java
index 34699d8..c74b0f2 100644
--- a/core/java/android/app/usage/UsageStatsManager.java
+++ b/core/java/android/app/usage/UsageStatsManager.java
@@ -16,6 +16,7 @@
package android.app.usage;
+import android.annotation.SystemApi;
import android.content.Context;
import android.content.pm.ParceledListSlice;
import android.os.RemoteException;
@@ -245,4 +246,25 @@ public final class UsageStatsManager {
// fall through
}
}
+
+ /**
+ * {@hide}
+ * Temporarily whitelist the specified app for a short duration. This is to allow an app
+ * receiving a high priority message to be able to access the network and acquire wakelocks
+ * even if the device is in power-save mode or the app is currently considered inactive.
+ * The caller must hold the CHANGE_DEVICE_IDLE_TEMP_WHITELIST permission.
+ * @param packageName The package name of the app to whitelist.
+ * @param duration Duration to whitelist the app for, in milliseconds. It is recommended that
+ * this be limited to 10s of seconds. Requested duration will be clamped to a few minutes.
+ * @param user The user for whom the package should be whitelisted. Passing in a user that is
+ * not the same as the caller's process will require the INTERACT_ACROSS_USERS permission.
+ * @see #isAppInactive(String)
+ */
+ @SystemApi
+ public void whitelistAppTemporarily(String packageName, long duration, UserHandle user) {
+ try {
+ mService.whitelistAppTemporarily(packageName, duration, user.getIdentifier());
+ } catch (RemoteException re) {
+ }
+ }
}
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index b22b914..8107a97 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -410,6 +410,7 @@ public final class BluetoothAdapter {
* Broadcast Action: The Bluetooth adapter state has changed in LE only mode.
* @hide
*/
+ @SystemApi
public static final String ACTION_BLE_STATE_CHANGED =
"android.bluetooth.adapter.action.BLE_STATE_CHANGED";
@@ -620,17 +621,18 @@ public final class BluetoothAdapter {
* @return true if the local Bluetooth LE adapter is turned on
* @hide
*/
- public boolean isLeEnabled() {
- final int state = getLeState();
- if (state == BluetoothAdapter.STATE_ON) {
- if (DBG) Log.d (TAG, "STATE_ON");
- } else if (state == BluetoothAdapter.STATE_BLE_ON) {
- if (DBG) Log.d (TAG, "STATE_BLE_ON");
- } else {
- if (DBG) Log.d (TAG, "STATE_OFF");
- return false;
- }
- return true;
+ @SystemApi
+ public boolean isLeEnabled() {
+ final int state = getLeState();
+ if (state == BluetoothAdapter.STATE_ON) {
+ if (DBG) Log.d (TAG, "STATE_ON");
+ } else if (state == BluetoothAdapter.STATE_BLE_ON) {
+ if (DBG) Log.d (TAG, "STATE_BLE_ON");
+ } else {
+ if (DBG) Log.d (TAG, "STATE_OFF");
+ return false;
+ }
+ return true;
}
/**
@@ -680,6 +682,7 @@ public final class BluetoothAdapter {
* immediate error
* @hide
*/
+ @SystemApi
public boolean disableBLE() {
if (!isBleScanAlwaysAvailable()) return false;
@@ -742,6 +745,7 @@ public final class BluetoothAdapter {
* immediate error
* @hide
*/
+ @SystemApi
public boolean enableBLE() {
if (!isBleScanAlwaysAvailable()) return false;
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index 26a91e4..dcf06d8 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -567,19 +567,16 @@ public final class BluetoothDevice implements Parcelable {
/**
* No preferrence of physical transport for GATT connections to remote dual-mode devices
- * @hide
*/
public static final int TRANSPORT_AUTO = 0;
/**
* Prefer BR/EDR transport for GATT connections to remote dual-mode devices
- * @hide
*/
public static final int TRANSPORT_BREDR = 1;
/**
* Prefer LE transport for GATT connections to remote dual-mode devices
- * @hide
*/
public static final int TRANSPORT_LE = 2;
@@ -1564,7 +1561,6 @@ public final class BluetoothDevice implements Parcelable {
* {@link BluetoothDevice#TRANSPORT_AUTO} or
* {@link BluetoothDevice#TRANSPORT_BREDR} or {@link BluetoothDevice#TRANSPORT_LE}
* @throws IllegalArgumentException if callback is null
- * @hide
*/
public BluetoothGatt connectGatt(Context context, boolean autoConnect,
BluetoothGattCallback callback, int transport) {
diff --git a/core/java/android/bluetooth/BluetoothPan.java b/core/java/android/bluetooth/BluetoothPan.java
index eb6166a..744f942 100644
--- a/core/java/android/bluetooth/BluetoothPan.java
+++ b/core/java/android/bluetooth/BluetoothPan.java
@@ -138,7 +138,6 @@ public final class BluetoothPan implements BluetoothProfile {
}
if (VDBG) Log.d(TAG, "BluetoothPan() call bindService");
doBind();
- if (VDBG) Log.d(TAG, "BluetoothPan(), bindService called");
}
boolean doBind() {
@@ -185,12 +184,22 @@ public final class BluetoothPan implements BluetoothProfile {
final private IBluetoothStateChangeCallback mStateChangeCallback = new IBluetoothStateChangeCallback.Stub() {
@Override
- public void onBluetoothStateChange(boolean on) throws RemoteException {
- //Handle enable request to bind again.
+ public void onBluetoothStateChange(boolean on) {
+ // Handle enable request to bind again.
+ Log.d(TAG, "onBluetoothStateChange on: " + on);
if (on) {
- Log.d(TAG, "onBluetoothStateChange(on) call bindService");
- doBind();
- if (VDBG) Log.d(TAG, "BluetoothPan(), bindService called");
+ try {
+ if (mPanService == null) {
+ if (VDBG) Log.d(TAG, "onBluetoothStateChange calling doBind()");
+ doBind();
+ }
+
+ } catch (IllegalStateException e) {
+ Log.e(TAG,"onBluetoothStateChange: could not bind to PAN service: ", e);
+
+ } catch (SecurityException e) {
+ Log.e(TAG,"onBluetoothStateChange: could not bind to PAN service: ", e);
+ }
} else {
if (VDBG) Log.d(TAG,"Unbinding service...");
synchronized (mConnection) {
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 62a1617..c01ce4f 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1387,6 +1387,11 @@ public class Intent implements Parcelable, Cloneable {
* <p>
* Output: If {@link #EXTRA_RETURN_RESULT}, returns whether the install
* succeeded.
+ * <p>
+ * <strong>Note:</strong>If your app is targeting API level higher than 22 you
+ * need to hold {@link android.Manifest.permission#REQUEST_INSTALL_PACKAGES}
+ * in order to launch the application installer.
+ * </p>
*
* @see #EXTRA_INSTALLER_PACKAGE_NAME
* @see #EXTRA_NOT_UNKNOWN_SOURCE
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 96bb2ee..9fb6f4d 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -373,6 +373,12 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
public static final int FLAG_EXTRACT_NATIVE_LIBS = 1<<28;
/**
+ * Value for {@link #flags}: {@code true} when the application's rendering
+ * should be hardware accelerated.
+ */
+ public static final int FLAG_HARDWARE_ACCELERATED = 1<<29;
+
+ /**
* Value for {@link #flags}: true if code from this application will need to be
* loaded into other applications' processes. On devices that support multiple
* instruction sets, this implies the code might be loaded into a process that's
@@ -648,11 +654,6 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
*/
public int installLocation = PackageInfo.INSTALL_LOCATION_UNSPECIFIED;
- /**
- * True when the application's rendering should be hardware accelerated.
- */
- public boolean hardwareAccelerated;
-
public void dump(Printer pw, String prefix) {
super.dumpFront(pw, prefix);
if (className != null) {
@@ -692,7 +693,6 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
}
pw.println(prefix + "enabled=" + enabled + " targetSdkVersion=" + targetSdkVersion
+ " versionCode=" + versionCode);
- pw.println(prefix + "hardwareAccelerated=" + hardwareAccelerated);
if (manageSpaceActivityName != null) {
pw.println(prefix + "manageSpaceActivityName="+manageSpaceActivityName);
}
@@ -784,7 +784,6 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
descriptionRes = orig.descriptionRes;
uiOptions = orig.uiOptions;
backupAgentName = orig.backupAgentName;
- hardwareAccelerated = orig.hardwareAccelerated;
fullBackupContent = orig.fullBackupContent;
}
@@ -838,7 +837,6 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
dest.writeString(backupAgentName);
dest.writeInt(descriptionRes);
dest.writeInt(uiOptions);
- dest.writeInt(hardwareAccelerated ? 1 : 0);
dest.writeInt(fullBackupContent);
}
@@ -891,7 +889,6 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
backupAgentName = source.readString();
descriptionRes = source.readInt();
uiOptions = source.readInt();
- hardwareAccelerated = source.readInt() != 0;
fullBackupContent = source.readInt();
}
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 596c0e4..755eb5b 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -2530,7 +2530,9 @@ public class PackageParser {
owner.baseHardwareAccelerated = sa.getBoolean(
com.android.internal.R.styleable.AndroidManifestApplication_hardwareAccelerated,
owner.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.ICE_CREAM_SANDWICH);
- ai.hardwareAccelerated = owner.baseHardwareAccelerated;
+ if (owner.baseHardwareAccelerated) {
+ ai.flags |= ApplicationInfo.FLAG_HARDWARE_ACCELERATED;
+ }
if (sa.getBoolean(
com.android.internal.R.styleable.AndroidManifestApplication_hasCode,
diff --git a/core/java/android/content/res/ColorStateList.java b/core/java/android/content/res/ColorStateList.java
index 14bfac5..579634f 100644
--- a/core/java/android/content/res/ColorStateList.java
+++ b/core/java/android/content/res/ColorStateList.java
@@ -382,6 +382,14 @@ public class ColorStateList implements Parcelable {
defaultAlphaMod = 1.0f;
}
+ // Extract the theme attributes, if any, before attempting to
+ // read from the typed array. This prevents a crash if we have
+ // unresolved attrs.
+ themeAttrsList[i] = a.extractThemeAttrs(themeAttrsList[i]);
+ if (themeAttrsList[i] != null) {
+ hasUnresolvedAttrs = true;
+ }
+
final int baseColor = a.getColor(
R.styleable.ColorStateListItem_color, mColors[i]);
final float alphaMod = a.getFloat(
@@ -391,12 +399,6 @@ public class ColorStateList implements Parcelable {
// Account for any configuration changes.
mChangingConfigurations |= a.getChangingConfigurations();
- // Extract the theme attributes, if any.
- themeAttrsList[i] = a.extractThemeAttrs(themeAttrsList[i]);
- if (themeAttrsList[i] != null) {
- hasUnresolvedAttrs = true;
- }
-
a.recycle();
}
}
diff --git a/core/java/android/content/res/TypedArray.java b/core/java/android/content/res/TypedArray.java
index 1fca920..8bcd5d1 100644
--- a/core/java/android/content/res/TypedArray.java
+++ b/core/java/android/content/res/TypedArray.java
@@ -160,7 +160,6 @@ public class TypedArray {
final TypedValue v = mValue;
if (getValueAt(index, v)) {
- StrictMode.noteResourceMismatch(v);
return v.coerceToString();
}
@@ -181,6 +180,7 @@ public class TypedArray {
* not be coerced to a string.
* @throws RuntimeException if the TypedArray has already been recycled.
*/
+ @Nullable
public String getString(int index) {
if (mRecycled) {
throw new RuntimeException("Cannot make calls to a recycled instance!");
@@ -197,7 +197,6 @@ public class TypedArray {
final TypedValue v = mValue;
if (getValueAt(index, v)) {
- StrictMode.noteResourceMismatch(v);
final CharSequence cs = v.coerceToString();
return cs != null ? cs.toString() : null;
}
@@ -271,7 +270,6 @@ public class TypedArray {
final TypedValue v = mValue;
if (getValueAt(index, v)) {
- StrictMode.noteResourceMismatch(v);
final CharSequence cs = v.coerceToString();
return cs != null ? cs.toString() : null;
}
diff --git a/core/java/android/database/DatabaseUtils.java b/core/java/android/database/DatabaseUtils.java
index e61664c..227066d 100644
--- a/core/java/android/database/DatabaseUtils.java
+++ b/core/java/android/database/DatabaseUtils.java
@@ -270,7 +270,7 @@ public class DatabaseUtils {
window.setStartPosition(position);
window.setNumColumns(numColumns);
if (cursor.moveToPosition(position)) {
- do {
+ rowloop: do {
if (!window.allocRow()) {
break;
}
@@ -307,7 +307,7 @@ public class DatabaseUtils {
}
if (!success) {
window.freeLastRow();
- break;
+ break rowloop;
}
}
position += 1;
diff --git a/core/java/android/hardware/SensorEvent.java b/core/java/android/hardware/SensorEvent.java
index 2bc0f9b..906c2a1 100644
--- a/core/java/android/hardware/SensorEvent.java
+++ b/core/java/android/hardware/SensorEvent.java
@@ -312,7 +312,7 @@ public class SensorEvent {
* </p>
*
* <p>
- * values[2]: Roll, rotation around the x-axis (-90 to 90)
+ * values[2]: Roll, rotation around the y-axis (-90 to 90)
* increasing as the device moves clockwise.
* </p>
* </ul>
@@ -325,6 +325,8 @@ public class SensorEvent {
*
* <p>
* <b>Note:</b> This sensor type exists for legacy reasons, please use
+ * {@link android.hardware.Sensor#TYPE_ROTATION_VECTOR
+ * rotation vector sensor type} and
* {@link android.hardware.SensorManager#getRotationMatrix
* getRotationMatrix()} in conjunction with
* {@link android.hardware.SensorManager#remapCoordinateSystem
diff --git a/core/java/android/hardware/SensorManager.java b/core/java/android/hardware/SensorManager.java
index 861969e..fda889f 100644
--- a/core/java/android/hardware/SensorManager.java
+++ b/core/java/android/hardware/SensorManager.java
@@ -967,8 +967,9 @@ public abstract class SensorManager {
* TYPE_MAGNETIC_FIELD}.
*
* @return <code>true</code> on success, <code>false</code> on failure (for
- * instance, if the device is in free fall). On failure the output
- * matrices are not modified.
+ * instance, if the device is in free fall). Free fall is defined as
+ * condition when the magnitude of the gravity is less than 1/10 of
+ * the nominal value. On failure the output matrices are not modified.
*
* @see #getInclination(float[])
* @see #getOrientation(float[], float[])
@@ -981,6 +982,15 @@ public abstract class SensorManager {
float Ax = gravity[0];
float Ay = gravity[1];
float Az = gravity[2];
+
+ final float normsqA = (Ax*Ax + Ay*Ay + Az*Az);
+ final float g = 9.81f;
+ final float freeFallGravitySquared = 0.01f * g * g;
+ if (normsqA < freeFallGravitySquared) {
+ // gravity less than 10% of normal value
+ return false;
+ }
+
final float Ex = geomagnetic[0];
final float Ey = geomagnetic[1];
final float Ez = geomagnetic[2];
@@ -988,6 +998,7 @@ public abstract class SensorManager {
float Hy = Ez*Ax - Ex*Az;
float Hz = Ex*Ay - Ey*Ax;
final float normH = (float)Math.sqrt(Hx*Hx + Hy*Hy + Hz*Hz);
+
if (normH < 0.1f) {
// device is close to free fall (or in space?), or close to
// magnetic north pole. Typical values are > 100.
@@ -1117,12 +1128,12 @@ public abstract class SensorManager {
* returned by {@link #getRotationMatrix}.
*
* @param X
- * defines on which world axis and direction the X axis of the device
- * is mapped.
+ * defines the axis of the new cooridinate system that coincide with the X axis of the
+ * original coordinate system.
*
* @param Y
- * defines on which world axis and direction the Y axis of the device
- * is mapped.
+ * defines the axis of the new cooridinate system that coincide with the Y axis of the
+ * original coordinate system.
*
* @param outR
* the transformed rotation matrix. inR and outR should not be the same
@@ -1219,27 +1230,18 @@ public abstract class SensorManager {
* <p>
* When it returns, the array values is filled with the result:
* <ul>
- * <li>values[0]: <i>azimuth</i>, rotation around the Z axis.</li>
- * <li>values[1]: <i>pitch</i>, rotation around the X axis.</li>
+ * <li>values[0]: <i>azimuth</i>, rotation around the -Z axis,
+ * i.e. the opposite direction of Z axis.</li>
+ * <li>values[1]: <i>pitch</i>, rotation around the -X axis,
+ * i.e the opposite direction of X axis.</li>
* <li>values[2]: <i>roll</i>, rotation around the Y axis.</li>
* </ul>
- * <p>The reference coordinate-system used is different from the world
- * coordinate-system defined for the rotation matrix:</p>
- * <ul>
- * <li>X is defined as the vector product <b>Y.Z</b> (It is tangential to
- * the ground at the device's current location and roughly points West).</li>
- * <li>Y is tangential to the ground at the device's current location and
- * points towards the magnetic North Pole.</li>
- * <li>Z points towards the center of the Earth and is perpendicular to the ground.</li>
- * </ul>
- *
- * <p>
- * <center><img src="../../../images/axis_globe_inverted.png"
- * alt="Inverted world coordinate-system diagram." border="0" /></center>
- * </p>
* <p>
+ * Applying these three intrinsic rotations in azimuth, pitch and roll order transforms
+ * identity matrix to the rotation matrix given in input R.
* All three angles above are in <b>radians</b> and <b>positive</b> in the
- * <b>counter-clockwise</b> direction.
+ * <b>counter-clockwise</b> direction. Range of output is: azimuth from -&pi; to &pi;,
+ * pitch from -&pi;/2 to &pi;/2 and roll from -&pi; to &pi;.
*
* @param R
* rotation matrix see {@link #getRotationMatrix}.
@@ -1275,6 +1277,7 @@ public abstract class SensorManager {
values[1] = (float)Math.asin(-R[9]);
values[2] = (float)Math.atan2(-R[8], R[10]);
}
+
return values;
}
@@ -1314,9 +1317,9 @@ public abstract class SensorManager {
/** Helper function to compute the angle change between two rotation matrices.
* Given a current rotation matrix (R) and a previous rotation matrix
- * (prevR) computes the rotation around the z,x, and y axes which
+ * (prevR) computes the intrinsic rotation around the z, x, and y axes which
* transforms prevR to R.
- * outputs a 3 element vector containing the z,x, and y angle
+ * outputs a 3 element vector containing the z, x, and y angle
* change at indexes 0, 1, and 2 respectively.
* <p> Each input matrix is either as a 3x3 or 4x4 row-major matrix
* depending on the length of the passed array:
@@ -1333,9 +1336,13 @@ public abstract class SensorManager {
* | R[ 8] R[ 9] R[10] R[11] |
* \ R[12] R[13] R[14] R[15] /
*</pre>
+ *
+ * See {@link #getOrientation} for more detailed definition of the output.
+ *
* @param R current rotation matrix
* @param prevR previous rotation matrix
- * @param angleChange an an array of floats (z, x, and y) in which the angle change is stored
+ * @param angleChange an an array of floats (z, x, and y) in which the angle change
+ * (in radians) is stored
*/
public static void getAngleChange( float[] angleChange, float[] R, float[] prevR) {
diff --git a/core/java/android/hardware/camera2/CameraCaptureSession.java b/core/java/android/hardware/camera2/CameraCaptureSession.java
index b3e7cfc..c22ee5f 100644
--- a/core/java/android/hardware/camera2/CameraCaptureSession.java
+++ b/core/java/android/hardware/camera2/CameraCaptureSession.java
@@ -654,16 +654,22 @@ public abstract class CameraCaptureSession implements AutoCloseable {
/**
* This method is called when the camera device has started capturing
- * the output image for the request, at the beginning of image exposure.
+ * the output image for the request, at the beginning of image exposure, or
+ * when the camera device has started processing an input image for a reprocess
+ * request.
*
- * <p>This callback is invoked right as the capture of a frame begins,
- * so it is the most appropriate time for playing a shutter sound,
- * or triggering UI indicators of capture.</p>
+ * <p>For a regular capture request, this callback is invoked right as
+ * the capture of a frame begins, so it is the most appropriate time
+ * for playing a shutter sound, or triggering UI indicators of capture.</p>
*
* <p>The request that is being used for this capture is provided, along
- * with the actual timestamp for the start of exposure. This timestamp
- * matches the timestamp that will be included in
- * {@link CaptureResult#SENSOR_TIMESTAMP the result timestamp field},
+ * with the actual timestamp for the start of exposure. For a reprocess
+ * request, this timestamp will be the input image's start of exposure
+ * which matches {@link CaptureResult#SENSOR_TIMESTAMP the result timestamp field}
+ * of the {@link TotalCaptureResult} that was used to
+ * {@link CameraDevice#createReprocessCaptureRequest create the reprocess request}.
+ * This timestamp matches the timestamps that will be
+ * included in {@link CaptureResult#SENSOR_TIMESTAMP the result timestamp field},
* and in the buffers sent to each output Surface. These buffer
* timestamps are accessible through, for example,
* {@link android.media.Image#getTimestamp() Image.getTimestamp()} or
@@ -679,7 +685,9 @@ public abstract class CameraCaptureSession implements AutoCloseable {
*
* @param session the session returned by {@link CameraDevice#createCaptureSession}
* @param request the request for the capture that just begun
- * @param timestamp the timestamp at start of capture, in nanoseconds.
+ * @param timestamp the timestamp at start of capture for a regular request, or
+ * the timestamp at the input image's start of capture for a
+ * reprocess request, in nanoseconds.
* @param frameNumber the frame number for this capture
*
* @see android.media.MediaActionSound
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index 4fe257c..d5867a9 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -1068,20 +1068,35 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
/**
* <p>The correction coefficients to correct for this camera device's
- * radial lens distortion.</p>
- * <p>Three cofficients <code>[kappa_1, kappa_2, kappa_3]</code> that
- * can be used to correct the lens's radial geometric
- * distortion with the mapping equations:</p>
- * <pre><code> x_c = x_i * ( 1 + kappa_1 * r^2 + kappa_2 * r^4 + kappa_3 * r^6 )
- * y_c = y_i * ( 1 + kappa_1 * r^2 + kappa_2 * r^4 + kappa_3 * r^6 )
+ * radial and tangential lens distortion.</p>
+ * <p>Three radial distortion coefficients <code>[kappa_1, kappa_2,
+ * kappa_3]</code> and two tangential distortion coefficients
+ * <code>[kappa_4, kappa_5]</code> that can be used to correct the
+ * lens's geometric distortion with the mapping equations:</p>
+ * <pre><code> x_c = x_i * ( 1 + kappa_1 * r^2 + kappa_2 * r^4 + kappa_3 * r^6 ) +
+ * kappa_4 * (2 * x_i * y_i) + kappa_5 * ( r^2 + 2 * x_i^2 )
+ * y_c = y_i * ( 1 + kappa_1 * r^2 + kappa_2 * r^4 + kappa_3 * r^6 ) +
+ * kappa_5 * (2 * x_i * y_i) + kappa_4 * ( r^2 + 2 * y_i^2 )
* </code></pre>
- * <p>where <code>[x_i, y_i]</code> are normalized coordinates with <code>(0,0)</code>
- * at the lens optical center, and <code>[-1, 1]</code> are the edges of
- * the active pixel array; and where <code>[x_c, y_c]</code> are the
- * corrected normalized coordinates with radial distortion
- * removed; and <code>r^2 = x_i^2 + y_i^2</code>.</p>
+ * <p>Here, <code>[x_c, y_c]</code> are the coordinates to sample in the
+ * input image that correspond to the pixel values in the
+ * corrected image at the coordinate <code>[x_i, y_i]</code>:</p>
+ * <pre><code> correctedImage(x_i, y_i) = sample_at(x_c, y_c, inputImage)
+ * </code></pre>
+ * <p>The pixel coordinates are defined in a normalized
+ * coordinate system related to the
+ * android.lens.intrinsicCalibration calibration fields.
+ * Both <code>[x_i, y_i]</code> and <code>[x_c, y_c]</code> have <code>(0,0)</code> at the
+ * lens optical center <code>[c_x, c_y]</code>. The maximum magnitudes
+ * of both x and y coordinates are normalized to be 1 at the
+ * edge further from the optical center, so the range
+ * for both dimensions is <code>-1 &lt;= x &lt;= 1</code>.</p>
+ * <p>Finally, <code>r</code> represents the radial distance from the
+ * optical center, <code>r^2 = x_i^2 + y_i^2</code>, and its magnitude
+ * is therefore no larger than <code>|r| &lt;= sqrt(2)</code>.</p>
+ * <p>The distortion model used is the Brown-Conrady model.</p>
* <p><b>Units</b>:
- * Coefficients for a 6th-degree even radial polynomial.</p>
+ * Unitless coefficients.</p>
* <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
*/
@PublicKey
diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java
index 20e1610..0f002a9 100644
--- a/core/java/android/hardware/camera2/CameraManager.java
+++ b/core/java/android/hardware/camera2/CameraManager.java
@@ -56,7 +56,7 @@ import java.util.ArrayList;
public final class CameraManager {
private static final String TAG = "CameraManager";
- private final boolean DEBUG;
+ private final boolean DEBUG = false;
private static final int USE_CALLING_UID = -1;
@@ -73,7 +73,6 @@ public final class CameraManager {
* @hide
*/
public CameraManager(Context context) {
- DEBUG = Log.isLoggable(TAG, Log.DEBUG);
synchronized(mLock) {
mContext = context;
}
@@ -722,7 +721,7 @@ public final class CameraManager {
implements IBinder.DeathRecipient {
private static final String TAG = "CameraManagerGlobal";
- private final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+ private final boolean DEBUG = false;
// Singleton instance
private static final CameraManagerGlobal gCameraManager =
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index cf091a9..ac29f80 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -51,7 +51,7 @@ import java.util.List;
public abstract class CameraMetadata<TKey> {
private static final String TAG = "CameraMetadataAb";
- private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
+ private static final boolean DEBUG = false;
/**
* Set a camera metadata field to a value. The field definitions can be
@@ -131,7 +131,7 @@ public abstract class CameraMetadata<TKey> {
CameraMetadata<TKey> instance,
int[] filterTags) {
- if (VERBOSE) Log.v(TAG, "getKeysStatic for " + type);
+ if (DEBUG) Log.v(TAG, "getKeysStatic for " + type);
// TotalCaptureResult does not have any of the keys on it, use CaptureResult instead
if (type.equals(TotalCaptureResult.class)) {
@@ -163,10 +163,10 @@ public abstract class CameraMetadata<TKey> {
if (shouldKeyBeAdded(key, field, filterTags)) {
keyList.add(key);
- if (VERBOSE) {
+ if (DEBUG) {
Log.v(TAG, "getKeysStatic - key was added - " + key);
}
- } else if (VERBOSE) {
+ } else if (DEBUG) {
Log.v(TAG, "getKeysStatic - key was filtered - " + key);
}
}
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index f4017d0..df6c986 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -2649,20 +2649,35 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> {
/**
* <p>The correction coefficients to correct for this camera device's
- * radial lens distortion.</p>
- * <p>Three cofficients <code>[kappa_1, kappa_2, kappa_3]</code> that
- * can be used to correct the lens's radial geometric
- * distortion with the mapping equations:</p>
- * <pre><code> x_c = x_i * ( 1 + kappa_1 * r^2 + kappa_2 * r^4 + kappa_3 * r^6 )
- * y_c = y_i * ( 1 + kappa_1 * r^2 + kappa_2 * r^4 + kappa_3 * r^6 )
+ * radial and tangential lens distortion.</p>
+ * <p>Three radial distortion coefficients <code>[kappa_1, kappa_2,
+ * kappa_3]</code> and two tangential distortion coefficients
+ * <code>[kappa_4, kappa_5]</code> that can be used to correct the
+ * lens's geometric distortion with the mapping equations:</p>
+ * <pre><code> x_c = x_i * ( 1 + kappa_1 * r^2 + kappa_2 * r^4 + kappa_3 * r^6 ) +
+ * kappa_4 * (2 * x_i * y_i) + kappa_5 * ( r^2 + 2 * x_i^2 )
+ * y_c = y_i * ( 1 + kappa_1 * r^2 + kappa_2 * r^4 + kappa_3 * r^6 ) +
+ * kappa_5 * (2 * x_i * y_i) + kappa_4 * ( r^2 + 2 * y_i^2 )
* </code></pre>
- * <p>where <code>[x_i, y_i]</code> are normalized coordinates with <code>(0,0)</code>
- * at the lens optical center, and <code>[-1, 1]</code> are the edges of
- * the active pixel array; and where <code>[x_c, y_c]</code> are the
- * corrected normalized coordinates with radial distortion
- * removed; and <code>r^2 = x_i^2 + y_i^2</code>.</p>
+ * <p>Here, <code>[x_c, y_c]</code> are the coordinates to sample in the
+ * input image that correspond to the pixel values in the
+ * corrected image at the coordinate <code>[x_i, y_i]</code>:</p>
+ * <pre><code> correctedImage(x_i, y_i) = sample_at(x_c, y_c, inputImage)
+ * </code></pre>
+ * <p>The pixel coordinates are defined in a normalized
+ * coordinate system related to the
+ * android.lens.intrinsicCalibration calibration fields.
+ * Both <code>[x_i, y_i]</code> and <code>[x_c, y_c]</code> have <code>(0,0)</code> at the
+ * lens optical center <code>[c_x, c_y]</code>. The maximum magnitudes
+ * of both x and y coordinates are normalized to be 1 at the
+ * edge further from the optical center, so the range
+ * for both dimensions is <code>-1 &lt;= x &lt;= 1</code>.</p>
+ * <p>Finally, <code>r</code> represents the radial distance from the
+ * optical center, <code>r^2 = x_i^2 + y_i^2</code>, and its magnitude
+ * is therefore no larger than <code>|r| &lt;= sqrt(2)</code>.</p>
+ * <p>The distortion model used is the Brown-Conrady model.</p>
* <p><b>Units</b>:
- * Coefficients for a 6th-degree even radial polynomial.</p>
+ * Unitless coefficients.</p>
* <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
*/
@PublicKey
@@ -2988,6 +3003,10 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> {
* timestamps measure time in the same timebase as {@link android.os.SystemClock#elapsedRealtimeNanos }, and they can
* be compared to other timestamps from other subsystems that
* are using that base.</p>
+ * <p>For reprocessing, the timestamp will match the start of exposure of
+ * the input image, i.e. {@link CaptureResult#SENSOR_TIMESTAMP the
+ * timestamp} in the TotalCaptureResult that was used to create the
+ * reprocess capture request.</p>
* <p><b>Units</b>: Nanoseconds</p>
* <p><b>Range of valid values:</b><br>
* &gt; 0</p>
diff --git a/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
index 7f4a76c..7a39dd5 100644
--- a/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
@@ -38,7 +38,7 @@ import static com.android.internal.util.Preconditions.*;
public class CameraCaptureSessionImpl extends CameraCaptureSession {
private static final String TAG = "CameraCaptureSession";
- private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
+ private static final boolean DEBUG = false;
/** Simple integer ID for session for debugging */
private final int mId;
@@ -124,7 +124,7 @@ public class CameraCaptureSessionImpl extends CameraCaptureSession {
if (configureSuccess) {
mStateCallback.onConfigured(this);
- if (VERBOSE) Log.v(TAG, mIdString + "Created session successfully");
+ if (DEBUG) Log.v(TAG, mIdString + "Created session successfully");
mConfigureSuccess = true;
} else {
mStateCallback.onConfigureFailed(this);
@@ -160,7 +160,7 @@ public class CameraCaptureSessionImpl extends CameraCaptureSession {
handler = checkHandler(handler, callback);
- if (VERBOSE) {
+ if (DEBUG) {
Log.v(TAG, mIdString + "capture - request " + request + ", callback " + callback +
" handler " + handler);
}
@@ -194,7 +194,7 @@ public class CameraCaptureSessionImpl extends CameraCaptureSession {
handler = checkHandler(handler, callback);
- if (VERBOSE) {
+ if (DEBUG) {
CaptureRequest[] requestArray = requests.toArray(new CaptureRequest[0]);
Log.v(TAG, mIdString + "captureBurst - requests " + Arrays.toString(requestArray) +
", callback " + callback + " handler " + handler);
@@ -218,7 +218,7 @@ public class CameraCaptureSessionImpl extends CameraCaptureSession {
handler = checkHandler(handler, callback);
- if (VERBOSE) {
+ if (DEBUG) {
Log.v(TAG, mIdString + "setRepeatingRequest - request " + request + ", callback " +
callback + " handler" + " " + handler);
}
@@ -247,7 +247,7 @@ public class CameraCaptureSessionImpl extends CameraCaptureSession {
handler = checkHandler(handler, callback);
- if (VERBOSE) {
+ if (DEBUG) {
CaptureRequest[] requestArray = requests.toArray(new CaptureRequest[0]);
Log.v(TAG, mIdString + "setRepeatingBurst - requests " + Arrays.toString(requestArray) +
", callback " + callback + " handler" + "" + handler);
@@ -261,7 +261,7 @@ public class CameraCaptureSessionImpl extends CameraCaptureSession {
public synchronized void stopRepeating() throws CameraAccessException {
checkNotClosed();
- if (VERBOSE) {
+ if (DEBUG) {
Log.v(TAG, mIdString + "stopRepeating");
}
@@ -272,7 +272,7 @@ public class CameraCaptureSessionImpl extends CameraCaptureSession {
public synchronized void abortCaptures() throws CameraAccessException {
checkNotClosed();
- if (VERBOSE) {
+ if (DEBUG) {
Log.v(TAG, mIdString + "abortCaptures");
}
@@ -325,7 +325,7 @@ public class CameraCaptureSessionImpl extends CameraCaptureSession {
* but this would introduce nondeterministic behavior.
*/
- if (VERBOSE) Log.v(TAG, mIdString + "replaceSessionClose");
+ if (DEBUG) Log.v(TAG, mIdString + "replaceSessionClose");
// Set up fast shutdown. Possible alternative paths:
// - This session is active, so close() below starts the shutdown drain
@@ -345,11 +345,11 @@ public class CameraCaptureSessionImpl extends CameraCaptureSession {
public synchronized void close() {
if (mClosed) {
- if (VERBOSE) Log.v(TAG, mIdString + "close - reentering");
+ if (DEBUG) Log.v(TAG, mIdString + "close - reentering");
return;
}
- if (VERBOSE) Log.v(TAG, mIdString + "close - first time");
+ if (DEBUG) Log.v(TAG, mIdString + "close - first time");
mClosed = true;
@@ -498,7 +498,7 @@ public class CameraCaptureSessionImpl extends CameraCaptureSession {
@Override
public void onDisconnected(CameraDevice camera) {
- if (VERBOSE) Log.v(TAG, mIdString + "onDisconnected");
+ if (DEBUG) Log.v(TAG, mIdString + "onDisconnected");
close();
}
@@ -513,14 +513,14 @@ public class CameraCaptureSessionImpl extends CameraCaptureSession {
mIdleDrainer.taskStarted();
mActive = true;
- if (VERBOSE) Log.v(TAG, mIdString + "onActive");
+ if (DEBUG) Log.v(TAG, mIdString + "onActive");
mStateCallback.onActive(session);
}
@Override
public void onIdle(CameraDevice camera) {
boolean isAborting;
- if (VERBOSE) Log.v(TAG, mIdString + "onIdle");
+ if (DEBUG) Log.v(TAG, mIdString + "onIdle");
synchronized (session) {
isAborting = mAborting;
@@ -562,17 +562,17 @@ public class CameraCaptureSessionImpl extends CameraCaptureSession {
// TODO: Queue captures during abort instead of failing them
// since the app won't be able to distinguish the two actives
// Don't signal the application since there's no clean mapping here
- if (VERBOSE) Log.v(TAG, mIdString + "onBusy");
+ if (DEBUG) Log.v(TAG, mIdString + "onBusy");
}
@Override
public void onUnconfigured(CameraDevice camera) {
- if (VERBOSE) Log.v(TAG, mIdString + "onUnconfigured");
+ if (DEBUG) Log.v(TAG, mIdString + "onUnconfigured");
}
@Override
public void onSurfacePrepared(Surface surface) {
- if (VERBOSE) Log.v(TAG, mIdString + "onPrepared");
+ if (DEBUG) Log.v(TAG, mIdString + "onPrepared");
mStateCallback.onSurfacePrepared(session, surface);
}
@@ -631,7 +631,7 @@ public class CameraCaptureSessionImpl extends CameraCaptureSession {
* If the camera is already "IDLE" and no aborts are pending,
* then the drain immediately finishes.
*/
- if (VERBOSE) Log.v(TAG, mIdString + "onSequenceDrained");
+ if (DEBUG) Log.v(TAG, mIdString + "onSequenceDrained");
// Fire session close as soon as all sequences are complete.
@@ -652,7 +652,7 @@ public class CameraCaptureSessionImpl extends CameraCaptureSession {
private class AbortDrainListener implements TaskDrainer.DrainListener {
@Override
public void onDrained() {
- if (VERBOSE) Log.v(TAG, mIdString + "onAbortDrained");
+ if (DEBUG) Log.v(TAG, mIdString + "onAbortDrained");
synchronized (CameraCaptureSessionImpl.this) {
/*
* Any queued aborts have now completed.
@@ -676,7 +676,7 @@ public class CameraCaptureSessionImpl extends CameraCaptureSession {
private class IdleDrainListener implements TaskDrainer.DrainListener {
@Override
public void onDrained() {
- if (VERBOSE) Log.v(TAG, mIdString + "onIdleDrained");
+ if (DEBUG) Log.v(TAG, mIdString + "onIdleDrained");
// Take device lock before session lock so that we can call back into device
// without causing a deadlock
@@ -690,7 +690,7 @@ public class CameraCaptureSessionImpl extends CameraCaptureSession {
*
* This operation is idempotent; a session will not be closed twice.
*/
- if (VERBOSE)
+ if (DEBUG)
Log.v(TAG, mIdString + "Session drain complete, skip unconfigure: " +
mSkipUnconfigure);
@@ -712,7 +712,7 @@ public class CameraCaptureSessionImpl extends CameraCaptureSession {
// TODO: call onError instead of onClosed if this happens
} catch (IllegalStateException e) {
// Camera is already closed, so nothing left to do
- if (VERBOSE) Log.v(TAG, mIdString +
+ if (DEBUG) Log.v(TAG, mIdString +
"Camera was already closed or busy, skipping unconfigure");
}
diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
index c4e8b15..e60e266 100644
--- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
@@ -58,7 +58,7 @@ import java.util.TreeMap;
*/
public class CameraDeviceImpl extends CameraDevice {
private final String TAG;
- private final boolean DEBUG;
+ private final boolean DEBUG = false;
private static final int REQUEST_ID_NONE = -1;
@@ -240,7 +240,6 @@ public class CameraDeviceImpl extends CameraDevice {
tag = tag.substring(0, MAX_TAG_LEN);
}
TAG = tag;
- DEBUG = Log.isLoggable(TAG, Log.DEBUG);
Integer partialCount =
mCharacteristics.get(CameraCharacteristics.REQUEST_PARTIAL_RESULT_COUNT);
diff --git a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
index b8b7d12..10dd8ae 100644
--- a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
+++ b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
@@ -222,7 +222,8 @@ public class CameraMetadataNative implements Parcelable {
}
private static final String TAG = "CameraMetadataJV";
- private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
+ private static final boolean DEBUG = false;
+
// this should be in sync with HAL_PIXEL_FORMAT_BLOB defined in graphics.h
public static final int NATIVE_JPEG_FORMAT = 0x21;
@@ -1197,7 +1198,7 @@ public class CameraMetadataNative implements Parcelable {
@SuppressWarnings({ "unchecked", "rawtypes" })
private static void registerAllMarshalers() {
- if (VERBOSE) {
+ if (DEBUG) {
Log.v(TAG, "Shall register metadata marshalers");
}
@@ -1234,7 +1235,7 @@ public class CameraMetadataNative implements Parcelable {
for (MarshalQueryable query : queryList) {
MarshalRegistry.registerMarshalQueryable(query);
}
- if (VERBOSE) {
+ if (DEBUG) {
Log.v(TAG, "Registered metadata marshalers");
}
}
diff --git a/core/java/android/hardware/camera2/legacy/CameraDeviceState.java b/core/java/android/hardware/camera2/legacy/CameraDeviceState.java
index 89e2d98..2c2ad1c 100644
--- a/core/java/android/hardware/camera2/legacy/CameraDeviceState.java
+++ b/core/java/android/hardware/camera2/legacy/CameraDeviceState.java
@@ -41,7 +41,7 @@ import android.util.Log;
*/
public class CameraDeviceState {
private static final String TAG = "CameraDeviceState";
- private static final boolean DEBUG = Log.isLoggable(LegacyCameraDevice.DEBUG_PROP, Log.DEBUG);
+ private static final boolean DEBUG = false;
private static final int STATE_ERROR = 0;
private static final int STATE_UNCONFIGURED = 1;
diff --git a/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java b/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java
index edad00f..bc0a3a8 100644
--- a/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java
+++ b/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java
@@ -61,7 +61,7 @@ import java.util.List;
public class CameraDeviceUserShim implements ICameraDeviceUser {
private static final String TAG = "CameraDeviceUserShim";
- private static final boolean DEBUG = Log.isLoggable(LegacyCameraDevice.DEBUG_PROP, Log.DEBUG);
+ private static final boolean DEBUG = false;
private static final int OPEN_CAMERA_TIMEOUT_MS = 5000; // 5 sec (same as api1 cts timeout)
private final LegacyCameraDevice mLegacyDevice;
diff --git a/core/java/android/hardware/camera2/legacy/CaptureCollector.java b/core/java/android/hardware/camera2/legacy/CaptureCollector.java
index 8404e86..eb48a01 100644
--- a/core/java/android/hardware/camera2/legacy/CaptureCollector.java
+++ b/core/java/android/hardware/camera2/legacy/CaptureCollector.java
@@ -34,7 +34,7 @@ import java.util.concurrent.locks.ReentrantLock;
public class CaptureCollector {
private static final String TAG = "CaptureCollector";
- private static final boolean DEBUG = Log.isLoggable(LegacyCameraDevice.DEBUG_PROP, Log.DEBUG);
+ private static final boolean DEBUG = false;
private static final int FLAG_RECEIVED_JPEG = 1;
private static final int FLAG_RECEIVED_JPEG_TS = 2;
diff --git a/core/java/android/hardware/camera2/legacy/GLThreadManager.java b/core/java/android/hardware/camera2/legacy/GLThreadManager.java
index b160d2a..152d82d 100644
--- a/core/java/android/hardware/camera2/legacy/GLThreadManager.java
+++ b/core/java/android/hardware/camera2/legacy/GLThreadManager.java
@@ -35,7 +35,7 @@ import static com.android.internal.util.Preconditions.*;
*/
public class GLThreadManager {
private final String TAG;
- private static final boolean DEBUG = Log.isLoggable(LegacyCameraDevice.DEBUG_PROP, Log.DEBUG);
+ private static final boolean DEBUG = false;
private static final int MSG_NEW_CONFIGURATION = 1;
private static final int MSG_NEW_FRAME = 2;
diff --git a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
index b5a019d..098c2d8 100644
--- a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
+++ b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
@@ -59,10 +59,9 @@ import static com.android.internal.util.Preconditions.*;
* </p>
*/
public class LegacyCameraDevice implements AutoCloseable {
- public static final String DEBUG_PROP = "HAL1ShimLogging";
private final String TAG;
- private static final boolean DEBUG = Log.isLoggable(LegacyCameraDevice.DEBUG_PROP, Log.DEBUG);
+ private static final boolean DEBUG = false;
private final int mCameraId;
private final CameraCharacteristics mStaticCharacteristics;
private final ICameraDeviceCallbacks mDeviceCallbacks;
diff --git a/core/java/android/hardware/camera2/legacy/LegacyFaceDetectMapper.java b/core/java/android/hardware/camera2/legacy/LegacyFaceDetectMapper.java
index e576beb..882a7f4 100644
--- a/core/java/android/hardware/camera2/legacy/LegacyFaceDetectMapper.java
+++ b/core/java/android/hardware/camera2/legacy/LegacyFaceDetectMapper.java
@@ -44,7 +44,7 @@ import static com.android.internal.util.Preconditions.*;
@SuppressWarnings("deprecation")
public class LegacyFaceDetectMapper {
private static String TAG = "LegacyFaceDetectMapper";
- private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
+ private static final boolean DEBUG = false;
private final Camera mCamera;
/** Is the camera capable of face detection? */
@@ -97,7 +97,7 @@ public class LegacyFaceDetectMapper {
}
}
- if (VERBOSE) {
+ if (DEBUG) {
Log.v(TAG, "onFaceDetection - read " + lengthFaces + " faces");
}
}
@@ -170,13 +170,13 @@ public class LegacyFaceDetectMapper {
if (enableFaceDetect) {
mCamera.startFaceDetection();
- if (VERBOSE) {
+ if (DEBUG) {
Log.v(TAG, "processFaceDetectMode - start face detection");
}
} else {
mCamera.stopFaceDetection();
- if (VERBOSE) {
+ if (DEBUG) {
Log.v(TAG, "processFaceDetectMode - stop face detection");
}
@@ -248,7 +248,7 @@ public class LegacyFaceDetectMapper {
}
}
- if (VERBOSE && previousFaces != faces) { // Log only in verbose and IF the faces changed
+ if (DEBUG && previousFaces != faces) { // Log only in verbose and IF the faces changed
Log.v(TAG, "mapResultFaces - changed to " + ListUtils.listToString(convertedFaces));
}
diff --git a/core/java/android/hardware/camera2/legacy/LegacyFocusStateMapper.java b/core/java/android/hardware/camera2/legacy/LegacyFocusStateMapper.java
index d5ec71a..d33c09e 100644
--- a/core/java/android/hardware/camera2/legacy/LegacyFocusStateMapper.java
+++ b/core/java/android/hardware/camera2/legacy/LegacyFocusStateMapper.java
@@ -38,7 +38,7 @@ import static com.android.internal.util.Preconditions.*;
@SuppressWarnings("deprecation")
public class LegacyFocusStateMapper {
private static String TAG = "LegacyFocusStateMapper";
- private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
+ private static final boolean DEBUG = false;
private final Camera mCamera;
@@ -90,7 +90,7 @@ public class LegacyFocusStateMapper {
final String afMode = parameters.getFocusMode();
if (!Objects.equals(mAfModePrevious, afMode)) {
- if (VERBOSE) {
+ if (DEBUG) {
Log.v(TAG, "processRequestTriggers - AF mode switched from " + mAfModePrevious +
" to " + afMode);
}
@@ -120,7 +120,7 @@ public class LegacyFocusStateMapper {
synchronized (mLock) {
int latestAfRun = mAfRun;
- if (VERBOSE) {
+ if (DEBUG) {
Log.v(TAG,
"onAutoFocusMoving - start " + start + " latest AF run " +
latestAfRun + ", last AF run " + currentAfRun
@@ -192,7 +192,7 @@ public class LegacyFocusStateMapper {
mAfState = afStateAfterStart;
}
- if (VERBOSE) {
+ if (DEBUG) {
Log.v(TAG, "processRequestTriggers - got AF_TRIGGER_START, " +
"new AF run is " + currentAfRun);
}
@@ -208,7 +208,7 @@ public class LegacyFocusStateMapper {
synchronized (mLock) {
int latestAfRun = mAfRun;
- if (VERBOSE) {
+ if (DEBUG) {
Log.v(TAG, "onAutoFocus - success " + success + " latest AF run " +
latestAfRun + ", last AF run " + currentAfRun);
}
@@ -255,7 +255,7 @@ public class LegacyFocusStateMapper {
mCamera.cancelAutoFocus();
- if (VERBOSE) {
+ if (DEBUG) {
Log.v(TAG, "processRequestTriggers - got AF_TRIGGER_CANCEL, " +
"new AF run is " + updatedAfRun);
}
@@ -288,7 +288,7 @@ public class LegacyFocusStateMapper {
newAfState = mAfState;
}
- if (VERBOSE && newAfState != mAfStatePrevious) {
+ if (DEBUG && newAfState != mAfStatePrevious) {
Log.v(TAG, String.format("mapResultTriggers - afState changed from %s to %s",
afStateToString(mAfStatePrevious), afStateToString(newAfState)));
}
diff --git a/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java b/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java
index 8776418..33a802b 100644
--- a/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java
+++ b/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java
@@ -55,7 +55,7 @@ import static android.hardware.camera2.legacy.ParameterUtils.*;
@SuppressWarnings("deprecation")
public class LegacyMetadataMapper {
private static final String TAG = "LegacyMetadataMapper";
- private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
+ private static final boolean DEBUG = false;
private static final long NS_PER_MS = 1000000;
@@ -152,7 +152,7 @@ public class LegacyMetadataMapper {
params.unflatten(parameters);
mapCharacteristicsFromParameters(m, params);
- if (VERBOSE) {
+ if (DEBUG) {
Log.v(TAG, "createCharacteristics metadata:");
Log.v(TAG, "--------------------------------------------------- (start)");
m.dumpToLog();
@@ -284,7 +284,7 @@ public class LegacyMetadataMapper {
Camera.Size maxJpegSize = SizeAreaComparator.findLargestByArea(jpegSizes);
float jpegAspectRatio = maxJpegSize.width * 1.0f / maxJpegSize.height;
- if (VERBOSE) {
+ if (DEBUG) {
Log.v(TAG, String.format("mapScalerStreamConfigs - largest JPEG area %dx%d, AR=%f",
maxJpegSize.width, maxJpegSize.height, jpegAspectRatio));
}
@@ -300,7 +300,7 @@ public class LegacyMetadataMapper {
PREVIEW_ASPECT_RATIO_TOLERANCE) {
previewSizes.remove(index); // Assume removing from end is O(1)
- if (VERBOSE) {
+ if (DEBUG) {
Log.v(TAG, String.format(
"mapScalerStreamConfigs - removed preview size %dx%d, AR=%f "
+ "was not the same",
@@ -329,7 +329,7 @@ public class LegacyMetadataMapper {
for (int format : p.getSupportedPreviewFormats()) {
if (ImageFormat.isPublicFormat(format) && format != ImageFormat.NV21) {
appendStreamConfig(availableStreamConfigs, format, previewSizes);
- } else if (VERBOSE) {
+ } else if (DEBUG) {
/*
* Do not add any formats unknown to us
* (since it would fail runtime checks in StreamConfigurationMap)
@@ -388,7 +388,7 @@ public class LegacyMetadataMapper {
int j = 0;
for (String mode : antiBandingModes) {
int convertedMode = convertAntiBandingMode(mode);
- if (VERBOSE && convertedMode == -1) {
+ if (DEBUG && convertedMode == -1) {
Log.v(TAG, "Antibanding mode " + ((mode == null) ? "NULL" : mode) +
" not supported, skipping...");
} else {
@@ -525,7 +525,7 @@ public class LegacyMetadataMapper {
m.set(CONTROL_AF_AVAILABLE_MODES, ArrayUtils.toIntArray(afAvail));
- if (VERBOSE) {
+ if (DEBUG) {
Log.v(TAG, "mapControlAf - control.afAvailableModes set to " +
ListUtils.listToString(afAvail));
}
@@ -575,7 +575,7 @@ public class LegacyMetadataMapper {
m.set(CONTROL_AWB_AVAILABLE_MODES, ArrayUtils.toIntArray(awbAvail));
- if (VERBOSE) {
+ if (DEBUG) {
Log.v(TAG, "mapControlAwb - control.awbAvailableModes set to " +
ListUtils.listToString(awbAvail));
}
@@ -681,7 +681,7 @@ public class LegacyMetadataMapper {
* We can tell if the lens is fixed focus;
* but if it's not, we can't tell the minimum focus distance, so leave it null then.
*/
- if (VERBOSE) {
+ if (DEBUG) {
Log.v(TAG, "mapLens - focus-mode='" + p.getFocusMode() + "'");
}
@@ -691,11 +691,11 @@ public class LegacyMetadataMapper {
*/
m.set(LENS_INFO_MINIMUM_FOCUS_DISTANCE, LENS_INFO_MINIMUM_FOCUS_DISTANCE_FIXED_FOCUS);
- if (VERBOSE) {
+ if (DEBUG) {
Log.v(TAG, "mapLens - lens.info.minimumFocusDistance = 0");
}
} else {
- if (VERBOSE) {
+ if (DEBUG) {
Log.v(TAG, "mapLens - lens.info.minimumFocusDistance is unknown");
}
}
@@ -752,11 +752,14 @@ public class LegacyMetadataMapper {
CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES ,
CameraCharacteristics.CONTROL_AE_COMPENSATION_RANGE ,
CameraCharacteristics.CONTROL_AE_COMPENSATION_STEP ,
+ CameraCharacteristics.CONTROL_AE_LOCK_AVAILABLE ,
CameraCharacteristics.CONTROL_AF_AVAILABLE_MODES ,
CameraCharacteristics.CONTROL_AVAILABLE_EFFECTS ,
+ CameraCharacteristics.CONTROL_AVAILABLE_MODES ,
CameraCharacteristics.CONTROL_AVAILABLE_SCENE_MODES ,
CameraCharacteristics.CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES ,
CameraCharacteristics.CONTROL_AWB_AVAILABLE_MODES ,
+ CameraCharacteristics.CONTROL_AWB_LOCK_AVAILABLE ,
CameraCharacteristics.CONTROL_MAX_REGIONS ,
CameraCharacteristics.FLASH_INFO_AVAILABLE ,
CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL ,
@@ -1339,7 +1342,7 @@ public class LegacyMetadataMapper {
}
}
- if (VERBOSE) {
+ if (DEBUG) {
Log.v(TAG, "createRequestTemplate (templateId=" + templateId + ")," +
" afMode=" + afMode + ", minimumFocusDistance=" + minimumFocusDistance);
}
diff --git a/core/java/android/hardware/camera2/legacy/LegacyRequestMapper.java b/core/java/android/hardware/camera2/legacy/LegacyRequestMapper.java
index 3688610..d5d7f0d 100644
--- a/core/java/android/hardware/camera2/legacy/LegacyRequestMapper.java
+++ b/core/java/android/hardware/camera2/legacy/LegacyRequestMapper.java
@@ -42,7 +42,7 @@ import static android.hardware.camera2.CaptureRequest.*;
@SuppressWarnings("deprecation")
public class LegacyRequestMapper {
private static final String TAG = "LegacyRequestMapper";
- private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
+ private static final boolean DEBUG = false;
/** Default quality for android.jpeg.quality, android.jpeg.thumbnailQuality */
private static final byte DEFAULT_JPEG_QUALITY = 85;
@@ -75,7 +75,7 @@ public class LegacyRequestMapper {
if (params.isZoomSupported()) {
params.setZoom(zoomData.zoomIndex);
- } else if (VERBOSE) {
+ } else if (DEBUG) {
Log.v(TAG, "convertRequestToMetadata - zoom is not supported");
}
}
@@ -210,7 +210,7 @@ public class LegacyRequestMapper {
params.setAutoExposureLock(aeLock);
}
- if (VERBOSE) {
+ if (DEBUG) {
Log.v(TAG, "convertRequestToMetadata - control.aeLock set to " + aeLock);
}
@@ -231,7 +231,7 @@ public class LegacyRequestMapper {
params.setFocusMode(focusMode);
}
- if (VERBOSE) {
+ if (DEBUG) {
Log.v(TAG, "convertRequestToMetadata - control.afMode "
+ afMode + " mapped to " + focusMode);
}
@@ -250,7 +250,7 @@ public class LegacyRequestMapper {
params.setWhiteBalance(whiteBalanceMode);
}
- if (VERBOSE) {
+ if (DEBUG) {
Log.v(TAG, "convertRequestToMetadata - control.awbMode "
+ awbMode + " mapped to " + whiteBalanceMode);
}
@@ -520,7 +520,7 @@ public class LegacyRequestMapper {
" regions, ignoring all beyond the first " + maxNumMeteringAreas);
}
- if (VERBOSE) {
+ if (DEBUG) {
Log.v(TAG, "convertMeteringRegionsToLegacy - " + regionName + " areas = "
+ ParameterUtils.stringFromAreaList(meteringAreaList));
}
@@ -593,7 +593,7 @@ public class LegacyRequestMapper {
p.setFlashMode(flashModeSetting);
}
- if (VERBOSE) {
+ if (DEBUG) {
Log.v(TAG,
"mapAeAndFlashMode - set flash.mode (api1) to " + flashModeSetting
+ ", requested (api2) " + flashMode
diff --git a/core/java/android/hardware/camera2/legacy/LegacyResultMapper.java b/core/java/android/hardware/camera2/legacy/LegacyResultMapper.java
index bad1d28..ce85005 100644
--- a/core/java/android/hardware/camera2/legacy/LegacyResultMapper.java
+++ b/core/java/android/hardware/camera2/legacy/LegacyResultMapper.java
@@ -42,7 +42,7 @@ import static android.hardware.camera2.CaptureResult.*;
@SuppressWarnings("deprecation")
public class LegacyResultMapper {
private static final String TAG = "LegacyResultMapper";
- private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
+ private static final boolean DEBUG = false;
private LegacyRequest mCachedRequest = null;
private CameraMetadataNative mCachedResult = null;
@@ -88,7 +88,7 @@ public class LegacyResultMapper {
result.set(SENSOR_TIMESTAMP, timestamp);
}
- if (VERBOSE) {
+ if (DEBUG) {
Log.v(TAG, "cachedConvertResultMetadata - cached? " + cached +
" timestamp = " + timestamp);
@@ -306,7 +306,7 @@ public class LegacyResultMapper {
{
boolean lock = p.isAutoExposureLockSupported() ? p.getAutoExposureLock() : false;
m.set(CONTROL_AE_LOCK, lock);
- if (VERBOSE) {
+ if (DEBUG) {
Log.v(TAG,
"mapAe - android.control.aeLock = " + lock +
", supported = " + p.isAutoExposureLockSupported());
@@ -332,7 +332,7 @@ public class LegacyResultMapper {
// control.aeRegions
if (p.getMaxNumMeteringAreas() > 0) {
- if (VERBOSE) {
+ if (DEBUG) {
String meteringAreas = p.get("metering-areas");
Log.v(TAG, "mapAe - parameter dump; metering-areas: " + meteringAreas);
}
@@ -352,7 +352,7 @@ public class LegacyResultMapper {
// control.afRegions
if (p.getMaxNumFocusAreas() > 0) {
- if (VERBOSE) {
+ if (DEBUG) {
String focusAreas = p.get("focus-areas");
Log.v(TAG, "mapAe - parameter dump; focus-areas: " + focusAreas);
}
@@ -392,7 +392,7 @@ public class LegacyResultMapper {
}
}
- if (VERBOSE) {
+ if (DEBUG) {
Log.v(TAG,
"Metering rectangles for " + regionName + ": "
+ ListUtils.listToString(meteringRectList));
diff --git a/core/java/android/hardware/camera2/legacy/ParameterUtils.java b/core/java/android/hardware/camera2/legacy/ParameterUtils.java
index 32bbc51..3cfd020 100644
--- a/core/java/android/hardware/camera2/legacy/ParameterUtils.java
+++ b/core/java/android/hardware/camera2/legacy/ParameterUtils.java
@@ -225,7 +225,7 @@ public class ParameterUtils {
}
private static final String TAG = "ParameterUtils";
- private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
+ private static final boolean DEBUG = false;
/** getZoomRatios stores zoom ratios in 1/100 increments, e.x. a zoom of 3.2 is 320 */
private static final int ZOOM_RATIO_MULTIPLIER = 100;
@@ -398,7 +398,7 @@ public class ParameterUtils {
Rect cropRegionAsPreview =
shrinkToSameAspectRatioCentered(previewCrop, actualCrop);
- if (VERBOSE) {
+ if (DEBUG) {
Log.v(TAG, "getClosestAvailableZoomCrop - actualCrop = " + actualCrop);
Log.v(TAG,
"getClosestAvailableZoomCrop - previewCrop = " + previewCrop);
@@ -418,7 +418,7 @@ public class ParameterUtils {
List<Rect> availablePreviewCropRegions =
getAvailablePreviewZoomCropRectangles(params, activeArray, streamSize);
- if (VERBOSE) {
+ if (DEBUG) {
Log.v(TAG,
"getClosestAvailableZoomCrop - availableReportedCropRegions = " +
ListUtils.listToString(availableReportedCropRegions));
@@ -758,7 +758,7 @@ public class ParameterUtils {
userCropRegion = activeArraySizeOnly;
}
- if (VERBOSE) {
+ if (DEBUG) {
Log.v(TAG, "convertScalerCropRegion - user crop region was " + userCropRegion);
}
@@ -768,7 +768,7 @@ public class ParameterUtils {
previewSize, userCropRegion,
/*out*/reportedCropRegion, /*out*/previewCropRegion);
- if (VERBOSE) {
+ if (DEBUG) {
Log.v(TAG, "convertScalerCropRegion - zoom calculated to: " +
"zoomIndex = " + zoomIdx +
", reported crop region = " + reportedCropRegion +
@@ -862,7 +862,7 @@ public class ParameterUtils {
reportedMetering = reportedMeteringRect.rect;
}
- if (VERBOSE) {
+ if (DEBUG) {
Log.v(TAG, String.format(
"convertMeteringRectangleToLegacy - activeArray = %s, meteringRect = %s, " +
"previewCrop = %s, meteringArea = %s, previewMetering = %s, " +
diff --git a/core/java/android/hardware/camera2/legacy/RequestThreadManager.java b/core/java/android/hardware/camera2/legacy/RequestThreadManager.java
index 691798f..5ea1ab8 100644
--- a/core/java/android/hardware/camera2/legacy/RequestThreadManager.java
+++ b/core/java/android/hardware/camera2/legacy/RequestThreadManager.java
@@ -62,10 +62,9 @@ public class RequestThreadManager {
private final int mCameraId;
private final RequestHandlerThread mRequestThread;
- private static final boolean DEBUG = Log.isLoggable(LegacyCameraDevice.DEBUG_PROP, Log.DEBUG);
+ private static final boolean DEBUG = false;
// For slightly more spammy messages that will get repeated every frame
- private static final boolean VERBOSE =
- Log.isLoggable(LegacyCameraDevice.DEBUG_PROP, Log.VERBOSE);
+ private static final boolean VERBOSE = false;
private Camera mCamera;
private final CameraCharacteristics mCharacteristics;
diff --git a/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java b/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java
index 615b2c8..f928a55 100644
--- a/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java
+++ b/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java
@@ -49,7 +49,7 @@ import java.util.List;
*/
public class SurfaceTextureRenderer {
private static final String TAG = SurfaceTextureRenderer.class.getSimpleName();
- private static final boolean DEBUG = Log.isLoggable(LegacyCameraDevice.DEBUG_PROP, Log.DEBUG);
+ private static final boolean DEBUG = false;
private static final int EGL_RECORDABLE_ANDROID = 0x3142; // from EGL/eglext.h
private static final int GL_MATRIX_SIZE = 16;
private static final int VERTEX_POS_SIZE = 3;
diff --git a/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableArray.java b/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableArray.java
index d89518b..ebc74f0 100644
--- a/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableArray.java
+++ b/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableArray.java
@@ -39,7 +39,7 @@ import java.util.ArrayList;
public class MarshalQueryableArray<T> implements MarshalQueryable<T> {
private static final String TAG = MarshalQueryableArray.class.getSimpleName();
- private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
+ private static final boolean DEBUG = false;
private class MarshalerArray extends Marshaler<T> {
private final Class<T> mClass;
@@ -81,7 +81,7 @@ public class MarshalQueryableArray<T> implements MarshalQueryable<T> {
+ "; but there are " + (remaining % elementSize) + " left over bytes");
}
- if (VERBOSE) {
+ if (DEBUG) {
Log.v(TAG, String.format(
"Attempting to unpack array (count = %d, element size = %d, bytes "
+ "remaining = %d) for type %s",
diff --git a/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableEnum.java b/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableEnum.java
index fa53db2..621a418 100644
--- a/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableEnum.java
+++ b/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableEnum.java
@@ -38,7 +38,7 @@ import static android.hardware.camera2.marshal.MarshalHelpers.*;
public class MarshalQueryableEnum<T extends Enum<T>> implements MarshalQueryable<T> {
private static final String TAG = MarshalQueryableEnum.class.getSimpleName();
- private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
+ private static final boolean DEBUG = false;
private static final int UINT8_MIN = 0x0;
private static final int UINT8_MAX = (1 << Byte.SIZE) - 1;
@@ -110,7 +110,7 @@ public class MarshalQueryableEnum<T extends Enum<T>> implements MarshalQueryable
Class<?> typeClass = (Class<?>)managedType.getType();
if (typeClass.isEnum()) {
- if (VERBOSE) {
+ if (DEBUG) {
Log.v(TAG, "possible enum detected for " + typeClass);
}
@@ -151,7 +151,7 @@ public class MarshalQueryableEnum<T extends Enum<T>> implements MarshalQueryable
"Expected values array to be the same size as the enumTypes values "
+ values.length + " for type " + enumType);
}
- if (VERBOSE) {
+ if (DEBUG) {
Log.v(TAG, "Registered enum values for type " + enumType + " values");
}
diff --git a/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableParcelable.java b/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableParcelable.java
index 0b7a4bf..fdde205 100644
--- a/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableParcelable.java
+++ b/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableParcelable.java
@@ -34,7 +34,7 @@ public class MarshalQueryableParcelable<T extends Parcelable>
implements MarshalQueryable<T> {
private static final String TAG = "MarshalParcelable";
- private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
+ private static final boolean DEBUG = false;
private static final String FIELD_CREATOR = "CREATOR";
@@ -70,7 +70,7 @@ public class MarshalQueryableParcelable<T extends Parcelable>
@Override
public void marshal(T value, ByteBuffer buffer) {
- if (VERBOSE) {
+ if (DEBUG) {
Log.v(TAG, "marshal " + value);
}
@@ -100,7 +100,7 @@ public class MarshalQueryableParcelable<T extends Parcelable>
@Override
public T unmarshal(ByteBuffer buffer) {
- if (VERBOSE) {
+ if (DEBUG) {
Log.v(TAG, "unmarshal, buffer remaining " + buffer.remaining());
}
@@ -142,7 +142,7 @@ public class MarshalQueryableParcelable<T extends Parcelable>
buffer.reset();
buffer.position(buffer.position() + actualLength);
- if (VERBOSE) {
+ if (DEBUG) {
Log.v(TAG, "unmarshal, parcel length was " + actualLength);
Log.v(TAG, "unmarshal, value is " + value);
}
@@ -165,7 +165,7 @@ public class MarshalQueryableParcelable<T extends Parcelable>
value.writeToParcel(parcel, /*flags*/0);
int length = parcel.marshall().length;
- if (VERBOSE) {
+ if (DEBUG) {
Log.v(TAG, "calculateMarshalSize, length when parceling "
+ value + " is " + length);
}
diff --git a/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableString.java b/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableString.java
index bf518bb..d2c3908 100644
--- a/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableString.java
+++ b/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableString.java
@@ -31,7 +31,7 @@ import static android.hardware.camera2.impl.CameraMetadataNative.*;
public class MarshalQueryableString implements MarshalQueryable<String> {
private static final String TAG = MarshalQueryableString.class.getSimpleName();
- private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
+ private static final boolean DEBUG = false;
private static final Charset UTF8_CHARSET = Charset.forName("UTF-8");
private static final byte NUL = (byte)'\0'; // used as string terminator
@@ -72,7 +72,7 @@ public class MarshalQueryableString implements MarshalQueryable<String> {
stringLength++;
}
- if (VERBOSE) {
+ if (DEBUG) {
Log.v(TAG,
"unmarshal - scanned " + stringLength + " characters; found null? "
+ foundNull);
diff --git a/core/java/android/hardware/camera2/utils/ArrayUtils.java b/core/java/android/hardware/camera2/utils/ArrayUtils.java
index 79a335c..99ddf6e 100644
--- a/core/java/android/hardware/camera2/utils/ArrayUtils.java
+++ b/core/java/android/hardware/camera2/utils/ArrayUtils.java
@@ -28,7 +28,7 @@ import java.util.Objects;
public class ArrayUtils {
private static final String TAG = "ArrayUtils";
- private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
+ private static final boolean DEBUG = false;
/** Return the index of {@code needle} in the {@code array}, or else {@code -1} */
public static <T> int getArrayIndex(T[] array, T needle) {
@@ -117,7 +117,7 @@ public class ArrayUtils {
// Guard against unexpected values
if (strIndex < 0) {
- if (VERBOSE) Log.v(TAG, "Ignoring invalid value " + str);
+ if (DEBUG) Log.v(TAG, "Ignoring invalid value " + str);
continue;
}
diff --git a/core/java/android/hardware/camera2/utils/TaskDrainer.java b/core/java/android/hardware/camera2/utils/TaskDrainer.java
index dc09f62..7c46e50 100644
--- a/core/java/android/hardware/camera2/utils/TaskDrainer.java
+++ b/core/java/android/hardware/camera2/utils/TaskDrainer.java
@@ -52,7 +52,7 @@ public class TaskDrainer<T> {
}
private static final String TAG = "TaskDrainer";
- private final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
+ private final boolean DEBUG = false;
private final Handler mHandler;
private final DrainListener mListener;
@@ -110,7 +110,7 @@ public class TaskDrainer<T> {
*/
public void taskStarted(T task) {
synchronized (mLock) {
- if (VERBOSE) {
+ if (DEBUG) {
Log.v(TAG + "[" + mName + "]", "taskStarted " + task);
}
@@ -141,7 +141,7 @@ public class TaskDrainer<T> {
*/
public void taskFinished(T task) {
synchronized (mLock) {
- if (VERBOSE) {
+ if (DEBUG) {
Log.v(TAG + "[" + mName + "]", "taskFinished " + task);
}
@@ -163,7 +163,7 @@ public class TaskDrainer<T> {
public void beginDrain() {
synchronized (mLock) {
if (!mDraining) {
- if (VERBOSE) {
+ if (DEBUG) {
Log.v(TAG + "[" + mName + "]", "beginDrain started");
}
@@ -172,7 +172,7 @@ public class TaskDrainer<T> {
// If all tasks that had started had already finished by now, fire #onDrained
checkIfDrainFinished();
} else {
- if (VERBOSE) {
+ if (DEBUG) {
Log.v(TAG + "[" + mName + "]", "beginDrain ignored");
}
}
@@ -190,7 +190,7 @@ public class TaskDrainer<T> {
mHandler.post(new Runnable() {
@Override
public void run() {
- if (VERBOSE) {
+ if (DEBUG) {
Log.v(TAG + "[" + mName + "]", "onDrained");
}
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 1b57055..81a65f8 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -306,6 +306,14 @@ public class InputMethodService extends AbstractInputMethodService {
int mStatusIcon;
int mBackDisposition;
+ /**
+ * {@code true} when the previous IME had non-empty inset at the bottom of the screen and we
+ * have not shown our own window yet. In this situation, the previous inset continues to be
+ * shown as an empty region until it is explicitly updated. Basically we can trigger the update
+ * by calling 1) {@code mWindow.show()} or 2) {@link #clearInsetOfPreviousIme()}.
+ */
+ boolean mShouldClearInsetOfPreviousIme;
+
final Insets mTmpInsets = new Insets();
final int[] mTmpLocation = new int[2];
@@ -408,6 +416,7 @@ public class InputMethodService extends AbstractInputMethodService {
mShowInputRequested = false;
mShowInputForced = false;
doHideWindow();
+ clearInsetOfPreviousIme();
if (resultReceiver != null) {
resultReceiver.send(wasVis != isInputViewShown()
? InputMethodManager.RESULT_HIDDEN
@@ -432,6 +441,7 @@ public class InputMethodService extends AbstractInputMethodService {
mWindowAdded = false;
}
}
+ clearInsetOfPreviousIme();
// If user uses hard keyboard, IME button should always be shown.
boolean showing = isInputViewShown();
mImm.setImeWindowStatus(mToken, IME_ACTIVE | (showing ? IME_VISIBLE : 0),
@@ -669,6 +679,9 @@ public class InputMethodService extends AbstractInputMethodService {
super.setTheme(mTheme);
super.onCreate();
mImm = (InputMethodManager)getSystemService(INPUT_METHOD_SERVICE);
+ // If the previous IME has occupied non-empty inset in the screen, we need to decide whether
+ // we continue to use the same size of the inset or update it
+ mShouldClearInsetOfPreviousIme = (mImm.getInputMethodWindowVisibleHeight() > 0);
mInflater = (LayoutInflater)getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
mWindow = new SoftInputWindow(this, "InputMethod", mTheme, null, null, mDispatcherState,
@@ -1494,6 +1507,9 @@ public class InputMethodService extends AbstractInputMethodService {
if (DEBUG) Log.v(TAG, "showWindow: showing!");
onWindowShown();
mWindow.show();
+ // Put here rather than in onWindowShown() in case people forget to call
+ // super.onWindowShown().
+ mShouldClearInsetOfPreviousIme = false;
}
}
@@ -1540,7 +1556,23 @@ public class InputMethodService extends AbstractInputMethodService {
public void onWindowHidden() {
// Intentionally empty
}
-
+
+ /**
+ * Reset the inset occupied the previous IME when and only when
+ * {@link #mShouldClearInsetOfPreviousIme} is {@code true}.
+ */
+ private void clearInsetOfPreviousIme() {
+ if (DEBUG) Log.v(TAG, "clearInsetOfPreviousIme() "
+ + " mShouldClearInsetOfPreviousIme=" + mShouldClearInsetOfPreviousIme);
+ if (!mShouldClearInsetOfPreviousIme || mWindow == null) return;
+ // We do not call onWindowShown() and onWindowHidden() so as not to make the IME author
+ // confused.
+ // TODO: Find out a better way which has less side-effect.
+ mWindow.show();
+ mWindow.hide();
+ mShouldClearInsetOfPreviousIme = false;
+ }
+
/**
* Called when a new client has bound to the input method. This
* may be followed by a series of {@link #onStartInput(EditorInfo, boolean)}
@@ -2428,5 +2460,6 @@ public class InputMethodService extends AbstractInputMethodService {
+ " visibleTopInsets=" + mTmpInsets.visibleTopInsets
+ " touchableInsets=" + mTmpInsets.touchableInsets
+ " touchableRegion=" + mTmpInsets.touchableRegion);
+ p.println(" mShouldClearInsetOfPreviousIme=" + mShouldClearInsetOfPreviousIme);
}
}
diff --git a/core/java/android/net/IpReachabilityMonitor.java b/core/java/android/net/IpReachabilityMonitor.java
index 78d147d..3cfd8b2 100644
--- a/core/java/android/net/IpReachabilityMonitor.java
+++ b/core/java/android/net/IpReachabilityMonitor.java
@@ -443,14 +443,13 @@ public class IpReachabilityMonitor {
if (mIpWatchList.containsKey(destination)) {
final short value =
(msgType == NetlinkConstants.RTM_DELNEIGH)
- ? StructNdMsg.NUD_FAILED
+ ? StructNdMsg.NUD_NONE
: nudState;
mIpWatchList.put(destination, value);
}
}
- if ((msgType == NetlinkConstants.RTM_DELNEIGH) ||
- (nudState == StructNdMsg.NUD_FAILED)) {
+ if (nudState == StructNdMsg.NUD_FAILED) {
Log.w(TAG, "ALERT: " + eventMsg);
handleNeighborLost(eventMsg);
}
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 5f515eb..0a45b8b 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -132,6 +132,16 @@ public abstract class BatteryStats implements Parcelable {
public static final int AUDIO_TURNED_ON = 15;
/**
+ * A constant indicating a flashlight turn on timer
+ */
+ public static final int FLASHLIGHT_TURNED_ON = 16;
+
+ /**
+ * A constant indicating a camera turn on timer
+ */
+ public static final int CAMERA_TURNED_ON = 17;
+
+ /**
* Include all of the data in the stats, including previously saved data.
*/
public static final int STATS_SINCE_CHARGED = 0;
@@ -208,6 +218,10 @@ public abstract class BatteryStats implements Parcelable {
private static final String CHARGE_STEP_DATA = "csd";
private static final String DISCHARGE_TIME_REMAIN_DATA = "dtr";
private static final String CHARGE_TIME_REMAIN_DATA = "ctr";
+ private static final String FLASHLIGHT_DATA = "fla";
+ private static final String CAMERA_DATA = "cam";
+ private static final String VIDEO_DATA = "vid";
+ private static final String AUDIO_DATA = "aud";
private final StringBuilder mFormatBuilder = new StringBuilder(32);
private final Formatter mFormatter = new Formatter(mFormatBuilder);
@@ -381,8 +395,10 @@ public abstract class BatteryStats implements Parcelable {
public abstract long getWifiBatchedScanTime(int csphBin, long elapsedRealtimeUs, int which);
public abstract int getWifiBatchedScanCount(int csphBin, int which);
public abstract long getWifiMulticastTime(long elapsedRealtimeUs, int which);
- public abstract long getAudioTurnedOnTime(long elapsedRealtimeUs, int which);
- public abstract long getVideoTurnedOnTime(long elapsedRealtimeUs, int which);
+ public abstract Timer getAudioTurnedOnTimer();
+ public abstract Timer getVideoTurnedOnTimer();
+ public abstract Timer getFlashlightTurnedOnTimer();
+ public abstract Timer getCameraTurnedOnTimer();
public abstract Timer getForegroundActivityTimer();
// Time this uid has any processes in foreground state.
@@ -1106,6 +1122,7 @@ public abstract class BatteryStats implements Parcelable {
public static final int STATE2_CHARGING_FLAG = 1<<25;
public static final int STATE2_PHONE_IN_CALL_FLAG = 1<<24;
public static final int STATE2_BLUETOOTH_ON_FLAG = 1<<23;
+ public static final int STATE2_CAMERA_FLAG = 1<<22;
public static final int MOST_INTERESTING_STATES2 =
STATE2_POWER_SAVE_FLAG | STATE2_WIFI_ON_FLAG | STATE2_DEVICE_IDLE_FLAG
@@ -1813,6 +1830,7 @@ public abstract class BatteryStats implements Parcelable {
new BitDescription(HistoryItem.STATE2_WIFI_SUPPL_STATE_MASK,
HistoryItem.STATE2_WIFI_SUPPL_STATE_SHIFT, "wifi_suppl", "Wsp",
WIFI_SUPPL_STATE_NAMES, WIFI_SUPPL_STATE_SHORT_NAMES),
+ new BitDescription(HistoryItem.STATE2_CAMERA_FLAG, "camera", "ca"),
};
public static final String[] HISTORY_EVENT_NAMES = new String[] {
@@ -2317,10 +2335,10 @@ public abstract class BatteryStats implements Parcelable {
*/
private static final String printWakeLock(StringBuilder sb, Timer timer,
long elapsedRealtimeUs, String name, int which, String linePrefix) {
-
+
if (timer != null) {
long totalTimeMillis = computeWakeLock(timer, elapsedRealtimeUs, which);
-
+
int count = timer.getCountLocked(which);
if (totalTimeMillis != 0) {
sb.append(linePrefix);
@@ -2337,6 +2355,40 @@ public abstract class BatteryStats implements Parcelable {
}
return linePrefix;
}
+
+ /**
+ *
+ * @param pw a PrintWriter object to print to.
+ * @param sb a StringBuilder object.
+ * @param timer a Timer object contining the wakelock times.
+ * @param rawRealtime the current on-battery time in microseconds.
+ * @param which which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
+ * @param prefix a String to be prepended to each line of output.
+ * @param type the name of the timer.
+ */
+ private static final boolean printTimer(PrintWriter pw, StringBuilder sb, Timer timer,
+ long rawRealtime, int which, String prefix, String type) {
+ if (timer != null) {
+ // Convert from microseconds to milliseconds with rounding
+ final long totalTime = (timer.getTotalTimeLocked(
+ rawRealtime, which) + 500) / 1000;
+ final int count = timer.getCountLocked(which);
+ if (totalTime != 0) {
+ sb.setLength(0);
+ sb.append(prefix);
+ sb.append(" ");
+ sb.append(type);
+ sb.append(": ");
+ formatTimeMs(sb, totalTime);
+ sb.append("realtime (");
+ sb.append(count);
+ sb.append(" times)");
+ pw.println(sb.toString());
+ return true;
+ }
+ }
+ return false;
+ }
/**
* Checkin version of wakelock printer. Prints simple comma-separated list.
@@ -2375,12 +2427,15 @@ public abstract class BatteryStats implements Parcelable {
*/
private static final void dumpLine(PrintWriter pw, int uid, String category, String type,
Object... args ) {
- pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
- pw.print(uid); pw.print(',');
- pw.print(category); pw.print(',');
+ pw.print(BATTERY_STATS_CHECKIN_VERSION);
+ pw.print(',');
+ pw.print(uid);
+ pw.print(',');
+ pw.print(category);
+ pw.print(',');
pw.print(type);
-
- for (Object arg : args) {
+
+ for (Object arg : args) {
pw.print(',');
pw.print(arg);
}
@@ -2388,6 +2443,30 @@ public abstract class BatteryStats implements Parcelable {
}
/**
+ * Dump a given timer stat for terse checkin mode.
+ *
+ * @param pw the PageWriter to dump log to
+ * @param uid the UID to log
+ * @param category category of data (e.g. "total", "last", "unplugged", "current" )
+ * @param type type of data (e.g. "wakelock", "sensor", "process", "apk" , "process", "network")
+ * @param timer a {@link Timer} to dump stats for
+ * @param rawRealtime the current elapsed realtime of the system in microseconds
+ * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT
+ */
+ private static final void dumpTimer(PrintWriter pw, int uid, String category, String type,
+ Timer timer, long rawRealtime, int which) {
+ if (timer != null) {
+ // Convert from microseconds to milliseconds with rounding
+ final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500)
+ / 1000;
+ final int count = timer.getCountLocked(which);
+ if (totalTime != 0) {
+ dumpLine(pw, uid, category, type, totalTime, count);
+ }
+ }
+ }
+
+ /**
* Temporary for settings.
*/
public final void dumpCheckinLocked(Context context, PrintWriter pw, int which, int reqUid) {
@@ -2764,6 +2843,15 @@ public abstract class BatteryStats implements Parcelable {
}
}
+ dumpTimer(pw, uid, category, FLASHLIGHT_DATA, u.getFlashlightTurnedOnTimer(),
+ rawRealtime, which);
+ dumpTimer(pw, uid, category, CAMERA_DATA, u.getCameraTurnedOnTimer(),
+ rawRealtime, which);
+ dumpTimer(pw, uid, category, VIDEO_DATA, u.getVideoTurnedOnTimer(),
+ rawRealtime, which);
+ dumpTimer(pw, uid, category, AUDIO_DATA, u.getAudioTurnedOnTimer(),
+ rawRealtime, which);
+
final SparseArray<? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
final int NSE = sensors.size();
for (int ise=0; ise<NSE; ise++) {
@@ -2781,27 +2869,11 @@ public abstract class BatteryStats implements Parcelable {
}
}
- final Timer vibTimer = u.getVibratorOnTimer();
- if (vibTimer != null) {
- // Convert from microseconds to milliseconds with rounding
- final long totalTime = (vibTimer.getTotalTimeLocked(rawRealtime, which) + 500)
- / 1000;
- final int count = vibTimer.getCountLocked(which);
- if (totalTime != 0) {
- dumpLine(pw, uid, category, VIBRATOR_DATA, totalTime, count);
- }
- }
+ dumpTimer(pw, uid, category, VIBRATOR_DATA, u.getVibratorOnTimer(),
+ rawRealtime, which);
- final Timer fgTimer = u.getForegroundActivityTimer();
- if (fgTimer != null) {
- // Convert from microseconds to milliseconds with rounding
- final long totalTime = (fgTimer.getTotalTimeLocked(rawRealtime, which) + 500)
- / 1000;
- final int count = fgTimer.getCountLocked(which);
- if (totalTime != 0) {
- dumpLine(pw, uid, category, FOREGROUND_DATA, totalTime, count);
- }
- }
+ dumpTimer(pw, uid, category, FOREGROUND_DATA, u.getForegroundActivityTimer(),
+ rawRealtime, which);
final Object[] stateTimes = new Object[Uid.NUM_PROCESS_STATE];
long totalStateTime = 0;
@@ -3282,12 +3354,13 @@ public abstract class BatteryStats implements Parcelable {
final long wifiIdleTimeMs = getWifiControllerActivity(CONTROLLER_IDLE_TIME, which);
final long wifiRxTimeMs = getWifiControllerActivity(CONTROLLER_RX_TIME, which);
final long wifiTxTimeMs = getWifiControllerActivity(CONTROLLER_TX_TIME, which);
+ final long wifiPowerDrainMaMs = getWifiControllerActivity(CONTROLLER_POWER_DRAIN, which);
final long wifiTotalTimeMs = wifiIdleTimeMs + wifiRxTimeMs + wifiTxTimeMs;
sb.setLength(0);
sb.append(prefix);
sb.append(" WiFi Idle time: "); formatTimeMs(sb, wifiIdleTimeMs);
- sb.append(" (");
+ sb.append("(");
sb.append(formatRatioLocked(wifiIdleTimeMs, wifiTotalTimeMs));
sb.append(")");
pw.println(sb.toString());
@@ -3295,7 +3368,7 @@ public abstract class BatteryStats implements Parcelable {
sb.setLength(0);
sb.append(prefix);
sb.append(" WiFi Rx time: "); formatTimeMs(sb, wifiRxTimeMs);
- sb.append(" (");
+ sb.append("(");
sb.append(formatRatioLocked(wifiRxTimeMs, wifiTotalTimeMs));
sb.append(")");
pw.println(sb.toString());
@@ -3303,16 +3376,16 @@ public abstract class BatteryStats implements Parcelable {
sb.setLength(0);
sb.append(prefix);
sb.append(" WiFi Tx time: "); formatTimeMs(sb, wifiTxTimeMs);
- sb.append(" (");
+ sb.append("(");
sb.append(formatRatioLocked(wifiTxTimeMs, wifiTotalTimeMs));
sb.append(")");
pw.println(sb.toString());
sb.setLength(0);
sb.append(prefix);
- sb.append(" WiFi Power drain: ").append(BatteryStatsHelper.makemAh(
- getWifiControllerActivity(CONTROLLER_POWER_DRAIN, which) / (double)(1000*60*60)));
- sb.append(" mAh");
+ sb.append(" WiFi Power drain: ").append(
+ BatteryStatsHelper.makemAh(wifiPowerDrainMaMs / (double) (1000*60*60)));
+ sb.append("mAh");
pw.println(sb.toString());
final long bluetoothIdleTimeMs =
@@ -3325,7 +3398,7 @@ public abstract class BatteryStats implements Parcelable {
sb.setLength(0);
sb.append(prefix);
sb.append(" Bluetooth Idle time: "); formatTimeMs(sb, bluetoothIdleTimeMs);
- sb.append(" (");
+ sb.append("(");
sb.append(formatRatioLocked(bluetoothIdleTimeMs, bluetoothTotalTimeMs));
sb.append(")");
pw.println(sb.toString());
@@ -3333,7 +3406,7 @@ public abstract class BatteryStats implements Parcelable {
sb.setLength(0);
sb.append(prefix);
sb.append(" Bluetooth Rx time: "); formatTimeMs(sb, bluetoothRxTimeMs);
- sb.append(" (");
+ sb.append("(");
sb.append(formatRatioLocked(bluetoothRxTimeMs, bluetoothTotalTimeMs));
sb.append(")");
pw.println(sb.toString());
@@ -3341,7 +3414,7 @@ public abstract class BatteryStats implements Parcelable {
sb.setLength(0);
sb.append(prefix);
sb.append(" Bluetooth Tx time: "); formatTimeMs(sb, bluetoothTxTimeMs);
- sb.append(" (");
+ sb.append("(");
sb.append(formatRatioLocked(bluetoothTxTimeMs, bluetoothTotalTimeMs));
sb.append(")");
pw.println(sb.toString());
@@ -3351,7 +3424,7 @@ public abstract class BatteryStats implements Parcelable {
sb.append(" Bluetooth Power drain: ").append(BatteryStatsHelper.makemAh(
getBluetoothControllerActivity(CONTROLLER_POWER_DRAIN, which) /
(double)(1000*60*60)));
- sb.append(" mAh");
+ sb.append("mAh");
pw.println(sb.toString());
pw.println();
@@ -3656,6 +3729,27 @@ public abstract class BatteryStats implements Parcelable {
pw.println(sb.toString());
}
+ final long uidWifiIdleTimeMs = u.getWifiControllerActivity(CONTROLLER_IDLE_TIME, which);
+ final long uidWifiRxTimeMs = u.getWifiControllerActivity(CONTROLLER_RX_TIME, which);
+ final long uidWifiTxTimeMs = u.getWifiControllerActivity(CONTROLLER_TX_TIME, which);
+ final long uidWifiTotalTimeMs = uidWifiIdleTimeMs + uidWifiRxTimeMs + uidWifiTxTimeMs;
+ if (uidWifiTotalTimeMs > 0) {
+ sb.setLength(0);
+ sb.append(prefix).append(" WiFi Idle time: ");
+ formatTimeMs(sb, uidWifiIdleTimeMs);
+ sb.append("(").append(formatRatioLocked(uidWifiIdleTimeMs, uidWifiTotalTimeMs))
+ .append(")\n");
+
+ sb.append(prefix).append(" WiFi Rx time: "); formatTimeMs(sb, uidWifiRxTimeMs);
+ sb.append("(").append(formatRatioLocked(uidWifiRxTimeMs, uidWifiTotalTimeMs))
+ .append(")\n");
+
+ sb.append(prefix).append(" WiFi Tx time: "); formatTimeMs(sb, uidWifiTxTimeMs);
+ sb.append("(").append(formatRatioLocked(uidWifiTxTimeMs, uidWifiTotalTimeMs))
+ .append(")");
+ pw.println(sb.toString());
+ }
+
if (u.hasUserActivity()) {
boolean hasData = false;
for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
@@ -3788,6 +3882,15 @@ public abstract class BatteryStats implements Parcelable {
uidActivity = true;
}
+ uidActivity |= printTimer(pw, sb, u.getFlashlightTurnedOnTimer(), rawRealtime, which,
+ prefix, "Flashlight");
+ uidActivity |= printTimer(pw, sb, u.getCameraTurnedOnTimer(), rawRealtime, which,
+ prefix, "Camera");
+ uidActivity |= printTimer(pw, sb, u.getVideoTurnedOnTimer(), rawRealtime, which,
+ prefix, "Video");
+ uidActivity |= printTimer(pw, sb, u.getAudioTurnedOnTimer(), rawRealtime, which,
+ prefix, "Audio");
+
final SparseArray<? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
final int NSE = sensors.size();
for (int ise=0; ise<NSE; ise++) {
@@ -3827,44 +3930,10 @@ public abstract class BatteryStats implements Parcelable {
uidActivity = true;
}
- final Timer vibTimer = u.getVibratorOnTimer();
- if (vibTimer != null) {
- // Convert from microseconds to milliseconds with rounding
- final long totalTime = (vibTimer.getTotalTimeLocked(
- rawRealtime, which) + 500) / 1000;
- final int count = vibTimer.getCountLocked(which);
- //timer.logState();
- if (totalTime != 0) {
- sb.setLength(0);
- sb.append(prefix);
- sb.append(" Vibrator: ");
- formatTimeMs(sb, totalTime);
- sb.append("realtime (");
- sb.append(count);
- sb.append(" times)");
- pw.println(sb.toString());
- uidActivity = true;
- }
- }
-
- final Timer fgTimer = u.getForegroundActivityTimer();
- if (fgTimer != null) {
- // Convert from microseconds to milliseconds with rounding
- final long totalTime = (fgTimer.getTotalTimeLocked(rawRealtime, which) + 500)
- / 1000;
- final int count = fgTimer.getCountLocked(which);
- if (totalTime != 0) {
- sb.setLength(0);
- sb.append(prefix);
- sb.append(" Foreground activities: ");
- formatTimeMs(sb, totalTime);
- sb.append("realtime (");
- sb.append(count);
- sb.append(" times)");
- pw.println(sb.toString());
- uidActivity = true;
- }
- }
+ uidActivity |= printTimer(pw, sb, u.getVibratorOnTimer(), rawRealtime, which, prefix,
+ "Vibrator");
+ uidActivity |= printTimer(pw, sb, u.getForegroundActivityTimer(), rawRealtime, which,
+ prefix, "Foreground activities");
long totalStateTime = 0;
for (int ips=0; ips<Uid.NUM_PROCESS_STATE; ips++) {
diff --git a/core/java/android/os/IDeviceIdleController.aidl b/core/java/android/os/IDeviceIdleController.aidl
index 602bfea..268295d 100644
--- a/core/java/android/os/IDeviceIdleController.aidl
+++ b/core/java/android/os/IDeviceIdleController.aidl
@@ -16,6 +16,8 @@
package android.os;
+import android.os.UserHandle;
+
/** @hide */
interface IDeviceIdleController {
void addPowerSaveWhitelistApp(String name);
@@ -23,5 +25,7 @@ interface IDeviceIdleController {
String[] getSystemPowerWhitelist();
String[] getFullPowerWhitelist();
int[] getAppIdWhitelist();
+ int[] getAppIdTempWhitelist();
boolean isPowerSaveWhitelistApp(String name);
+ void addPowerSaveTempWhitelistApp(String name, long duration, int userId);
}
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 1d9d7d2..8b18f32 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -928,6 +928,14 @@ public final class PowerManager {
= "android.os.action.POWER_SAVE_WHITELIST_CHANGED";
/**
+ * @hide Intent that is broadcast when the set of temporarily whitelisted apps has changed.
+ * This broadcast is only sent to registered receivers.
+ */
+ @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_POWER_SAVE_TEMP_WHITELIST_CHANGED
+ = "android.os.action.POWER_SAVE_TEMP_WHITELIST_CHANGED";
+
+ /**
* Intent that is broadcast when the state of {@link #isPowerSaveMode()} is about to change.
* This broadcast is only sent to registered receivers.
*
diff --git a/core/java/android/os/PowerManagerInternal.java b/core/java/android/os/PowerManagerInternal.java
index e523285..e742f98 100644
--- a/core/java/android/os/PowerManagerInternal.java
+++ b/core/java/android/os/PowerManagerInternal.java
@@ -137,6 +137,8 @@ public abstract class PowerManagerInternal {
public abstract void setDeviceIdleWhitelist(int[] appids);
+ public abstract void setDeviceIdleTempWhitelist(int[] appids);
+
public abstract void updateUidProcState(int uid, int procState);
public abstract void uidGone(int uid);
diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java
index 4aeab49..0c79094 100644
--- a/core/java/android/os/RecoverySystem.java
+++ b/core/java/android/os/RecoverySystem.java
@@ -71,6 +71,7 @@ public class RecoverySystem {
/** Used to communicate with recovery. See bootable/recovery/recovery.c. */
private static File RECOVERY_DIR = new File("/cache/recovery");
private static File COMMAND_FILE = new File(RECOVERY_DIR, "command");
+ private static File UNCRYPT_FILE = new File(RECOVERY_DIR, "uncrypt_file");
private static File LOG_FILE = new File(RECOVERY_DIR, "log");
private static String LAST_PREFIX = "last_";
@@ -333,8 +334,21 @@ public class RecoverySystem {
public static void installPackage(Context context, File packageFile)
throws IOException {
String filename = packageFile.getCanonicalPath();
+
+ FileWriter uncryptFile = new FileWriter(UNCRYPT_FILE);
+ try {
+ uncryptFile.write(filename + "\n");
+ } finally {
+ uncryptFile.close();
+ }
Log.w(TAG, "!!! REBOOTING TO INSTALL " + filename + " !!!");
+ // If the package is on the /data partition, write the block map file
+ // into COMMAND_FILE instead.
+ if (filename.startsWith("/data/")) {
+ filename = "@/cache/recovery/block.map";
+ }
+
final String filenameArg = "--update_package=" + filename;
final String localeArg = "--locale=" + Locale.getDefault().toString();
bootCommand(context, filenameArg, localeArg);
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index a81b83f..ef7e747 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -200,6 +200,20 @@ public class UserManager {
public static final String DISALLOW_CONFIG_TETHERING = "no_config_tethering";
/**
+ * Specifies if a user is disallowed from resetting network settings
+ * from Settings. This can only be set by device owners and profile owners on the primary user.
+ * The default value is <code>false</code>.
+ * <p/>This restriction has no effect on secondary users and managed profiles since only the
+ * primary user can reset the network settings of the device.
+ *
+ * <p/>Key for user restrictions.
+ * <p/>Type: Boolean
+ * @see #setUserRestrictions(Bundle)
+ * @see #getUserRestrictions()
+ */
+ public static final String DISALLOW_NETWORK_RESET = "no_network_reset";
+
+ /**
* Specifies if a user is disallowed from factory resetting
* from Settings. This can only be set by device owners and profile owners on the primary user.
* The default value is <code>false</code>.
diff --git a/core/java/android/provider/VoicemailContract.java b/core/java/android/provider/VoicemailContract.java
index c6ea50a..e1b5a6d 100644
--- a/core/java/android/provider/VoicemailContract.java
+++ b/core/java/android/provider/VoicemailContract.java
@@ -19,6 +19,7 @@ package android.provider;
import android.Manifest;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
+import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
@@ -27,6 +28,7 @@ import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.provider.CallLog.Calls;
+import android.telecom.PhoneAccount;
import android.telecom.PhoneAccountHandle;
import android.telecom.Voicemail;
@@ -211,13 +213,17 @@ public class VoicemailContract {
// that was encoded into call log databases.
/**
- * The component name of the account in string form.
+ * The {@link ComponentName} of the {@link PhoneAccount} in string form. The
+ * {@link PhoneAccount} of the voicemail is used to differentiate voicemails from different
+ * sources.
* <P>Type: TEXT</P>
*/
public static final String PHONE_ACCOUNT_COMPONENT_NAME = "subscription_component_name";
/**
- * The identifier of a account that is unique to a specified component.
+ * The identifier of a {@link PhoneAccount} that is unique to a specified
+ * {@link ComponentName}. The {@link PhoneAccount} of the voicemail is used to differentiate
+ * voicemails from different sources.
* <P>Type: TEXT</P>
*/
public static final String PHONE_ACCOUNT_ID = "subscription_id";
@@ -340,13 +346,15 @@ public class VoicemailContract {
// PHONE_ACCOUNT_* fields.
/**
- * The component name of the account in string form.
+ * The {@link ComponentName} of the {@link PhoneAccount} in string form. The
+ * {@link PhoneAccount} differentiates voicemail sources from the same package.
* <P>Type: TEXT</P>
*/
public static final String PHONE_ACCOUNT_COMPONENT_NAME = "phone_account_component_name";
/**
- * The identifier of a account that is unique to a specified component.
+ * The identifier of a {@link PhoneAccount} that is unique to a specified component. The
+ * {@link PhoneAccount} differentiates voicemail sources from the same package.
* <P>Type: TEXT</P>
*/
public static final String PHONE_ACCOUNT_ID = "phone_account_id";
diff --git a/core/java/android/service/carrier/CarrierConfigService.java b/core/java/android/service/carrier/CarrierService.java
index bf33ad5..15ccc25 100644
--- a/core/java/android/service/carrier/CarrierConfigService.java
+++ b/core/java/android/service/carrier/CarrierService.java
@@ -20,31 +20,35 @@ import android.os.IBinder;
import android.os.PersistableBundle;
/**
- * A service that sets carrier configuration for telephony services.
+ * A service that exposes carrier-specific functionality to the system.
* <p>
* To extend this class, you must declare the service in your manifest file to require the
* {@link android.Manifest.permission#BIND_CARRIER_SERVICES} permission and include an intent
- * filter with the {@link #SERVICE_INTERFACE} action. For example:
+ * filter with the {@link #CONFIG_SERVICE_INTERFACE} action if the service exposes carrier config
+ * and the {@link #BIND_SERVICE_INTERFACE} action if the service should have a long-lived binding.
+ * For example:
* </p>
*
* <pre>{@code
- * <service android:name=".MyCarrierConfigService"
+ * <service android:name=".MyCarrierService"
* android:label="@string/service_name"
* android:permission="android.permission.BIND_CARRIER_SERVICES">
* <intent-filter>
- * <action android:name="android.service.carrier.CarrierConfigService" />
+ * <action android:name="android.service.carrier.ConfigService" />
+ * <action android:name="android.service.carrier.BindService" />
* </intent-filter>
* </service>
* }</pre>
*/
-public abstract class CarrierConfigService extends Service {
+public abstract class CarrierService extends Service {
- public static final String SERVICE_INTERFACE = "android.service.carrier.CarrierConfigService";
+ public static final String CONFIG_SERVICE_INTERFACE = "android.service.carrier.ConfigService";
+ public static final String BIND_SERVICE_INTERFACE = "android.service.carrier.BindService";
- private final ICarrierConfigService.Stub mStubWrapper;
+ private final ICarrierService.Stub mStubWrapper;
- public CarrierConfigService() {
- mStubWrapper = new ICarrierConfigServiceWrapper();
+ public CarrierService() {
+ mStubWrapper = new ICarrierServiceWrapper();
}
/**
@@ -82,23 +86,24 @@ public abstract class CarrierConfigService extends Service {
/** @hide */
@Override
public final IBinder onBind(Intent intent) {
- if (!SERVICE_INTERFACE.equals(intent.getAction())) {
+ if (!CONFIG_SERVICE_INTERFACE.equals(intent.getAction())
+ || !BIND_SERVICE_INTERFACE.equals(intent.getAction())) {
return null;
}
return mStubWrapper;
}
/**
- * A wrapper around ICarrierConfigService that forwards calls to implementations of
- * {@link CarrierConfigService}.
+ * A wrapper around ICarrierService that forwards calls to implementations of
+ * {@link CarrierService}.
*
* @hide
*/
- private class ICarrierConfigServiceWrapper extends ICarrierConfigService.Stub {
+ private class ICarrierServiceWrapper extends ICarrierService.Stub {
@Override
public PersistableBundle getCarrierConfig(CarrierIdentifier id) {
- return CarrierConfigService.this.onLoadConfig(id);
+ return CarrierService.this.onLoadConfig(id);
}
}
}
diff --git a/core/java/android/service/carrier/ICarrierConfigService.aidl b/core/java/android/service/carrier/ICarrierService.aidl
index abbc000..4c87585 100644
--- a/core/java/android/service/carrier/ICarrierConfigService.aidl
+++ b/core/java/android/service/carrier/ICarrierService.aidl
@@ -20,13 +20,13 @@ import android.os.PersistableBundle;
import android.service.carrier.CarrierIdentifier;
/**
- * Service used to get carrier config from carrier apps.
+ * Service used to expose carrier-specific functionality to the system.
*
- * @see android.service.carrier.CarrierConfigService
+ * @see android.service.carrier.CarrierService
* @hide
*/
-interface ICarrierConfigService {
+interface ICarrierService {
- /** @see android.service.carrier.CarrierConfigService#onLoadConfig */
+ /** @see android.service.carrier.CarrierService#onLoadConfig */
PersistableBundle getCarrierConfig(in CarrierIdentifier id);
}
diff --git a/core/java/android/service/gatekeeper/GateKeeperResponse.aidl b/core/java/android/service/gatekeeper/GateKeeperResponse.aidl
new file mode 100644
index 0000000..966606e
--- /dev/null
+++ b/core/java/android/service/gatekeeper/GateKeeperResponse.aidl
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.service.gatekeeper;
+
+/**
+ * Response object for a GateKeeper verification request.
+ * @hide
+ */
+parcelable GateKeeperResponse;
+
diff --git a/core/java/android/service/gatekeeper/GateKeeperResponse.java b/core/java/android/service/gatekeeper/GateKeeperResponse.java
new file mode 100644
index 0000000..a512957
--- /dev/null
+++ b/core/java/android/service/gatekeeper/GateKeeperResponse.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.service.gatekeeper;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Response object for a GateKeeper verification request.
+ * @hide
+ */
+public final class GateKeeperResponse implements Parcelable {
+
+ public static final int RESPONSE_ERROR = -1;
+ public static final int RESPONSE_OK = 0;
+ public static final int RESPONSE_RETRY = 1;
+
+ private final int mResponseCode;
+
+ private int mTimeout;
+ private byte[] mPayload;
+ private boolean mShouldReEnroll;
+
+ private GateKeeperResponse(int responseCode) {
+ mResponseCode = responseCode;
+ }
+
+ private GateKeeperResponse(int responseCode, int timeout) {
+ mResponseCode = responseCode;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ public static final Parcelable.Creator<GateKeeperResponse> CREATOR
+ = new Parcelable.Creator<GateKeeperResponse>() {
+ @Override
+ public GateKeeperResponse createFromParcel(Parcel source) {
+ int responseCode = source.readInt();
+ GateKeeperResponse response = new GateKeeperResponse(responseCode);
+ if (responseCode == RESPONSE_RETRY) {
+ response.setTimeout(source.readInt());
+ } else if (responseCode == RESPONSE_OK) {
+ response.setShouldReEnroll(source.readInt() == 1);
+ int size = source.readInt();
+ if (size > 0) {
+ byte[] payload = new byte[size];
+ source.readByteArray(payload);
+ response.setPayload(payload);
+ }
+ }
+ return response;
+ }
+
+ @Override
+ public GateKeeperResponse[] newArray(int size) {
+ return new GateKeeperResponse[size];
+ }
+
+ };
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mResponseCode);
+ if (mResponseCode == RESPONSE_RETRY) {
+ dest.writeInt(mTimeout);
+ } else if (mResponseCode == RESPONSE_OK) {
+ dest.writeInt(mShouldReEnroll ? 1 : 0);
+ if (mPayload != null) {
+ dest.writeInt(mPayload.length);
+ dest.writeByteArray(mPayload);
+ }
+ }
+ }
+
+ public byte[] getPayload() {
+ return mPayload;
+ }
+
+ public int getTimeout() {
+ return mTimeout;
+ }
+
+ public boolean getShouldReEnroll() {
+ return mShouldReEnroll;
+ }
+
+ public int getResponseCode() {
+ return mResponseCode;
+ }
+
+ private void setTimeout(int timeout) {
+ mTimeout = timeout;
+ }
+
+ private void setShouldReEnroll(boolean shouldReEnroll) {
+ mShouldReEnroll = shouldReEnroll;
+ }
+
+ private void setPayload(byte[] payload) {
+ mPayload = payload;
+ }
+
+}
diff --git a/core/java/android/service/gatekeeper/IGateKeeperService.aidl b/core/java/android/service/gatekeeper/IGateKeeperService.aidl
index 4f46701..6db2110 100644
--- a/core/java/android/service/gatekeeper/IGateKeeperService.aidl
+++ b/core/java/android/service/gatekeeper/IGateKeeperService.aidl
@@ -16,6 +16,8 @@
package android.service.gatekeeper;
+import android.service.gatekeeper.GateKeeperResponse;
+
/**
* Interface for communication with GateKeeper, the
* secure password storage daemon.
@@ -34,9 +36,9 @@ interface IGateKeeperService {
* If provided, must verify against the currentPasswordHandle.
* @param desiredPassword The new desired password, for which a handle will be returned
* upon success.
- * @return the handle corresponding to desiredPassword, or null
+ * @return an EnrollResponse or null on failure
*/
- byte[] enroll(int uid, in byte[] currentPasswordHandle, in byte[] currentPassword,
+ GateKeeperResponse enroll(int uid, in byte[] currentPasswordHandle, in byte[] currentPassword,
in byte[] desiredPassword);
/**
@@ -45,10 +47,10 @@ interface IGateKeeperService {
* @param enrolledPasswordHandle The handle against which the provided password will be
* verified.
* @param The plaintext blob to verify against enrolledPassword.
- * @return True if the authentication was successful
+ * @return a VerifyResponse, or null on failure.
*/
- boolean verify(int uid, in byte[] enrolledPasswordHandle,
- in byte[] providedPassword);
+ GateKeeperResponse verify(int uid, in byte[] enrolledPasswordHandle, in byte[] providedPassword);
+
/**
* Verifies an enrolled handle against a provided, plaintext blob.
* @param uid The Android user ID associated to this enrollment
@@ -58,9 +60,9 @@ interface IGateKeeperService {
* @param enrolledPasswordHandle The handle against which the provided password will be
* verified.
* @param The plaintext blob to verify against enrolledPassword.
- * @return an opaque attestation of authentication on success, or null.
+ * @return a VerifyResponse with an attestation, or null on failure.
*/
- byte[] verifyChallenge(int uid, long challenge, in byte[] enrolledPasswordHandle,
+ GateKeeperResponse verifyChallenge(int uid, long challenge, in byte[] enrolledPasswordHandle,
in byte[] providedPassword);
/**
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java
index dd3cedc..db19f7a 100644
--- a/core/java/android/service/notification/ZenModeConfig.java
+++ b/core/java/android/service/notification/ZenModeConfig.java
@@ -79,6 +79,7 @@ public class ZenModeConfig implements Parcelable {
private static final int XML_VERSION = 2;
private static final String ZEN_TAG = "zen";
private static final String ZEN_ATT_VERSION = "version";
+ private static final String ZEN_ATT_USER = "user";
private static final String ALLOW_TAG = "allow";
private static final String ALLOW_ATT_CALLS = "calls";
private static final String ALLOW_ATT_REPEAT_CALLERS = "repeatCallers";
@@ -117,6 +118,7 @@ public class ZenModeConfig implements Parcelable {
public boolean allowEvents = DEFAULT_ALLOW_EVENTS;
public int allowCallsFrom = DEFAULT_SOURCE;
public int allowMessagesFrom = DEFAULT_SOURCE;
+ public int user = UserHandle.USER_OWNER;
public ZenRule manualRule;
public ArrayMap<String, ZenRule> automaticRules = new ArrayMap<>();
@@ -131,6 +133,7 @@ public class ZenModeConfig implements Parcelable {
allowEvents = source.readInt() == 1;
allowCallsFrom = source.readInt();
allowMessagesFrom = source.readInt();
+ user = source.readInt();
manualRule = source.readParcelable(null);
final int len = source.readInt();
if (len > 0) {
@@ -153,6 +156,7 @@ public class ZenModeConfig implements Parcelable {
dest.writeInt(allowEvents ? 1 : 0);
dest.writeInt(allowCallsFrom);
dest.writeInt(allowMessagesFrom);
+ dest.writeInt(user);
dest.writeParcelable(manualRule, 0);
if (!automaticRules.isEmpty()) {
final int len = automaticRules.size();
@@ -173,7 +177,8 @@ public class ZenModeConfig implements Parcelable {
@Override
public String toString() {
return new StringBuilder(ZenModeConfig.class.getSimpleName()).append('[')
- .append("allowCalls=").append(allowCalls)
+ .append("user=").append(user)
+ .append(",allowCalls=").append(allowCalls)
.append(",allowRepeatCallers=").append(allowRepeatCallers)
.append(",allowMessages=").append(allowMessages)
.append(",allowCallsFrom=").append(sourceToString(allowCallsFrom))
@@ -185,6 +190,68 @@ public class ZenModeConfig implements Parcelable {
.append(']').toString();
}
+ private Diff diff(ZenModeConfig to) {
+ final Diff d = new Diff();
+ if (to == null) {
+ return d.addLine("config", "delete");
+ }
+ if (user != to.user) {
+ d.addLine("user", user, to.user);
+ }
+ if (allowCalls != to.allowCalls) {
+ d.addLine("allowCalls", allowCalls, to.allowCalls);
+ }
+ if (allowRepeatCallers != to.allowRepeatCallers) {
+ d.addLine("allowRepeatCallers", allowRepeatCallers, to.allowRepeatCallers);
+ }
+ if (allowMessages != to.allowMessages) {
+ d.addLine("allowMessages", allowMessages, to.allowMessages);
+ }
+ if (allowCallsFrom != to.allowCallsFrom) {
+ d.addLine("allowCallsFrom", allowCallsFrom, to.allowCallsFrom);
+ }
+ if (allowMessagesFrom != to.allowMessagesFrom) {
+ d.addLine("allowMessagesFrom", allowMessagesFrom, to.allowMessagesFrom);
+ }
+ if (allowReminders != to.allowReminders) {
+ d.addLine("allowReminders", allowReminders, to.allowReminders);
+ }
+ if (allowEvents != to.allowEvents) {
+ d.addLine("allowEvents", allowEvents, to.allowEvents);
+ }
+ final ArraySet<String> allRules = new ArraySet<>();
+ addKeys(allRules, automaticRules);
+ addKeys(allRules, to.automaticRules);
+ final int N = allRules.size();
+ for (int i = 0; i < N; i++) {
+ final String rule = allRules.valueAt(i);
+ final ZenRule fromRule = automaticRules != null ? automaticRules.get(rule) : null;
+ final ZenRule toRule = to.automaticRules != null ? to.automaticRules.get(rule) : null;
+ ZenRule.appendDiff(d, "automaticRule[" + rule + "]", fromRule, toRule);
+ }
+ ZenRule.appendDiff(d, "manualRule", manualRule, to.manualRule);
+ return d;
+ }
+
+ public static Diff diff(ZenModeConfig from, ZenModeConfig to) {
+ if (from == null) {
+ final Diff d = new Diff();
+ if (to != null) {
+ d.addLine("config", "insert");
+ }
+ return d;
+ }
+ return from.diff(to);
+ }
+
+ private static <T> void addKeys(ArraySet<T> set, ArrayMap<T, ?> map) {
+ if (map != null) {
+ for (int i = 0; i < map.size(); i++) {
+ set.add(map.keyAt(i));
+ }
+ }
+ }
+
public boolean isValid() {
if (!isValidManualRule(manualRule)) return false;
final int N = automaticRules.size();
@@ -249,6 +316,7 @@ public class ZenModeConfig implements Parcelable {
&& other.allowMessagesFrom == allowMessagesFrom
&& other.allowReminders == allowReminders
&& other.allowEvents == allowEvents
+ && other.user == user
&& Objects.equals(other.automaticRules, automaticRules)
&& Objects.equals(other.manualRule, manualRule);
}
@@ -256,7 +324,7 @@ public class ZenModeConfig implements Parcelable {
@Override
public int hashCode() {
return Objects.hash(allowCalls, allowRepeatCallers, allowMessages, allowCallsFrom,
- allowMessagesFrom, allowReminders, allowEvents, automaticRules, manualRule);
+ allowMessagesFrom, allowReminders, allowEvents, user, automaticRules, manualRule);
}
private static String toDayList(int[] days) {
@@ -312,6 +380,7 @@ public class ZenModeConfig implements Parcelable {
final XmlV1 v1 = XmlV1.readXml(parser);
return migration.migrate(v1);
}
+ rt.user = safeInt(parser, ZEN_ATT_USER, rt.user);
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
tag = parser.getName();
if (type == XmlPullParser.END_TAG && ZEN_TAG.equals(tag)) {
@@ -341,10 +410,10 @@ public class ZenModeConfig implements Parcelable {
rt.allowMessagesFrom = DEFAULT_SOURCE;
}
} else if (MANUAL_TAG.equals(tag)) {
- rt.manualRule = readRuleXml(parser, false /*conditionRequired*/);
+ rt.manualRule = readRuleXml(parser);
} else if (AUTOMATIC_TAG.equals(tag)) {
final String id = parser.getAttributeValue(null, RULE_ATT_ID);
- final ZenRule automaticRule = readRuleXml(parser, true /*conditionRequired*/);
+ final ZenRule automaticRule = readRuleXml(parser);
if (id != null && automaticRule != null) {
rt.automaticRules.put(id, automaticRule);
}
@@ -357,6 +426,7 @@ public class ZenModeConfig implements Parcelable {
public void writeXml(XmlSerializer out) throws IOException {
out.startTag(null, ZEN_TAG);
out.attribute(null, ZEN_ATT_VERSION, Integer.toString(XML_VERSION));
+ out.attribute(null, ZEN_ATT_USER, Integer.toString(user));
out.startTag(null, ALLOW_TAG);
out.attribute(null, ALLOW_ATT_CALLS, Boolean.toString(allowCalls));
@@ -385,7 +455,7 @@ public class ZenModeConfig implements Parcelable {
out.endTag(null, ZEN_TAG);
}
- public static ZenRule readRuleXml(XmlPullParser parser, boolean conditionRequired) {
+ public static ZenRule readRuleXml(XmlPullParser parser) {
final ZenRule rt = new ZenRule();
rt.enabled = safeBoolean(parser, RULE_ATT_ENABLED, true);
rt.snoozing = safeBoolean(parser, RULE_ATT_SNOOZING, false);
@@ -731,7 +801,7 @@ public class ZenModeConfig implements Parcelable {
.authority(SYSTEM_AUTHORITY)
.appendPath(EVENT_PATH)
.appendQueryParameter("userId", Long.toString(event.userId))
- .appendQueryParameter("calendar", Long.toString(event.calendar))
+ .appendQueryParameter("calendar", event.calendar != null ? event.calendar : "")
.appendQueryParameter("reply", Integer.toString(event.reply))
.build();
}
@@ -749,21 +819,21 @@ public class ZenModeConfig implements Parcelable {
if (!isEvent) return null;
final EventInfo rt = new EventInfo();
rt.userId = tryParseInt(conditionId.getQueryParameter("userId"), UserHandle.USER_NULL);
- rt.calendar = tryParseLong(conditionId.getQueryParameter("calendar"),
- EventInfo.ANY_CALENDAR);
+ rt.calendar = conditionId.getQueryParameter("calendar");
+ if (TextUtils.isEmpty(rt.calendar) || tryParseLong(rt.calendar, -1L) != -1L) {
+ rt.calendar = null;
+ }
rt.reply = tryParseInt(conditionId.getQueryParameter("reply"), 0);
return rt;
}
public static class EventInfo {
- public static final long ANY_CALENDAR = 0;
-
public static final int REPLY_ANY_EXCEPT_NO = 0;
public static final int REPLY_YES_OR_MAYBE = 1;
public static final int REPLY_YES = 2;
public int userId = UserHandle.USER_NULL; // USER_NULL = unspecified - use current user
- public long calendar = ANY_CALENDAR; // CalendarContract.Calendars._ID, or ANY_CALENDAR
+ public String calendar; // CalendarContract.Calendars.OWNER_ACCOUNT, or null for any
public int reply;
@Override
@@ -776,7 +846,7 @@ public class ZenModeConfig implements Parcelable {
if (!(o instanceof EventInfo)) return false;
final EventInfo other = (EventInfo) o;
return userId == other.userId
- && calendar == other.calendar
+ && Objects.equals(calendar, other.calendar)
&& reply == other.reply;
}
@@ -790,7 +860,6 @@ public class ZenModeConfig implements Parcelable {
public static int resolveUserId(int userId) {
return userId == UserHandle.USER_NULL ? ActivityManager.getCurrentUser() : userId;
-
}
}
@@ -915,6 +984,45 @@ public class ZenModeConfig implements Parcelable {
.append(']').toString();
}
+ private static void appendDiff(Diff d, String item, ZenRule from, ZenRule to) {
+ if (d == null) return;
+ if (from == null) {
+ if (to != null) {
+ d.addLine(item, "insert");
+ }
+ return;
+ }
+ from.appendDiff(d, item, to);
+ }
+
+ private void appendDiff(Diff d, String item, ZenRule to) {
+ if (to == null) {
+ d.addLine(item, "delete");
+ return;
+ }
+ if (enabled != to.enabled) {
+ d.addLine(item, "enabled", enabled, to.enabled);
+ }
+ if (snoozing != to.snoozing) {
+ d.addLine(item, "snoozing", snoozing, to.snoozing);
+ }
+ if (!Objects.equals(name, to.name)) {
+ d.addLine(item, "name", name, to.name);
+ }
+ if (zenMode != to.zenMode) {
+ d.addLine(item, "zenMode", zenMode, to.zenMode);
+ }
+ if (!Objects.equals(conditionId, to.conditionId)) {
+ d.addLine(item, "conditionId", conditionId, to.conditionId);
+ }
+ if (!Objects.equals(condition, to.condition)) {
+ d.addLine(item, "condition", condition, to.condition);
+ }
+ if (!Objects.equals(component, to.component)) {
+ d.addLine(item, "component", component, to.component);
+ }
+ }
+
@Override
public boolean equals(Object o) {
if (!(o instanceof ZenRule)) return false;
@@ -1073,4 +1181,34 @@ public class ZenModeConfig implements Parcelable {
ZenModeConfig migrate(XmlV1 v1);
}
+ public static class Diff {
+ private final ArrayList<String> lines = new ArrayList<>();
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder("Diff[");
+ final int N = lines.size();
+ for (int i = 0; i < N; i++) {
+ if (i > 0) {
+ sb.append(',');
+ }
+ sb.append(lines.get(i));
+ }
+ return sb.append(']').toString();
+ }
+
+ private Diff addLine(String item, String action) {
+ lines.add(item + ":" + action);
+ return this;
+ }
+
+ public Diff addLine(String item, String subitem, Object from, Object to) {
+ return addLine(item + "." + subitem, from, to);
+ }
+
+ public Diff addLine(String item, Object from, Object to) {
+ return addLine(item, from + "->" + to);
+ }
+ }
+
}
diff --git a/core/java/android/service/voice/IVoiceInteractionSession.aidl b/core/java/android/service/voice/IVoiceInteractionSession.aidl
index 7c90261..894edac 100644
--- a/core/java/android/service/voice/IVoiceInteractionSession.aidl
+++ b/core/java/android/service/voice/IVoiceInteractionSession.aidl
@@ -16,6 +16,8 @@
package android.service.voice;
+import android.app.AssistContent;
+import android.app.AssistStructure;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
@@ -28,7 +30,7 @@ import com.android.internal.app.IVoiceInteractionSessionShowCallback;
oneway interface IVoiceInteractionSession {
void show(in Bundle sessionArgs, int flags, IVoiceInteractionSessionShowCallback showCallback);
void hide();
- void handleAssist(in Bundle assistData);
+ void handleAssist(in Bundle assistData, in AssistStructure structure, in AssistContent content);
void handleScreenshot(in Bitmap screenshot);
void taskStarted(in Intent intent, int taskId);
void taskFinished(in Intent intent, int taskId);
diff --git a/core/java/android/service/voice/VoiceInteractionService.java b/core/java/android/service/voice/VoiceInteractionService.java
index 77e2125..8119049 100644
--- a/core/java/android/service/voice/VoiceInteractionService.java
+++ b/core/java/android/service/voice/VoiceInteractionService.java
@@ -70,25 +70,6 @@ public class VoiceInteractionService extends Service {
*/
public static final String SERVICE_META_DATA = "android.voice_interaction";
- /**
- * Flag for use with {@link #showSession}: request that the session be started with
- * assist data from the currently focused activity.
- */
- public static final int START_WITH_ASSIST = 1<<0;
-
- /**
- * @hide
- * Flag for use with {@link #showSession}: request that the session be started with
- * a screen shot of the currently focused activity.
- */
- public static final int START_WITH_SCREENSHOT = 1<<1;
-
- /**
- * Flag for use with {@link #showSession}: indicate that the session has been started from the
- * system assist gesture.
- */
- public static final int START_SOURCE_ASSIST_GESTURE = 1<<2;
-
IVoiceInteractionService mInterface = new IVoiceInteractionService.Stub() {
@Override public void ready() {
mHandler.sendEmptyMessage(MSG_READY);
@@ -176,6 +157,10 @@ public class VoiceInteractionService extends Service {
* Request that the associated {@link android.service.voice.VoiceInteractionSession} be
* shown to the user, starting it if necessary.
* @param args Arbitrary arguments that will be propagated to the session.
+ * @param flags Indicates additional optional behavior that should be performed. May
+ * be {@link VoiceInteractionSession#SHOW_WITH_ASSIST VoiceInteractionSession.SHOW_WITH_ASSIST}
+ * to request that the system generate and deliver assist data on the current foreground
+ * app as part of showing the session UI.
*/
public void showSession(Bundle args, int flags) {
if (mSystemService == null) {
diff --git a/core/java/android/service/voice/VoiceInteractionSession.java b/core/java/android/service/voice/VoiceInteractionSession.java
index f122d10..48ad5a8 100644
--- a/core/java/android/service/voice/VoiceInteractionSession.java
+++ b/core/java/android/service/voice/VoiceInteractionSession.java
@@ -16,6 +16,7 @@
package android.service.voice;
+import android.app.AssistContent;
import android.app.AssistStructure;
import android.app.Dialog;
import android.app.Instrumentation;
@@ -67,11 +68,29 @@ import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
* when done. It can also initiate voice interactions with applications by calling
* {@link #startVoiceActivity}</p>.
*/
-public abstract class VoiceInteractionSession implements KeyEvent.Callback,
- ComponentCallbacks2 {
+public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCallbacks2 {
static final String TAG = "VoiceInteractionSession";
static final boolean DEBUG = true;
+ /**
+ * Flag received in {@link #onShow}: originator requested that the session be started with
+ * assist data from the currently focused activity.
+ */
+ public static final int SHOW_WITH_ASSIST = 1<<0;
+
+ /**
+ * @hide
+ * Flag received in {@link #onShow}: originator requested that the session be started with
+ * a screen shot of the currently focused activity.
+ */
+ public static final int SHOW_WITH_SCREENSHOT = 1<<1;
+
+ /**
+ * Flag for use with {@link #onShow}: indicates that the session has been started from the
+ * system assist gesture.
+ */
+ public static final int SHOW_SOURCE_ASSIST_GESTURE = 1<<2;
+
final Context mContext;
final HandlerCaller mHandlerCaller;
@@ -104,10 +123,12 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback,
@Override
public IVoiceInteractorRequest startConfirmation(String callingPackage,
IVoiceInteractorCallback callback, CharSequence prompt, Bundle extras) {
- Request request = newRequest(callback);
- mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageOOOO(MSG_START_CONFIRMATION,
- new Caller(callingPackage, Binder.getCallingUid()), request,
- prompt, extras));
+ ConfirmationRequest request = new ConfirmationRequest(callingPackage,
+ Binder.getCallingUid(), callback, VoiceInteractionSession.this,
+ prompt, extras);
+ addRequest(request);
+ mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageO(MSG_START_CONFIRMATION,
+ request));
return request.mInterface;
}
@@ -115,47 +136,54 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback,
public IVoiceInteractorRequest startPickOption(String callingPackage,
IVoiceInteractorCallback callback, CharSequence prompt,
VoiceInteractor.PickOptionRequest.Option[] options, Bundle extras) {
- Request request = newRequest(callback);
- mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageOOOOO(MSG_START_PICK_OPTION,
- new Caller(callingPackage, Binder.getCallingUid()), request,
- prompt, options, extras));
+ PickOptionRequest request = new PickOptionRequest(callingPackage,
+ Binder.getCallingUid(), callback, VoiceInteractionSession.this,
+ prompt, options, extras);
+ addRequest(request);
+ mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageO(MSG_START_PICK_OPTION,
+ request));
return request.mInterface;
}
@Override
public IVoiceInteractorRequest startCompleteVoice(String callingPackage,
IVoiceInteractorCallback callback, CharSequence message, Bundle extras) {
- Request request = newRequest(callback);
- mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageOOOO(MSG_START_COMPLETE_VOICE,
- new Caller(callingPackage, Binder.getCallingUid()), request,
- message, extras));
+ CompleteVoiceRequest request = new CompleteVoiceRequest(callingPackage,
+ Binder.getCallingUid(), callback, VoiceInteractionSession.this,
+ message, extras);
+ addRequest(request);
+ mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageO(MSG_START_COMPLETE_VOICE,
+ request));
return request.mInterface;
}
@Override
public IVoiceInteractorRequest startAbortVoice(String callingPackage,
IVoiceInteractorCallback callback, CharSequence message, Bundle extras) {
- Request request = newRequest(callback);
- mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageOOOO(MSG_START_ABORT_VOICE,
- new Caller(callingPackage, Binder.getCallingUid()), request,
- message, extras));
+ AbortVoiceRequest request = new AbortVoiceRequest(callingPackage,
+ Binder.getCallingUid(), callback, VoiceInteractionSession.this,
+ message, extras);
+ addRequest(request);
+ mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageO(MSG_START_ABORT_VOICE,
+ request));
return request.mInterface;
}
@Override
public IVoiceInteractorRequest startCommand(String callingPackage,
IVoiceInteractorCallback callback, String command, Bundle extras) {
- Request request = newRequest(callback);
- mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageOOOO(MSG_START_COMMAND,
- new Caller(callingPackage, Binder.getCallingUid()), request,
- command, extras));
+ CommandRequest request = new CommandRequest(callingPackage,
+ Binder.getCallingUid(), callback, VoiceInteractionSession.this,
+ command, extras);
+ mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageO(MSG_START_COMMAND,
+ request));
return request.mInterface;
}
@Override
public boolean[] supportsCommands(String callingPackage, String[] commands) {
Message msg = mHandlerCaller.obtainMessageIOO(MSG_SUPPORTS_COMMANDS,
- 0, new Caller(callingPackage, Binder.getCallingUid()), commands);
+ 0, commands, null);
SomeArgs args = mHandlerCaller.sendMessageAndWait(msg);
if (args != null) {
boolean[] res = (boolean[])args.arg1;
@@ -180,21 +208,16 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback,
}
@Override
- public void handleAssist(Bundle assistBundle) {
+ public void handleAssist(Bundle data, AssistStructure structure,
+ AssistContent content) {
// We want to pre-warm the AssistStructure before handing it off to the main
// thread. There is a strong argument to be made that it should be handed
// through as a separate param rather than part of the assistBundle.
- if (assistBundle != null) {
- Bundle assistContext = assistBundle.getBundle(Intent.EXTRA_ASSIST_CONTEXT);
- if (assistContext != null) {
- AssistStructure as = AssistStructure.getAssistStructure(assistContext);
- if (as != null) {
- as.ensureData();
- }
- }
+ if (structure != null) {
+ structure.ensureData();
}
- mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageO(MSG_HANDLE_ASSIST,
- assistBundle));
+ mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageOOO(MSG_HANDLE_ASSIST,
+ data, structure, content));
}
@Override
@@ -226,7 +249,16 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback,
}
};
- public static class Request {
+ /** @hide */
+ public static class Caller {
+ }
+
+ /**
+ * Base class representing a request from a voice-driver app to perform a particular
+ * voice operation with the user. See related subclasses for the types of requests
+ * that are possible.
+ */
+ public static class Request extends Caller {
final IVoiceInteractorRequest mInterface = new IVoiceInteractorRequest.Stub() {
@Override
public void cancel() throws RemoteException {
@@ -237,12 +269,40 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback,
}
}
};
+ final String mCallingPackage;
+ final int mCallingUid;
final IVoiceInteractorCallback mCallback;
final WeakReference<VoiceInteractionSession> mSession;
+ final Bundle mExtras;
- Request(IVoiceInteractorCallback callback, VoiceInteractionSession session) {
+ Request(String packageName, int uid, IVoiceInteractorCallback callback,
+ VoiceInteractionSession session, Bundle extras) {
+ mCallingPackage = packageName;
+ mCallingUid = uid;
mCallback = callback;
mSession = session.mWeakRef;
+ mExtras = extras;
+ }
+
+ /**
+ * Return the uid of the application that initiated the request.
+ */
+ public int getCallingUid() {
+ return mCallingUid;
+ }
+
+ /**
+ * Return the package name of the application that initiated the request.
+ */
+ public String getCallingPackage() {
+ return mCallingPackage;
+ }
+
+ /**
+ * Return any additional extra information that was supplied as part of the request.
+ */
+ public Bundle getExtras() {
+ return mExtras;
}
void finishRequest() {
@@ -259,6 +319,7 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback,
}
}
+ /** @hide */
public void sendConfirmResult(boolean confirmed, Bundle result) {
try {
if (DEBUG) Log.d(TAG, "sendConfirmResult: req=" + mInterface
@@ -269,6 +330,7 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback,
}
}
+ /** @hide */
public void sendPickOptionResult(boolean finished,
VoiceInteractor.PickOptionRequest.Option[] selections, Bundle result) {
try {
@@ -283,6 +345,7 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback,
}
}
+ /** @hide */
public void sendCompleteVoiceResult(Bundle result) {
try {
if (DEBUG) Log.d(TAG, "sendCompleteVoiceResult: req=" + mInterface
@@ -293,6 +356,7 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback,
}
}
+ /** @hide */
public void sendAbortVoiceResult(Bundle result) {
try {
if (DEBUG) Log.d(TAG, "sendConfirmResult: req=" + mInterface
@@ -303,6 +367,7 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback,
}
}
+ /** @hide */
public void sendCommandResult(boolean finished, Bundle result) {
try {
if (DEBUG) Log.d(TAG, "sendCommandResult: req=" + mInterface
@@ -315,7 +380,15 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback,
}
}
+ /** @hide */
public void sendCancelResult() {
+ cancel();
+ }
+
+ /**
+ * ASk the app to cancel this current request.
+ */
+ public void cancel() {
try {
if (DEBUG) Log.d(TAG, "sendCancelResult: req=" + mInterface);
finishRequest();
@@ -325,13 +398,200 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback,
}
}
- public static class Caller {
- final String packageName;
- final int uid;
+ /**
+ * A request for confirmation from the user of an operation, as per
+ * {@link android.app.VoiceInteractor.ConfirmationRequest
+ * VoiceInteractor.ConfirmationRequest}.
+ */
+ public static final class ConfirmationRequest extends Request {
+ final CharSequence mPrompt;
- Caller(String _packageName, int _uid) {
- packageName = _packageName;
- uid = _uid;
+ ConfirmationRequest(String packageName, int uid, IVoiceInteractorCallback callback,
+ VoiceInteractionSession session, CharSequence prompt, Bundle extras) {
+ super(packageName, uid, callback, session, extras);
+ mPrompt = prompt;
+ }
+
+ /**
+ * Return the prompt informing the user of what will happen, as per
+ * {@link android.app.VoiceInteractor.ConfirmationRequest
+ * VoiceInteractor.ConfirmationRequest}.
+ */
+ public CharSequence getPrompt() {
+ return mPrompt;
+ }
+
+ /**
+ * Report that the voice interactor has confirmed the operation with the user, resulting
+ * in a call to
+ * {@link android.app.VoiceInteractor.ConfirmationRequest#onConfirmationResult
+ * VoiceInteractor.ConfirmationRequest.onConfirmationResult}.
+ */
+ public void sendConfirmationResult(boolean confirmed, Bundle result) {
+ sendConfirmResult(confirmed, result);
+ }
+ }
+
+ /**
+ * A request for the user to pick from a set of option, as per
+ * {@link android.app.VoiceInteractor.PickOptionRequest VoiceInteractor.PickOptionRequest}.
+ */
+ public static final class PickOptionRequest extends Request {
+ final CharSequence mPrompt;
+ final VoiceInteractor.PickOptionRequest.Option[] mOptions;
+
+ PickOptionRequest(String packageName, int uid, IVoiceInteractorCallback callback,
+ VoiceInteractionSession session, CharSequence prompt,
+ VoiceInteractor.PickOptionRequest.Option[] options, Bundle extras) {
+ super(packageName, uid, callback, session, extras);
+ mPrompt = prompt;
+ mOptions = options;
+ }
+
+ /**
+ * Return the prompt informing the user of what they are picking, as per
+ * {@link android.app.VoiceInteractor.PickOptionRequest VoiceInteractor.PickOptionRequest}.
+ */
+ public CharSequence getPrompt() {
+ return mPrompt;
+ }
+
+ /**
+ * Return the set of options the user is picking from, as per
+ * {@link android.app.VoiceInteractor.PickOptionRequest VoiceInteractor.PickOptionRequest}.
+ */
+ public VoiceInteractor.PickOptionRequest.Option[] getOptions() {
+ return mOptions;
+ }
+
+ /**
+ * Report an intermediate option selection from the request, without completing it (the
+ * request is still active and the app is waiting for the final option selection),
+ * resulting in a call to
+ * {@link android.app.VoiceInteractor.PickOptionRequest#onPickOptionResult
+ * VoiceInteractor.PickOptionRequest.onPickOptionResult} with false for finished.
+ */
+ public void sendIntermediatePickOptionResult(
+ VoiceInteractor.PickOptionRequest.Option[] selections, Bundle result) {
+ sendPickOptionResult(false, selections, result);
+ }
+
+ /**
+ * Report the final option selection for the request, completing the request
+ * and resulting in a call to
+ * {@link android.app.VoiceInteractor.PickOptionRequest#onPickOptionResult
+ * VoiceInteractor.PickOptionRequest.onPickOptionResult} with false for finished.
+ */
+ public void sendPickOptionResult(
+ VoiceInteractor.PickOptionRequest.Option[] selections, Bundle result) {
+ sendPickOptionResult(true, selections, result);
+ }
+ }
+
+ /**
+ * A request to simply inform the user that the voice operation has completed, as per
+ * {@link android.app.VoiceInteractor.CompleteVoiceRequest
+ * VoiceInteractor.CompleteVoiceRequest}.
+ */
+ public static final class CompleteVoiceRequest extends Request {
+ final CharSequence mMessage;
+
+ CompleteVoiceRequest(String packageName, int uid, IVoiceInteractorCallback callback,
+ VoiceInteractionSession session, CharSequence message, Bundle extras) {
+ super(packageName, uid, callback, session, extras);
+ mMessage = message;
+ }
+
+ /**
+ * Return the message informing the user of the completion, as per
+ * {@link android.app.VoiceInteractor.CompleteVoiceRequest
+ * VoiceInteractor.CompleteVoiceRequest}.
+ */
+ public CharSequence getMessage() {
+ return mMessage;
+ }
+
+ /**
+ * Report that the voice interactor has finished completing the voice operation, resulting
+ * in a call to
+ * {@link android.app.VoiceInteractor.CompleteVoiceRequest#onCompleteResult
+ * VoiceInteractor.CompleteVoiceRequest.onCompleteResult}.
+ */
+ public void sendCompleteResult(Bundle result) {
+ sendCompleteVoiceResult(result);
+ }
+ }
+
+ /**
+ * A request to report that the current user interaction can not be completed with voice, as per
+ * {@link android.app.VoiceInteractor.AbortVoiceRequest VoiceInteractor.AbortVoiceRequest}.
+ */
+ public static final class AbortVoiceRequest extends Request {
+ final CharSequence mMessage;
+
+ AbortVoiceRequest(String packageName, int uid, IVoiceInteractorCallback callback,
+ VoiceInteractionSession session, CharSequence message, Bundle extras) {
+ super(packageName, uid, callback, session, extras);
+ mMessage = message;
+ }
+
+ /**
+ * Return the message informing the user of the problem, as per
+ * {@link android.app.VoiceInteractor.AbortVoiceRequest VoiceInteractor.AbortVoiceRequest}.
+ */
+ public CharSequence getMessage() {
+ return mMessage;
+ }
+
+ /**
+ * Report that the voice interactor has finished aborting the voice operation, resulting
+ * in a call to
+ * {@link android.app.VoiceInteractor.AbortVoiceRequest#onAbortResult
+ * VoiceInteractor.AbortVoiceRequest.onAbortResult}.
+ */
+ public void sendAbortResult(Bundle result) {
+ sendAbortVoiceResult(result);
+ }
+ }
+
+ /**
+ * A generic vendor-specific request, as per
+ * {@link android.app.VoiceInteractor.CommandRequest VoiceInteractor.CommandRequest}.
+ */
+ public static final class CommandRequest extends Request {
+ final String mCommand;
+
+ CommandRequest(String packageName, int uid, IVoiceInteractorCallback callback,
+ VoiceInteractionSession session, String command, Bundle extras) {
+ super(packageName, uid, callback, session, extras);
+ mCommand = command;
+ }
+
+ /**
+ * Return the command that is being executed, as per
+ * {@link android.app.VoiceInteractor.CommandRequest VoiceInteractor.CommandRequest}.
+ */
+ public String getCommand() {
+ return mCommand;
+ }
+
+ /**
+ * Report an intermediate result of the request, without completing it (the request
+ * is still active and the app is waiting for the final result), resulting in a call to
+ * {@link android.app.VoiceInteractor.CommandRequest#onCommandResult
+ * VoiceInteractor.CommandRequest.onCommandResult} with false for isCompleted.
+ */
+ public void sendIntermediateResult(Bundle result) {
+ sendCommandResult(false, result);
+ }
+
+ /**
+ * Report the final result of the request, completing the request and resulting in a call to
+ * {@link android.app.VoiceInteractor.CommandRequest#onCommandResult
+ * VoiceInteractor.CommandRequest.onCommandResult} with true for isCompleted.
+ */
+ public void sendResult(Bundle result) {
+ sendCommandResult(true, result);
}
}
@@ -358,50 +618,33 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback,
SomeArgs args;
switch (msg.what) {
case MSG_START_CONFIRMATION:
- args = (SomeArgs)msg.obj;
- if (DEBUG) Log.d(TAG, "onConfirm: req=" + ((Request) args.arg2).mInterface
- + " prompt=" + args.arg3 + " extras=" + args.arg4);
- onConfirm((Caller)args.arg1, (Request)args.arg2, (CharSequence)args.arg3,
- (Bundle)args.arg4);
+ if (DEBUG) Log.d(TAG, "onConfirm: req=" + msg.obj);
+ onRequestConfirmation((ConfirmationRequest) msg.obj);
break;
case MSG_START_PICK_OPTION:
- args = (SomeArgs)msg.obj;
- if (DEBUG) Log.d(TAG, "onPickOption: req=" + ((Request) args.arg2).mInterface
- + " prompt=" + args.arg3 + " options=" + args.arg4
- + " extras=" + args.arg5);
- onPickOption((Caller)args.arg1, (Request)args.arg2, (CharSequence)args.arg3,
- (VoiceInteractor.PickOptionRequest.Option[])args.arg4,
- (Bundle)args.arg5);
+ if (DEBUG) Log.d(TAG, "onPickOption: req=" + msg.obj);
+ onRequestPickOption((PickOptionRequest) msg.obj);
break;
case MSG_START_COMPLETE_VOICE:
- args = (SomeArgs)msg.obj;
- if (DEBUG) Log.d(TAG, "onCompleteVoice: req=" + ((Request) args.arg2).mInterface
- + " message=" + args.arg3 + " extras=" + args.arg4);
- onCompleteVoice((Caller) args.arg1, (Request) args.arg2,
- (CharSequence) args.arg3, (Bundle) args.arg4);
+ if (DEBUG) Log.d(TAG, "onCompleteVoice: req=" + msg.obj);
+ onRequestCompleteVoice((CompleteVoiceRequest) msg.obj);
break;
case MSG_START_ABORT_VOICE:
- args = (SomeArgs)msg.obj;
- if (DEBUG) Log.d(TAG, "onAbortVoice: req=" + ((Request) args.arg2).mInterface
- + " message=" + args.arg3 + " extras=" + args.arg4);
- onAbortVoice((Caller) args.arg1, (Request) args.arg2, (CharSequence) args.arg3,
- (Bundle) args.arg4);
+ if (DEBUG) Log.d(TAG, "onAbortVoice: req=" + msg.obj);
+ onRequestAbortVoice((AbortVoiceRequest) msg.obj);
break;
case MSG_START_COMMAND:
- args = (SomeArgs)msg.obj;
- if (DEBUG) Log.d(TAG, "onCommand: req=" + ((Request) args.arg2).mInterface
- + " command=" + args.arg3 + " extras=" + args.arg4);
- onCommand((Caller) args.arg1, (Request) args.arg2, (String) args.arg3,
- (Bundle) args.arg4);
+ if (DEBUG) Log.d(TAG, "onCommand: req=" + msg.obj);
+ onRequestCommand((CommandRequest) msg.obj);
break;
case MSG_SUPPORTS_COMMANDS:
args = (SomeArgs)msg.obj;
- if (DEBUG) Log.d(TAG, "onGetSupportedCommands: cmds=" + args.arg2);
- args.arg1 = onGetSupportedCommands((Caller) args.arg1, (String[]) args.arg2);
+ if (DEBUG) Log.d(TAG, "onGetSupportedCommands: cmds=" + args.arg1);
+ args.arg1 = onGetSupportedCommands((String[]) args.arg1);
break;
case MSG_CANCEL:
if (DEBUG) Log.d(TAG, "onCancel: req=" + ((Request)msg.obj));
- onCancel((Request)msg.obj);
+ onCancelRequest((Request) msg.obj);
break;
case MSG_TASK_STARTED:
if (DEBUG) Log.d(TAG, "onTaskStarted: intent=" + msg.obj
@@ -422,8 +665,11 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback,
doDestroy();
break;
case MSG_HANDLE_ASSIST:
- if (DEBUG) Log.d(TAG, "onHandleAssist: " + msg.obj);
- onHandleAssist((Bundle) msg.obj);
+ args = (SomeArgs)msg.obj;
+ if (DEBUG) Log.d(TAG, "onHandleAssist: data=" + args.arg1
+ + " structure=" + args.arg2 + " content=" + args.arg3);
+ onHandleAssist((Bundle) args.arg1, (AssistStructure) args.arg2,
+ (AssistContent) args.arg3);
break;
case MSG_HANDLE_SCREENSHOT:
if (DEBUG) Log.d(TAG, "onHandleScreenshot: " + msg.obj);
@@ -527,12 +773,8 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback,
return mContext;
}
- Request newRequest(IVoiceInteractorCallback callback) {
- synchronized (this) {
- Request req = new Request(callback, this);
- mActiveRequests.put(req.mInterface.asBinder(), req);
- return req;
- }
+ void addRequest(Request req) {
+ mActiveRequests.put(req.mInterface.asBinder(), req);
}
Request removeRequest(IBinder reqInterface) {
@@ -631,7 +873,12 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback,
mContentFrame = (FrameLayout)mRootView.findViewById(android.R.id.content);
}
+ /** @hide */
public void show() {
+ show(null, 0);
+ }
+
+ public void show(Bundle args, int showFlags) {
try {
mSystemService.showSessionFromSession(mToken, null, 0);
} catch (RemoteException e) {
@@ -645,11 +892,11 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback,
}
}
- /** TODO: remove */
+ /** @hide */
public void showWindow() {
}
- /** TODO: remove */
+ /** @hide */
public void hideWindow() {
}
@@ -678,7 +925,9 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback,
* <p>As the voice activity runs, it can retrieve a {@link android.app.VoiceInteractor}
* through which it can perform voice interactions through your session. These requests
* for voice interactions will appear as callbacks on {@link #onGetSupportedCommands},
- * {@link #onConfirm}, {@link #onCommand}, and {@link #onCancel}.
+ * {@link #onRequestConfirmation}, {@link #onRequestPickOption},
+ * {@link #onRequestCompleteVoice}, {@link #onRequestAbortVoice},
+ * or {@link #onRequestCommand}
*
* <p>You will receive a call to {@link #onTaskStarted} when the task starts up
* and {@link #onTaskFinished} when the last activity has finished.
@@ -749,8 +998,25 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback,
}
}
+ /**
+ * Initiatize a new session. At this point you don't know exactly what this
+ * session will be used for; you will find that out in {@link #onShow}.
+ */
+ public void onCreate() {
+ doOnCreate();
+ }
+
/** @hide */
public void onCreate(Bundle args) {
+ doOnCreate();
+ }
+
+ /** @hide */
+ public void onCreate(Bundle args, int showFlags) {
+ doOnCreate();
+ }
+
+ private void doOnCreate() {
mTheme = mTheme != 0 ? mTheme
: com.android.internal.R.style.Theme_DeviceDefault_VoiceInteractionSession;
mInflater = (LayoutInflater)mContext.getSystemService(
@@ -767,15 +1033,6 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback,
}
/**
- * Initiatize a new session. The given args and showFlags are the initial values
- * passed to {@link VoiceInteractionService#showSession VoiceInteractionService.showSession},
- * if possible. Normally you should handle these in {@link #onShow}.
- */
- public void onCreate(Bundle args, int showFlags) {
- onCreate(args);
- }
-
- /**
* Called when the session UI is going to be shown. This is called after
* {@link #onCreateContentView} (if the session's content UI needed to be created) and
* immediately prior to the window being shown. This may be called while the window
@@ -817,9 +1074,22 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback,
}
+ /** @hide */
public void onHandleAssist(Bundle assistBundle) {
}
+ public void onHandleAssist(Bundle data, AssistStructure structure, AssistContent content) {
+ if (data != null) {
+ Bundle assistContext = data.getBundle(Intent.EXTRA_ASSIST_CONTEXT);
+ if (assistContext != null) {
+ assistContext.putParcelable(AssistStructure.ASSIST_KEY, structure);
+ assistContext.putParcelable(AssistContent.ASSIST_KEY, content);
+ data.putBundle(Intent.EXTRA_ASSIST_CONTEXT, assistContext);
+ }
+ }
+ onHandleAssist(data);
+ }
+
/** @hide */
public void onHandleScreenshot(Bitmap screenshot) {
}
@@ -916,18 +1186,45 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback,
hide();
}
+ /** @hide */
+ public boolean[] onGetSupportedCommands(Caller caller, String[] commands) {
+ return new boolean[commands.length];
+ }
+ /** @hide */
+ public void onConfirm(Caller caller, Request request, CharSequence prompt,
+ Bundle extras) {
+ }
+ /** @hide */
+ public void onPickOption(Caller caller, Request request, CharSequence prompt,
+ VoiceInteractor.PickOptionRequest.Option[] options, Bundle extras) {
+ }
+ /** @hide */
+ public void onCompleteVoice(Caller caller, Request request, CharSequence message,
+ Bundle extras) {
+ request.sendCompleteVoiceResult(null);
+ }
+ /** @hide */
+ public void onAbortVoice(Caller caller, Request request, CharSequence message, Bundle extras) {
+ request.sendAbortVoiceResult(null);
+ }
+ /** @hide */
+ public void onCommand(Caller caller, Request request, String command, Bundle extras) {
+ }
+ /** @hide */
+ public void onCancel(Request request) {
+ }
+
/**
* Request to query for what extended commands the session supports.
*
- * @param caller Who is making the request.
* @param commands An array of commands that are being queried.
* @return Return an array of booleans indicating which of each entry in the
* command array is supported. A true entry in the array indicates the command
* is supported; false indicates it is not. The default implementation returns
* an array of all false entries.
*/
- public boolean[] onGetSupportedCommands(Caller caller, String[] commands) {
- return new boolean[commands.length];
+ public boolean[] onGetSupportedCommands(String[] commands) {
+ return onGetSupportedCommands(new Caller(), commands);
}
/**
@@ -935,31 +1232,22 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback,
* corresponding to a {@link android.app.VoiceInteractor.ConfirmationRequest
* VoiceInteractor.ConfirmationRequest}.
*
- * @param caller Who is making the request.
* @param request The active request.
- * @param prompt The prompt informing the user of what will happen, as per
- * {@link android.app.VoiceInteractor.ConfirmationRequest VoiceInteractor.ConfirmationRequest}.
- * @param extras Any additional information, as per
- * {@link android.app.VoiceInteractor.ConfirmationRequest VoiceInteractor.ConfirmationRequest}.
*/
- public abstract void onConfirm(Caller caller, Request request, CharSequence prompt,
- Bundle extras);
+ public void onRequestConfirmation(ConfirmationRequest request) {
+ onConfirm(request, request, request.getPrompt(), request.getExtras());
+ }
/**
* Request for the user to pick one of N options, corresponding to a
* {@link android.app.VoiceInteractor.PickOptionRequest VoiceInteractor.PickOptionRequest}.
*
- * @param caller Who is making the request.
* @param request The active request.
- * @param prompt The prompt informing the user of what they are picking, as per
- * {@link android.app.VoiceInteractor.PickOptionRequest VoiceInteractor.PickOptionRequest}.
- * @param options The set of options the user is picking from, as per
- * {@link android.app.VoiceInteractor.PickOptionRequest VoiceInteractor.PickOptionRequest}.
- * @param extras Any additional information, as per
- * {@link android.app.VoiceInteractor.PickOptionRequest VoiceInteractor.PickOptionRequest}.
*/
- public abstract void onPickOption(Caller caller, Request request, CharSequence prompt,
- VoiceInteractor.PickOptionRequest.Option[] options, Bundle extras);
+ public void onRequestPickOption(PickOptionRequest request) {
+ onPickOption(request, request, request.getPrompt(), request.getOptions(),
+ request.getExtras());
+ }
/**
* Request to complete the voice interaction session because the voice activity successfully
@@ -968,18 +1256,10 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback,
* VoiceInteractor.CompleteVoiceRequest}. The default implementation just sends an empty
* confirmation back to allow the activity to exit.
*
- * @param caller Who is making the request.
* @param request The active request.
- * @param message The message informing the user of the problem, as per
- * {@link android.app.VoiceInteractor.CompleteVoiceRequest
- * VoiceInteractor.CompleteVoiceRequest}.
- * @param extras Any additional information, as per
- * {@link android.app.VoiceInteractor.CompleteVoiceRequest
- * VoiceInteractor.CompleteVoiceRequest}.
*/
- public void onCompleteVoice(Caller caller, Request request, CharSequence message,
- Bundle extras) {
- request.sendCompleteVoiceResult(null);
+ public void onRequestCompleteVoice(CompleteVoiceRequest request) {
+ onCompleteVoice(request, request, request.getMessage(), request.getExtras());
}
/**
@@ -989,15 +1269,10 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback,
* VoiceInteractor.AbortVoiceRequest}. The default implementation just sends an empty
* confirmation back to allow the activity to exit.
*
- * @param caller Who is making the request.
* @param request The active request.
- * @param message The message informing the user of the problem, as per
- * {@link android.app.VoiceInteractor.AbortVoiceRequest VoiceInteractor.AbortVoiceRequest}.
- * @param extras Any additional information, as per
- * {@link android.app.VoiceInteractor.AbortVoiceRequest VoiceInteractor.AbortVoiceRequest}.
*/
- public void onAbortVoice(Caller caller, Request request, CharSequence message, Bundle extras) {
- request.sendAbortVoiceResult(null);
+ public void onRequestAbortVoice(AbortVoiceRequest request) {
+ onAbortVoice(request, request, request.getMessage(), request.getExtras());
}
/**
@@ -1005,20 +1280,21 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback,
* corresponding to a {@link android.app.VoiceInteractor.CommandRequest
* VoiceInteractor.CommandRequest}.
*
- * @param caller Who is making the request.
* @param request The active request.
- * @param command The command that is being executed, as per
- * {@link android.app.VoiceInteractor.CommandRequest VoiceInteractor.CommandRequest}.
- * @param extras Any additional information, as per
- * {@link android.app.VoiceInteractor.CommandRequest VoiceInteractor.CommandRequest}.
*/
- public abstract void onCommand(Caller caller, Request request, String command, Bundle extras);
+ public void onRequestCommand(CommandRequest request) {
+ onCommand(request, request, request.getCommand(), request.getExtras());
+ }
/**
* Called when the {@link android.app.VoiceInteractor} has asked to cancel a {@link Request}
- * that was previously delivered to {@link #onConfirm} or {@link #onCommand}.
+ * that was previously delivered to {@link #onRequestConfirmation},
+ * {@link #onRequestPickOption}, {@link #onRequestCompleteVoice}, {@link #onRequestAbortVoice},
+ * or {@link #onRequestCommand}.
*
* @param request The request that is being canceled.
*/
- public abstract void onCancel(Request request);
+ public void onCancelRequest(Request request) {
+ onCancel(request);
+ }
}
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index b93a4a5..8952807 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -18,7 +18,6 @@ package android.service.wallpaper;
import android.content.res.TypedArray;
import android.graphics.Canvas;
-import android.os.SystemProperties;
import android.view.WindowInsets;
import com.android.internal.R;
@@ -161,9 +160,11 @@ public abstract class WallpaperService extends Service {
final Rect mOverscanInsets = new Rect();
final Rect mContentInsets = new Rect();
final Rect mStableInsets = new Rect();
+ final Rect mOutsets = new Rect();
final Rect mDispatchedOverscanInsets = new Rect();
final Rect mDispatchedContentInsets = new Rect();
final Rect mDispatchedStableInsets = new Rect();
+ final Rect mDispatchedOutsets = new Rect();
final Rect mFinalSystemInsets = new Rect();
final Rect mFinalStableInsets = new Rect();
final Configuration mConfiguration = new Configuration();
@@ -268,7 +269,7 @@ public abstract class WallpaperService extends Service {
final BaseIWindow mWindow = new BaseIWindow() {
@Override
public void resized(Rect frame, Rect overscanInsets, Rect contentInsets,
- Rect visibleInsets, Rect stableInsets, boolean reportDraw,
+ Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw,
Configuration newConfig) {
Message msg = mCaller.obtainMessageI(MSG_WINDOW_RESIZED,
reportDraw ? 1 : 0);
@@ -658,30 +659,35 @@ public abstract class WallpaperService extends Service {
mInputEventReceiver = new WallpaperInputEventReceiver(
mInputChannel, Looper.myLooper());
}
-
+
mSurfaceHolder.mSurfaceLock.lock();
mDrawingAllowed = true;
if (!fixedSize) {
mLayout.surfaceInsets.set(mIWallpaperEngine.mDisplayPadding);
+ mLayout.surfaceInsets.left += mOutsets.left;
+ mLayout.surfaceInsets.top += mOutsets.top;
+ mLayout.surfaceInsets.right += mOutsets.right;
+ mLayout.surfaceInsets.bottom += mOutsets.bottom;
} else {
mLayout.surfaceInsets.set(0, 0, 0, 0);
}
final int relayoutResult = mSession.relayout(
mWindow, mWindow.mSeq, mLayout, mWidth, mHeight,
View.VISIBLE, 0, mWinFrame, mOverscanInsets, mContentInsets,
- mVisibleInsets, mStableInsets, mConfiguration, mSurfaceHolder.mSurface);
+ mVisibleInsets, mStableInsets, mOutsets, mConfiguration,
+ mSurfaceHolder.mSurface);
if (DEBUG) Log.v(TAG, "New surface: " + mSurfaceHolder.mSurface
+ ", frame=" + mWinFrame);
-
+
int w = mWinFrame.width();
int h = mWinFrame.height();
if (!fixedSize) {
final Rect padding = mIWallpaperEngine.mDisplayPadding;
- w += padding.left + padding.right;
- h += padding.top + padding.bottom;
+ w += padding.left + padding.right + mOutsets.left + mOutsets.right;
+ h += padding.top + padding.bottom + mOutsets.top + mOutsets.bottom;
mOverscanInsets.left += padding.left;
mOverscanInsets.top += padding.top;
mOverscanInsets.right += padding.right;
@@ -705,9 +711,14 @@ public abstract class WallpaperService extends Service {
mCurHeight = h;
}
+ if (DEBUG) {
+ Log.v(TAG, "Wallpaper size has changed: (" + mCurWidth + ", " + mCurHeight);
+ }
+
insetsChanged |= !mDispatchedOverscanInsets.equals(mOverscanInsets);
insetsChanged |= !mDispatchedContentInsets.equals(mContentInsets);
insetsChanged |= !mDispatchedStableInsets.equals(mStableInsets);
+ insetsChanged |= !mDispatchedOutsets.equals(mOutsets);
mSurfaceHolder.setSurfaceFrameSize(w, h);
mSurfaceHolder.mSurfaceLock.unlock();
@@ -767,14 +778,21 @@ public abstract class WallpaperService extends Service {
if (insetsChanged) {
mDispatchedOverscanInsets.set(mOverscanInsets);
+ mDispatchedOverscanInsets.left += mOutsets.left;
+ mDispatchedOverscanInsets.top += mOutsets.top;
+ mDispatchedOverscanInsets.right += mOutsets.right;
+ mDispatchedOverscanInsets.bottom += mOutsets.bottom;
mDispatchedContentInsets.set(mContentInsets);
mDispatchedStableInsets.set(mStableInsets);
+ mDispatchedOutsets.set(mOutsets);
mFinalSystemInsets.set(mDispatchedOverscanInsets);
mFinalStableInsets.set(mDispatchedStableInsets);
- mFinalSystemInsets.bottom = mIWallpaperEngine.mDisplayPadding.bottom;
WindowInsets insets = new WindowInsets(mFinalSystemInsets,
null, mFinalStableInsets,
getResources().getConfiguration().isScreenRound());
+ if (DEBUG) {
+ Log.v(TAG, "dispatching insets=" + insets);
+ }
onApplyWindowInsets(insets);
}
diff --git a/core/java/android/speech/RecognitionService.java b/core/java/android/speech/RecognitionService.java
index dcdbba7..3e74d22 100644
--- a/core/java/android/speech/RecognitionService.java
+++ b/core/java/android/speech/RecognitionService.java
@@ -21,6 +21,7 @@ import android.annotation.SdkConstant.SdkConstantType;
import android.app.Service;
import android.content.Intent;
import android.content.pm.PackageManager;
+import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
@@ -78,7 +79,7 @@ public abstract class RecognitionService extends Service {
switch (msg.what) {
case MSG_START_LISTENING:
StartListeningArgs args = (StartListeningArgs) msg.obj;
- dispatchStartListening(args.mIntent, args.mListener);
+ dispatchStartListening(args.mIntent, args.mListener, args.mCallingUid);
break;
case MSG_STOP_LISTENING:
dispatchStopListening((IRecognitionListener) msg.obj);
@@ -93,7 +94,8 @@ public abstract class RecognitionService extends Service {
}
};
- private void dispatchStartListening(Intent intent, final IRecognitionListener listener) {
+ private void dispatchStartListening(Intent intent, final IRecognitionListener listener,
+ int callingUid) {
if (mCurrentCallback == null) {
if (DBG) Log.d(TAG, "created new mCurrentCallback, listener = " + listener.asBinder());
try {
@@ -107,7 +109,7 @@ public abstract class RecognitionService extends Service {
Log.e(TAG, "dead listener on startListening");
return;
}
- mCurrentCallback = new Callback(listener);
+ mCurrentCallback = new Callback(listener, callingUid);
RecognitionService.this.onStartListening(intent, mCurrentCallback);
} else {
try {
@@ -155,10 +157,12 @@ public abstract class RecognitionService extends Service {
public final Intent mIntent;
public final IRecognitionListener mListener;
+ public final int mCallingUid;
- public StartListeningArgs(Intent intent, IRecognitionListener listener) {
+ public StartListeningArgs(Intent intent, IRecognitionListener listener, int callingUid) {
this.mIntent = intent;
this.mListener = listener;
+ this.mCallingUid = callingUid;
}
}
@@ -227,9 +231,11 @@ public abstract class RecognitionService extends Service {
*/
public class Callback {
private final IRecognitionListener mListener;
+ private final int mCallingUid;
- private Callback(IRecognitionListener listener) {
+ private Callback(IRecognitionListener listener, int callingUid) {
mListener = listener;
+ mCallingUid = callingUid;
}
/**
@@ -314,6 +320,14 @@ public abstract class RecognitionService extends Service {
public void rmsChanged(float rmsdB) throws RemoteException {
mListener.onRmsChanged(rmsdB);
}
+
+ /**
+ * Return the Linux uid assigned to the process that sent you the current transaction that
+ * is being processed. This is obtained from {@link Binder#getCallingUid()}.
+ */
+ public int getCallingUid() {
+ return mCallingUid;
+ }
}
/** Binder of the recognition service */
@@ -331,7 +345,7 @@ public abstract class RecognitionService extends Service {
if (service != null && service.checkPermissions(listener)) {
service.mHandler.sendMessage(Message.obtain(service.mHandler,
MSG_START_LISTENING, service.new StartListeningArgs(
- recognizerIntent, listener)));
+ recognizerIntent, listener, Binder.getCallingUid())));
}
}
diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java
index f176240..f7027f9 100644
--- a/core/java/android/text/Layout.java
+++ b/core/java/android/text/Layout.java
@@ -1121,6 +1121,7 @@ public abstract class Layout {
* closest to the specified horizontal position.
*/
public int getOffsetForHorizontal(int line, float horiz) {
+ // TODO: use Paint.getOffsetForAdvance to avoid binary search
int max = getLineEnd(line) - 1;
int min = getLineStart(line);
Directions dirs = getLineDirections(line);
diff --git a/core/java/android/text/TextLine.java b/core/java/android/text/TextLine.java
index 479242c..605b91d 100644
--- a/core/java/android/text/TextLine.java
+++ b/core/java/android/text/TextLine.java
@@ -739,16 +739,14 @@ class TextLine {
float ret = 0;
- int contextLen = contextEnd - contextStart;
if (needWidth || (c != null && (wp.bgColor != 0 || wp.underlineColor != 0 || runIsRtl))) {
if (mCharsValid) {
- ret = wp.getTextRunAdvances(mChars, start, runLen,
- contextStart, contextLen, runIsRtl, null, 0);
+ ret = wp.getRunAdvance(mChars, start, contextEnd, contextStart, contextEnd,
+ runIsRtl, end);
} else {
int delta = mStart;
- ret = wp.getTextRunAdvances(mText, delta + start,
- delta + end, delta + contextStart, delta + contextEnd,
- runIsRtl, null, 0);
+ ret = wp.getRunAdvance(mText, delta + start, delta + contextEnd,
+ delta + contextStart, delta + contextEnd, runIsRtl, delta + end);
}
}
diff --git a/core/java/android/text/format/DateUtils.java b/core/java/android/text/format/DateUtils.java
index ac98e8a..14ebec7 100644
--- a/core/java/android/text/format/DateUtils.java
+++ b/core/java/android/text/format/DateUtils.java
@@ -258,7 +258,7 @@ public class DateUtils
* Returns a string describing 'time' as a time relative to 'now'.
* <p>
* Time spans in the past are formatted like "42 minutes ago".
- * Time spans in the future are formatted like "in 42 minutes".
+ * Time spans in the future are formatted like "In 42 minutes".
*
* @param time the time to describe, in milliseconds
* @param now the current time in milliseconds
@@ -275,7 +275,7 @@ public class DateUtils
* Returns a string describing 'time' as a time relative to 'now'.
* <p>
* Time spans in the past are formatted like "42 minutes ago". Time spans in
- * the future are formatted like "in 42 minutes".
+ * the future are formatted like "In 42 minutes".
* <p>
* Can use {@link #FORMAT_ABBREV_RELATIVE} flag to use abbreviated relative
* times, like "42 mins ago".
diff --git a/core/java/android/view/AccessibilityInteractionController.java b/core/java/android/view/AccessibilityInteractionController.java
index 3781d40..6e2d110 100644
--- a/core/java/android/view/AccessibilityInteractionController.java
+++ b/core/java/android/view/AccessibilityInteractionController.java
@@ -758,7 +758,10 @@ final class AccessibilityInteractionController {
Rect visibleDisplayFrame = mTempRect2;
visibleDisplayFrame.set(0, 0, displayWidth, displayHeight);
- visibleWinFrame.intersect(visibleDisplayFrame);
+ if (!visibleWinFrame.intersect(visibleDisplayFrame)) {
+ // If there's no intersection with display, set visibleWinFrame empty.
+ visibleDisplayFrame.setEmpty();
+ }
if (!visibleWinFrame.intersects(boundsInScreen.left, boundsInScreen.top,
boundsInScreen.right, boundsInScreen.bottom)) {
diff --git a/core/java/android/view/GestureDetector.java b/core/java/android/view/GestureDetector.java
index b8544c6..ff0af6b 100644
--- a/core/java/android/view/GestureDetector.java
+++ b/core/java/android/view/GestureDetector.java
@@ -32,6 +32,9 @@ import android.os.Message;
* <li>In the {@link View#onTouchEvent(MotionEvent)} method ensure you call
* {@link #onTouchEvent(MotionEvent)}. The methods defined in your callback
* will be executed when the events occur.
+ * <li>If listening for {@link OnStylusButtonPressListener#onStylusButtonPress(MotionEvent)}
+ * you must call {@link #onGenericMotionEvent(MotionEvent)}
+ * in {@link View#onGenericMotionEvent(MotionEvent)}.
* </ul>
*/
public class GestureDetector {
@@ -149,12 +152,14 @@ public class GestureDetector {
}
/**
- * The listener that is used to notify when a stylus button press occurs.
+ * The listener that is used to notify when a stylus button press occurs. When listening for a
+ * stylus button press ensure that you call {@link #onGenericMotionEvent(MotionEvent)} in
+ * {@link View#onGenericMotionEvent(MotionEvent)}.
*/
public interface OnStylusButtonPressListener {
/**
* Notified when a stylus button press occurs. This is when the stylus
- * is touching the screen and the {@value MotionEvent#BUTTON_SECONDARY}
+ * is touching the screen and the {@value MotionEvent#BUTTON_STYLUS_PRIMARY}
* is pressed.
*
* @param e The motion event that occurred during the stylus button
@@ -241,6 +246,7 @@ public class GestureDetector {
private boolean mInStylusButtonPress;
private boolean mAlwaysInTapRegion;
private boolean mAlwaysInBiggerTapRegion;
+ private boolean mIgnoreNextUpEvent;
private MotionEvent mCurrentDownEvent;
private MotionEvent mPreviousUpEvent;
@@ -552,18 +558,7 @@ public class GestureDetector {
break;
case MotionEvent.ACTION_DOWN:
- if (mStylusButtonListener != null
- && ev.getToolType(0) == MotionEvent.TOOL_TYPE_STYLUS
- && (ev.getButtonState() & MotionEvent.BUTTON_SECONDARY) != 0) {
- if (mStylusButtonListener.onStylusButtonPress(ev)) {
- mInStylusButtonPress = true;
- handled = true;
- mHandler.removeMessages(LONG_PRESS);
- mHandler.removeMessages(TAP);
- }
- }
-
- if (mDoubleTapListener != null && !mInStylusButtonPress) {
+ if (mDoubleTapListener != null) {
boolean hadTapMessage = mHandler.hasMessages(TAP);
if (hadTapMessage) mHandler.removeMessages(TAP);
if ((mCurrentDownEvent != null) && (mPreviousUpEvent != null) && hadTapMessage &&
@@ -592,7 +587,7 @@ public class GestureDetector {
mInLongPress = false;
mDeferConfirmSingleTap = false;
- if (mIsLongpressEnabled && !mInStylusButtonPress) {
+ if (mIsLongpressEnabled) {
mHandler.removeMessages(LONG_PRESS);
mHandler.sendEmptyMessageAtTime(LONG_PRESS, mCurrentDownEvent.getDownTime()
+ TAP_TIMEOUT + LONGPRESS_TIMEOUT);
@@ -602,16 +597,6 @@ public class GestureDetector {
break;
case MotionEvent.ACTION_MOVE:
- if (mStylusButtonListener != null && !mInStylusButtonPress && !mInLongPress
- && ev.getToolType(0) == MotionEvent.TOOL_TYPE_STYLUS
- && (ev.getButtonState() & MotionEvent.BUTTON_SECONDARY) != 0) {
- if (mStylusButtonListener.onStylusButtonPress(ev)) {
- mInStylusButtonPress = true;
- handled = true;
- mHandler.removeMessages(LONG_PRESS);
- mHandler.removeMessages(TAP);
- }
- }
if (mInLongPress || mInStylusButtonPress) {
break;
}
@@ -652,15 +637,12 @@ public class GestureDetector {
} else if (mInLongPress) {
mHandler.removeMessages(TAP);
mInLongPress = false;
- } else if (mInStylusButtonPress) {
- mHandler.removeMessages(TAP);
- mInStylusButtonPress = false;
- } else if (mAlwaysInTapRegion) {
+ } else if (mAlwaysInTapRegion && !mIgnoreNextUpEvent) {
handled = mListener.onSingleTapUp(ev);
if (mDeferConfirmSingleTap && mDoubleTapListener != null) {
mDoubleTapListener.onSingleTapConfirmed(ev);
}
- } else {
+ } else if (!mIgnoreNextUpEvent) {
// A fling must travel the minimum tap distance
final VelocityTracker velocityTracker = mVelocityTracker;
@@ -687,6 +669,7 @@ public class GestureDetector {
}
mIsDoubleTapping = false;
mDeferConfirmSingleTap = false;
+ mIgnoreNextUpEvent = false;
mHandler.removeMessages(SHOW_PRESS);
mHandler.removeMessages(LONG_PRESS);
break;
@@ -702,6 +685,43 @@ public class GestureDetector {
return handled;
}
+ /**
+ * Analyzes the given generic motion event and if applicable triggers the
+ * appropriate callbacks on the {@link OnGestureListener} supplied.
+ *
+ * @param ev The current motion event.
+ * @return true if the {@link OnGestureListener} consumed the event,
+ * else false.
+ */
+ public boolean onGenericMotionEvent(MotionEvent ev) {
+ if (mInputEventConsistencyVerifier != null) {
+ mInputEventConsistencyVerifier.onGenericMotionEvent(ev, 0);
+ }
+
+ switch (ev.getActionMasked()) {
+ case MotionEvent.ACTION_BUTTON_PRESS:
+ if (mStylusButtonListener != null && !mInStylusButtonPress && !mInLongPress
+ && ev.getActionButton() == MotionEvent.BUTTON_STYLUS_PRIMARY) {
+ if (mStylusButtonListener.onStylusButtonPress(ev)) {
+ mInStylusButtonPress = true;
+ mHandler.removeMessages(LONG_PRESS);
+ mHandler.removeMessages(TAP);
+ return true;
+ }
+ }
+ break;
+
+ case MotionEvent.ACTION_BUTTON_RELEASE:
+ if (mInStylusButtonPress
+ && ev.getActionButton() == MotionEvent.BUTTON_STYLUS_PRIMARY) {
+ mInStylusButtonPress = false;
+ mIgnoreNextUpEvent = true;
+ }
+ break;
+ }
+ return false;
+ }
+
private void cancel() {
mHandler.removeMessages(SHOW_PRESS);
mHandler.removeMessages(LONG_PRESS);
@@ -715,6 +735,7 @@ public class GestureDetector {
mDeferConfirmSingleTap = false;
mInLongPress = false;
mInStylusButtonPress = false;
+ mIgnoreNextUpEvent = false;
}
private void cancelTaps() {
@@ -727,6 +748,7 @@ public class GestureDetector {
mDeferConfirmSingleTap = false;
mInLongPress = false;
mInStylusButtonPress = false;
+ mIgnoreNextUpEvent = false;
}
private boolean isConsideredDoubleTap(MotionEvent firstDown, MotionEvent firstUp,
diff --git a/core/java/android/view/IWindow.aidl b/core/java/android/view/IWindow.aidl
index 0fefdc7..9cf3759 100644
--- a/core/java/android/view/IWindow.aidl
+++ b/core/java/android/view/IWindow.aidl
@@ -46,7 +46,7 @@ oneway interface IWindow {
void executeCommand(String command, String parameters, in ParcelFileDescriptor descriptor);
void resized(in Rect frame, in Rect overscanInsets, in Rect contentInsets,
- in Rect visibleInsets, in Rect stableInsets, boolean reportDraw,
+ in Rect visibleInsets, in Rect stableInsets, in Rect outsets, boolean reportDraw,
in Configuration newConfig);
void moved(int newX, int newY);
void dispatchAppVisibility(boolean visible);
diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl
index fc0148f..19253dd 100644
--- a/core/java/android/view/IWindowSession.aidl
+++ b/core/java/android/view/IWindowSession.aidl
@@ -79,11 +79,13 @@ interface IWindowSession {
* contents to make sure the user can see it. This is different than
* <var>outContentInsets</var> in that these insets change transiently,
* so complex relayout of the window should not happen based on them.
+ * @param outOutsets Rect in which is placed the dead area of the screen that we would like to
+ * treat as real display. Example of such area is a chin in some models of wearable devices.
* @param outConfiguration New configuration of window, if it is now
* becoming visible and the global configuration has changed since it
* was last displayed.
* @param outSurface Object in which is placed the new display surface.
- *
+ *
* @return int Result flags: {@link WindowManagerGlobal#RELAYOUT_SHOW_FOCUS},
* {@link WindowManagerGlobal#RELAYOUT_FIRST_TIME}.
*/
@@ -91,7 +93,7 @@ interface IWindowSession {
int requestedWidth, int requestedHeight, int viewVisibility,
int flags, out Rect outFrame, out Rect outOverscanInsets,
out Rect outContentInsets, out Rect outVisibleInsets, out Rect outStableInsets,
- out Configuration outConfig, out Surface outSurface);
+ out Rect outOutsets, out Configuration outConfig, out Surface outSurface);
/**
* If a call to relayout() asked to have the surface destroy deferred,
diff --git a/core/java/android/view/ScaleGestureDetector.java b/core/java/android/view/ScaleGestureDetector.java
index b055efe..7b0f1fb 100644
--- a/core/java/android/view/ScaleGestureDetector.java
+++ b/core/java/android/view/ScaleGestureDetector.java
@@ -320,8 +320,8 @@ public class ScaleGestureDetector {
}
final int count = event.getPointerCount();
- final boolean isStylusButtonDown = (event.getToolType(0) == MotionEvent.TOOL_TYPE_STYLUS)
- && (event.getButtonState() & MotionEvent.BUTTON_SECONDARY) != 0;
+ final boolean isStylusButtonDown =
+ (event.getButtonState() & MotionEvent.BUTTON_STYLUS_PRIMARY) != 0;
final boolean anchoredScaleCancelled =
mAnchoredScaleMode == ANCHORED_SCALE_MODE_STYLUS && !isStylusButtonDown;
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 49be57d..160c662 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -106,6 +106,7 @@ public class SurfaceView extends View {
final Rect mOverscanInsets = new Rect();
final Rect mContentInsets = new Rect();
final Rect mStableInsets = new Rect();
+ final Rect mOutsets = new Rect();
final Configuration mConfiguration = new Configuration();
static final int KEEP_SCREEN_ON_MSG = 1;
@@ -519,7 +520,8 @@ public class SurfaceView extends View {
visible ? VISIBLE : GONE,
WindowManagerGlobal.RELAYOUT_DEFER_SURFACE_DESTROY,
mWinFrame, mOverscanInsets, mContentInsets,
- mVisibleInsets, mStableInsets, mConfiguration, mNewSurface);
+ mVisibleInsets, mStableInsets, mOutsets, mConfiguration,
+ mNewSurface);
if ((relayoutResult & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0) {
mReportDrawNeeded = true;
}
@@ -654,7 +656,7 @@ public class SurfaceView extends View {
@Override
public void resized(Rect frame, Rect overscanInsets, Rect contentInsets,
- Rect visibleInsets, Rect stableInsets, boolean reportDraw,
+ Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw,
Configuration newConfig) {
SurfaceView surfaceView = mSurfaceView.get();
if (surfaceView != null) {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 3962b70..cfd504d 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -3521,7 +3521,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* the stylus is touching the screen and the button has been pressed, this
* is false once the stylus has been lifted.
*/
- private boolean mInStylusButtonPress = false;
+ private boolean mInStylusButtonPress;
+
+ /**
+ * Whether the next up event should be ignored for the purposes of gesture recognition. This is
+ * true after a stylus button press has occured, when the next up event should not be recognized
+ * as a tap.
+ */
+ private boolean mIgnoreNextUpEvent;
/**
* The minimum height of the view. We'll try our best to have the height
@@ -4457,47 +4464,60 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
private static SparseArray<String> getAttributeMap() {
if (mAttributeMap == null) {
- mAttributeMap = new SparseArray<String>();
+ mAttributeMap = new SparseArray<>();
}
return mAttributeMap;
}
- private void saveAttributeData(AttributeSet attrs, TypedArray a) {
- int length = ((attrs == null ? 0 : attrs.getAttributeCount()) + a.getIndexCount()) * 2;
- mAttributes = new String[length];
+ private void saveAttributeData(@Nullable AttributeSet attrs, @NonNull TypedArray t) {
+ final int attrsCount = attrs == null ? 0 : attrs.getAttributeCount();
+ final int indexCount = t.getIndexCount();
+ final String[] attributes = new String[(attrsCount + indexCount) * 2];
int i = 0;
- if (attrs != null) {
- for (i = 0; i < attrs.getAttributeCount(); i += 2) {
- mAttributes[i] = attrs.getAttributeName(i);
- mAttributes[i + 1] = attrs.getAttributeValue(i);
- }
+ // Store raw XML attributes.
+ for (int j = 0; j < attrsCount; ++j) {
+ attributes[i] = attrs.getAttributeName(j);
+ attributes[i + 1] = attrs.getAttributeValue(j);
+ i += 2;
}
- SparseArray<String> attributeMap = getAttributeMap();
- for (int j = 0; j < a.length(); ++j) {
- if (a.hasValue(j)) {
- try {
- int resourceId = a.getResourceId(j, 0);
- if (resourceId == 0) {
- continue;
- }
+ // Store resolved styleable attributes.
+ final Resources res = t.getResources();
+ final SparseArray<String> attributeMap = getAttributeMap();
+ for (int j = 0; j < indexCount; ++j) {
+ final int index = t.getIndex(j);
+ if (!t.hasValueOrEmpty(index)) {
+ // Value is undefined. Skip it.
+ continue;
+ }
- String resourceName = attributeMap.get(resourceId);
- if (resourceName == null) {
- resourceName = a.getResources().getResourceName(resourceId);
- attributeMap.put(resourceId, resourceName);
- }
+ final int resourceId = t.getResourceId(index, 0);
+ if (resourceId == 0) {
+ // Value is not a reference. Skip it.
+ continue;
+ }
- mAttributes[i] = resourceName;
- mAttributes[i + 1] = a.getText(j).toString();
- i += 2;
+ String resourceName = attributeMap.get(resourceId);
+ if (resourceName == null) {
+ try {
+ resourceName = res.getResourceName(resourceId);
} catch (Resources.NotFoundException e) {
- // if we can't get the resource name, we just ignore it
+ resourceName = "0x" + Integer.toHexString(resourceId);
}
+ attributeMap.put(resourceId, resourceName);
}
+
+ attributes[i] = resourceName;
+ attributes[i + 1] = t.getString(index);
+ i += 2;
}
+
+ // Trim to fit contents.
+ final String[] trimmed = new String[i];
+ System.arraycopy(attributes, 0, trimmed, 0, i);
+ mAttributes = trimmed;
}
public String toString() {
@@ -5218,26 +5238,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
/**
- * Checks for a stylus button press and calls the listener.
- *
- * @param event The event.
- * @return True if the event was consumed.
- */
- private boolean performStylusActionOnButtonPress(MotionEvent event) {
- if (isStylusButtonPressable() && !mInStylusButtonPress && !mHasPerformedLongPress
- && event.isButtonPressed(MotionEvent.BUTTON_STYLUS_SECONDARY)) {
- if (performStylusButtonPress()) {
- mInStylusButtonPress = true;
- setPressed(true, event.getX(), event.getY());
- removeTapCallback();
- removeLongPressCallback();
- return true;
- }
- }
- return false;
- }
-
- /**
* Performs button-related actions during a touch down event.
*
* @param event The event.
@@ -6351,7 +6351,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
View next = rootView.findViewInsideOutShouldExist(this,
mAccessibilityTraversalBeforeId);
- if (next != null) {
+ if (next != null && next.includeForAccessibility()) {
info.setTraversalBefore(next);
}
}
@@ -6363,7 +6363,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
View next = rootView.findViewInsideOutShouldExist(this,
mAccessibilityTraversalAfterId);
- if (next != null) {
+ if (next != null && next.includeForAccessibility()) {
info.setTraversalAfter(next);
}
}
@@ -7363,6 +7363,15 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
/**
+ * Returns the outsets, which areas of the device that aren't a surface, but we would like to
+ * treat them as such.
+ * @hide
+ */
+ public void getOutsets(Rect outOutsetRect) {
+ outOutsetRect.set(mAttachInfo.mOutsets);
+ }
+
+ /**
* Returns the visibility status for this view.
*
* @return One of {@link #VISIBLE}, {@link #INVISIBLE}, or {@link #GONE}.
@@ -9358,6 +9367,29 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
return true;
}
+ switch (event.getActionMasked()) {
+ case MotionEvent.ACTION_BUTTON_PRESS:
+ if (isStylusButtonPressable() && !mInStylusButtonPress && !mHasPerformedLongPress
+ && event.getActionButton() == MotionEvent.BUTTON_STYLUS_PRIMARY) {
+ if (performStylusButtonPress()) {
+ mInStylusButtonPress = true;
+ setPressed(true, event.getX(), event.getY());
+ removeTapCallback();
+ removeLongPressCallback();
+ return true;
+ }
+ }
+ break;
+
+ case MotionEvent.ACTION_BUTTON_RELEASE:
+ if (mInStylusButtonPress
+ && event.getActionButton() == MotionEvent.BUTTON_STYLUS_PRIMARY) {
+ mInStylusButtonPress = false;
+ mIgnoreNextUpEvent = true;
+ }
+ break;
+ }
+
if (mInputEventConsistencyVerifier != null) {
mInputEventConsistencyVerifier.onUnhandledEvent(event, 0);
}
@@ -10218,10 +10250,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
(viewFlags & STYLUS_BUTTON_PRESSABLE) == STYLUS_BUTTON_PRESSABLE) {
switch (action) {
case MotionEvent.ACTION_UP:
- if (mInStylusButtonPress) {
- mInStylusButtonPress = false;
- mHasPerformedLongPress = false;
- }
boolean prepressed = (mPrivateFlags & PFLAG_PREPRESSED) != 0;
if ((mPrivateFlags & PFLAG_PRESSED) != 0 || prepressed) {
// take focus if we don't have it already and we should in
@@ -10239,7 +10267,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
setPressed(true, x, y);
}
- if (!mHasPerformedLongPress) {
+ if (!mHasPerformedLongPress && !mIgnoreNextUpEvent) {
// This is a tap, so remove the longpress check
removeLongPressCallback();
@@ -10271,15 +10299,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
removeTapCallback();
}
+ mIgnoreNextUpEvent = false;
break;
case MotionEvent.ACTION_DOWN:
mHasPerformedLongPress = false;
- mInStylusButtonPress = false;
-
- if (performStylusActionOnButtonPress(event)) {
- break;
- }
if (performButtonActionOnTouchDown(event)) {
break;
@@ -10309,10 +10333,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
setPressed(false);
removeTapCallback();
removeLongPressCallback();
- if (mInStylusButtonPress) {
- mInStylusButtonPress = false;
- mHasPerformedLongPress = false;
- }
+ mInStylusButtonPress = false;
+ mHasPerformedLongPress = false;
+ mIgnoreNextUpEvent = false;
break;
case MotionEvent.ACTION_MOVE:
@@ -10328,9 +10351,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
setPressed(false);
}
- } else if (performStylusActionOnButtonPress(event)) {
- // Check for stylus button press if we're within the view.
- break;
}
break;
}
@@ -14493,6 +14513,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
onDetachedFromWindow();
onDetachedFromWindowInternal();
+ InputMethodManager imm = InputMethodManager.peekInstance();
+ if (imm != null) {
+ imm.onViewDetachedFromWindow(this);
+ }
+
ListenerInfo li = mListenerInfo;
final CopyOnWriteArrayList<OnAttachStateChangeListener> listeners =
li != null ? li.mOnAttachStateChangeListeners : null;
@@ -21548,6 +21573,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
final Rect mStableInsets = new Rect();
/**
+ * For windows that include areas that are not covered by real surface these are the outsets
+ * for real surface.
+ */
+ final Rect mOutsets = new Rect();
+
+ /**
* The internal insets given by this window. This value is
* supplied by the client (through
* {@link ViewTreeObserver.OnComputeInternalInsetsListener}) and will
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index a7e739d..e015c04 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -793,7 +793,8 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
@Override
public ActionMode startActionModeForChild(
View originalView, ActionMode.Callback callback, int type) {
- if ((mGroupFlags & FLAG_START_ACTION_MODE_FOR_CHILD_IS_NOT_TYPED) == 0) {
+ if ((mGroupFlags & FLAG_START_ACTION_MODE_FOR_CHILD_IS_NOT_TYPED) == 0
+ && type == ActionMode.TYPE_PRIMARY) {
ActionMode mode;
try {
mGroupFlags |= FLAG_START_ACTION_MODE_FOR_CHILD_IS_TYPED;
@@ -1913,6 +1914,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
@Override
public void addChildrenForAccessibility(ArrayList<View> childrenForAccessibility) {
+ if (getAccessibilityNodeProvider() != null) {
+ return;
+ }
ChildListForAccessibility children = ChildListForAccessibility.obtain(this, true);
try {
final int childrenCount = children.getChildCount();
@@ -3602,14 +3606,14 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
}
/**
- * Sets whether this ViewGroup will clip its children to its padding, if
- * padding is present.
+ * Sets whether this ViewGroup will clip its children to its padding and resize (but not
+ * clip) any EdgeEffect to the padded region, if padding is present.
* <p>
* By default, children are clipped to the padding of their parent
- * Viewgroup. This clipping behavior is only enabled if padding is non-zero.
+ * ViewGroup. This clipping behavior is only enabled if padding is non-zero.
*
- * @param clipToPadding true to clip children to the padding of the
- * group, false otherwise
+ * @param clipToPadding true to clip children to the padding of the group, and resize (but
+ * not clip) any EdgeEffect to the padded region. False otherwise.
* @attr ref android.R.styleable#ViewGroup_clipToPadding
*/
public void setClipToPadding(boolean clipToPadding) {
@@ -3620,13 +3624,14 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
}
/**
- * Returns whether this ViewGroup will clip its children to its padding, if
- * padding is present.
+ * Returns whether this ViewGroup will clip its children to its padding, and resize (but
+ * not clip) any EdgeEffect to the padded region, if padding is present.
* <p>
* By default, children are clipped to the padding of their parent
* Viewgroup. This clipping behavior is only enabled if padding is non-zero.
*
- * @return true if this ViewGroup clips children to its padding, false otherwise
+ * @return true if this ViewGroup clips children to its padding and resizes (but doesn't
+ * clip) any EdgeEffect to the padded region, false otherwise.
*
* @attr ref android.R.styleable#ViewGroup_clipToPadding
*/
@@ -5224,12 +5229,20 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
descendant.mTop - descendant.mScrollY);
if (clipToBounds) {
View p = (View) theParent;
- rect.intersect(0, 0, p.mRight - p.mLeft, p.mBottom - p.mTop);
+ boolean intersected = rect.intersect(0, 0, p.mRight - p.mLeft,
+ p.mBottom - p.mTop);
+ if (!intersected) {
+ rect.setEmpty();
+ }
}
} else {
if (clipToBounds) {
View p = (View) theParent;
- rect.intersect(0, 0, p.mRight - p.mLeft, p.mBottom - p.mTop);
+ boolean intersected = rect.intersect(0, 0, p.mRight - p.mLeft,
+ p.mBottom - p.mTop);
+ if (!intersected) {
+ rect.setEmpty();
+ }
}
rect.offset(descendant.mScrollX - descendant.mLeft,
descendant.mScrollY - descendant.mTop);
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 89b91f1..e1e0154 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -268,6 +268,7 @@ public final class ViewRootImpl implements ViewParent,
final Rect mPendingVisibleInsets = new Rect();
final Rect mPendingStableInsets = new Rect();
final Rect mPendingContentInsets = new Rect();
+ final Rect mPendingOutsets = new Rect();
final ViewTreeObserver.InternalInsetsInfo mLastGivenInsets
= new ViewTreeObserver.InternalInsetsInfo();
@@ -1267,6 +1268,12 @@ public final class ViewRootImpl implements ViewParent,
contentInsets = mPendingContentInsets;
stableInsets = mPendingStableInsets;
}
+ Rect outsets = mAttachInfo.mOutsets;
+ if (outsets.left > 0 || outsets.top > 0 || outsets.right > 0 || outsets.bottom > 0) {
+ contentInsets = new Rect(contentInsets.left + outsets.left,
+ contentInsets.top + outsets.top, contentInsets.right + outsets.right,
+ contentInsets.bottom + outsets.bottom);
+ }
mLastWindowInsets = new WindowInsets(contentInsets,
null /* windowDecorInsets */, stableInsets,
mContext.getResources().getConfiguration().isScreenRound());
@@ -1425,6 +1432,9 @@ public final class ViewRootImpl implements ViewParent,
if (DEBUG_LAYOUT) Log.v(TAG, "Visible insets changing to: "
+ mAttachInfo.mVisibleInsets);
}
+ if (!mPendingOutsets.equals(mAttachInfo.mOutsets)) {
+ insetsChanged = true;
+ }
if (lp.width == ViewGroup.LayoutParams.WRAP_CONTENT
|| lp.height == ViewGroup.LayoutParams.WRAP_CONTENT) {
windowSizeMayChange = true;
@@ -1598,6 +1608,7 @@ public final class ViewRootImpl implements ViewParent,
mAttachInfo.mVisibleInsets);
final boolean stableInsetsChanged = !mPendingStableInsets.equals(
mAttachInfo.mStableInsets);
+ final boolean outsetsChanged = !mPendingOutsets.equals(mAttachInfo.mOutsets);
if (contentInsetsChanged) {
if (mWidth > 0 && mHeight > 0 && lp != null &&
((lp.systemUiVisibility|lp.subtreeSystemUiVisibility)
@@ -1681,9 +1692,11 @@ public final class ViewRootImpl implements ViewParent,
}
if (contentInsetsChanged || mLastSystemUiVisibility !=
mAttachInfo.mSystemUiVisibility || mApplyInsetsRequested
- || mLastOverscanRequested != mAttachInfo.mOverscanRequested) {
+ || mLastOverscanRequested != mAttachInfo.mOverscanRequested
+ || outsetsChanged) {
mLastSystemUiVisibility = mAttachInfo.mSystemUiVisibility;
mLastOverscanRequested = mAttachInfo.mOverscanRequested;
+ mAttachInfo.mOutsets.set(mPendingOutsets);
mApplyInsetsRequested = false;
dispatchApplyInsets(host);
}
@@ -2791,7 +2804,11 @@ public final class ViewRootImpl implements ViewParent,
final AttachInfo attachInfo = mAttachInfo;
bounds.offset(0, attachInfo.mViewRootImpl.mScrollY);
bounds.offset(-attachInfo.mWindowLeft, -attachInfo.mWindowTop);
- bounds.intersect(0, 0, attachInfo.mViewRootImpl.mWidth, attachInfo.mViewRootImpl.mHeight);
+ if (!bounds.intersect(0, 0, attachInfo.mViewRootImpl.mWidth,
+ attachInfo.mViewRootImpl.mHeight)) {
+ // If no intersection, set bounds to empty.
+ bounds.setEmpty();
+ }
return !bounds.isEmpty();
}
@@ -3259,6 +3276,7 @@ public final class ViewRootImpl implements ViewParent,
&& mPendingContentInsets.equals(args.arg2)
&& mPendingStableInsets.equals(args.arg6)
&& mPendingVisibleInsets.equals(args.arg3)
+ && mPendingOutsets.equals(args.arg7)
&& args.arg4 == null) {
break;
}
@@ -3277,6 +3295,7 @@ public final class ViewRootImpl implements ViewParent,
mPendingContentInsets.set((Rect) args.arg2);
mPendingStableInsets.set((Rect) args.arg6);
mPendingVisibleInsets.set((Rect) args.arg3);
+ mPendingOutsets.set((Rect) args.arg7);
args.recycle();
@@ -5387,7 +5406,7 @@ public final class ViewRootImpl implements ViewParent,
(int) (mView.getMeasuredHeight() * appScale + 0.5f),
viewVisibility, insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0,
mWinFrame, mPendingOverscanInsets, mPendingContentInsets, mPendingVisibleInsets,
- mPendingStableInsets, mPendingConfiguration, mSurface);
+ mPendingStableInsets, mPendingOutsets, mPendingConfiguration, mSurface);
//Log.d(TAG, "<<<<<< BACK FROM relayout");
if (restore) {
params.restore();
@@ -5656,7 +5675,8 @@ public final class ViewRootImpl implements ViewParent,
}
public void dispatchResized(Rect frame, Rect overscanInsets, Rect contentInsets,
- Rect visibleInsets, Rect stableInsets, boolean reportDraw, Configuration newConfig) {
+ Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw,
+ Configuration newConfig) {
if (DEBUG_LAYOUT) Log.v(TAG, "Resizing " + this + ": frame=" + frame.toShortString()
+ " contentInsets=" + contentInsets.toShortString()
+ " visibleInsets=" + visibleInsets.toShortString()
@@ -5676,6 +5696,7 @@ public final class ViewRootImpl implements ViewParent,
args.arg4 = sameProcessCall && newConfig != null ? new Configuration(newConfig) : newConfig;
args.arg5 = sameProcessCall ? new Rect(overscanInsets) : overscanInsets;
args.arg6 = sameProcessCall ? new Rect(stableInsets) : stableInsets;
+ args.arg7 = sameProcessCall ? new Rect(outsets) : outsets;
msg.obj = args;
mHandler.sendMessage(msg);
}
@@ -6650,12 +6671,12 @@ public final class ViewRootImpl implements ViewParent,
@Override
public void resized(Rect frame, Rect overscanInsets, Rect contentInsets,
- Rect visibleInsets, Rect stableInsets, boolean reportDraw,
+ Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw,
Configuration newConfig) {
final ViewRootImpl viewAncestor = mViewAncestor.get();
if (viewAncestor != null) {
viewAncestor.dispatchResized(frame, overscanInsets, contentInsets,
- visibleInsets, stableInsets, reportDraw, newConfig);
+ visibleInsets, stableInsets, outsets, reportDraw, newConfig);
}
}
diff --git a/core/java/android/view/ViewStructure.java b/core/java/android/view/ViewStructure.java
index 5c8b023..886547a 100644
--- a/core/java/android/view/ViewStructure.java
+++ b/core/java/android/view/ViewStructure.java
@@ -145,13 +145,6 @@ public abstract class ViewStructure {
public abstract void setText(CharSequence text, int selectionStart, int selectionEnd);
/**
- * Set default global style of the text previously set with
- * {@link #setText}, derived from the given TextPaint object. Size, foreground color,
- * background color, and style information will be extracted from the paint.
- */
- public abstract void setTextPaint(TextPaint paint);
-
- /**
* Explicitly set default global style information for text that was previously set with
* {@link #setText}.
*
@@ -160,7 +153,7 @@ public abstract class ViewStructure {
* @param bgColor The background color, packed as 0xAARRGGBB.
* @param style Style flags, as defined by {@link android.app.AssistStructure.ViewNode}.
*/
- public abstract void setTextStyle(int size, int fgColor, int bgColor, int style);
+ public abstract void setTextStyle(float size, int fgColor, int bgColor, int style);
/**
* Set optional hint text associated with this view; this is for example the text that is
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index f0c86e5..45bc1df 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -309,6 +309,7 @@ public interface WindowManager extends ViewManager {
* Window type: a above sub-panel on top of an application window and it's
* sub-panel windows. These windows are displayed on top of their attached window
* and any {@link #TYPE_APPLICATION_SUB_PANEL} panels.
+ * @hide
*/
public static final int TYPE_APPLICATION_ABOVE_SUB_PANEL = FIRST_SUB_WINDOW + 5;
diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java
index c16578e..606168c 100644
--- a/core/java/android/view/WindowManagerGlobal.java
+++ b/core/java/android/view/WindowManagerGlobal.java
@@ -20,6 +20,7 @@ import android.animation.ValueAnimator;
import android.app.ActivityManager;
import android.content.ComponentCallbacks2;
import android.content.Context;
+import android.content.pm.ApplicationInfo;
import android.content.res.Configuration;
import android.os.IBinder;
import android.os.RemoteException;
@@ -247,7 +248,8 @@ public final class WindowManagerGlobal {
// set from the application's hardware acceleration setting.
final Context context = view.getContext();
if (context != null
- && context.getApplicationInfo().hardwareAccelerated) {
+ && (context.getApplicationInfo().flags
+ & ApplicationInfo.FLAG_HARDWARE_ACCELERATED) != 0) {
wparams.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
}
}
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index eebcd84..f7b6405 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -158,10 +158,12 @@ public interface WindowManagerPolicy {
* @param decorFrame The decor frame specified by policy specific to this window,
* to use for proper cropping during animation.
* @param stableFrame The frame around which stable system decoration is positioned.
+ * @param outsetFrame The frame that includes areas that aren't part of the surface but we
+ * want to treat them as such.
*/
public void computeFrameLw(Rect parentFrame, Rect displayFrame,
Rect overlayFrame, Rect contentFrame, Rect visibleFrame, Rect decorFrame,
- Rect stableFrame);
+ Rect stableFrame, Rect outsetFrame);
/**
* Retrieve the current frame of the window that has been assigned by
@@ -945,17 +947,30 @@ public interface WindowManagerPolicy {
public int focusChangedLw(WindowState lastFocus, WindowState newFocus);
/**
- * Called when the device is waking up.
+ * Called when the device has started waking up.
*/
- public void wakingUp();
+ public void startedWakingUp();
/**
- * Called when the device is going to sleep.
+ * Called when the device has finished waking up.
+ */
+ public void finishedWakingUp();
+
+ /**
+ * Called when the device has started going to sleep.
+ *
+ * @param why {@link #OFF_BECAUSE_OF_USER}, {@link #OFF_BECAUSE_OF_ADMIN},
+ * or {@link #OFF_BECAUSE_OF_TIMEOUT}.
+ */
+ public void startedGoingToSleep(int why);
+
+ /**
+ * Called when the device has finished going to sleep.
*
- * @param why {@link #OFF_BECAUSE_OF_USER} or
- * {@link #OFF_BECAUSE_OF_TIMEOUT}.
+ * @param why {@link #OFF_BECAUSE_OF_USER}, {@link #OFF_BECAUSE_OF_ADMIN},
+ * or {@link #OFF_BECAUSE_OF_TIMEOUT}.
*/
- public void goingToSleep(int why);
+ public void finishedGoingToSleep(int why);
/**
* Called when the device is about to turn on the screen to show content.
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index 901a32d..b454d1c 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -2737,10 +2737,10 @@ public class AccessibilityNodeInfo implements Parcelable {
if (mCollectionItemInfo != null) {
parcel.writeInt(1);
- parcel.writeInt(mCollectionItemInfo.getColumnIndex());
- parcel.writeInt(mCollectionItemInfo.getColumnSpan());
parcel.writeInt(mCollectionItemInfo.getRowIndex());
parcel.writeInt(mCollectionItemInfo.getRowSpan());
+ parcel.writeInt(mCollectionItemInfo.getColumnIndex());
+ parcel.writeInt(mCollectionItemInfo.getColumnSpan());
parcel.writeInt(mCollectionItemInfo.isHeading() ? 1 : 0);
parcel.writeInt(mCollectionItemInfo.isSelected() ? 1 : 0);
} else {
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index f61e372..5537b3e 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -1320,6 +1320,22 @@ public final class InputMethodManager {
}
}
+ /**
+ * Call this when a view is being detached from a {@link android.view.Window}.
+ * @hide
+ */
+ public void onViewDetachedFromWindow(View view) {
+ synchronized (mH) {
+ if (DEBUG) Log.v(TAG, "onViewDetachedFromWindow: " + view
+ + " mServedView=" + mServedView
+ + " hasWindowFocus=" + view.hasWindowFocus());
+ if (mServedView == view && view.hasWindowFocus()) {
+ mNextServedView = null;
+ scheduleCheckFocusLocked(view);
+ }
+ }
+ }
+
static void scheduleCheckFocusLocked(View view) {
ViewRootImpl viewRootImpl = view.getViewRootImpl();
if (viewRootImpl != null) {
diff --git a/core/java/android/webkit/ViewAssistStructure.java b/core/java/android/webkit/ViewAssistStructure.java
deleted file mode 100644
index bbaceee..0000000
--- a/core/java/android/webkit/ViewAssistStructure.java
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.webkit;
-
-import android.graphics.Rect;
-import android.os.Bundle;
-import android.text.TextPaint;
-import android.view.ViewStructure;
-
-
-/**
- * TODO This class is temporary. It will be deleted once we update Webview APK to use the
- * new ViewStructure method.
- * @hide
- */
-public class ViewAssistStructure extends android.view.ViewAssistStructure {
-
- private ViewStructure mV;
-
- public ViewAssistStructure(ViewStructure v) {
- mV = v;
- }
-
- @Override
- public void setId(int id, String packageName, String typeName, String entryName) {
- mV.setId(id, packageName, typeName, entryName);
- }
-
- @Override
- public void setDimens(int left, int top, int scrollX, int scrollY, int width,
- int height) {
- mV.setDimens(left, top, scrollX, scrollY, width, height);
- }
-
- @Override
- public void setVisibility(int visibility) {
- mV.setVisibility(visibility);
- }
-
- @Override
- public void setAssistBlocked(boolean state) {
- mV.setAssistBlocked(state);
- }
-
- @Override
- public void setEnabled(boolean state) {
- mV.setEnabled(state);
- }
-
- @Override
- public void setClickable(boolean state) {
- mV.setClickable(state);
- }
-
- @Override
- public void setLongClickable(boolean state) {
- mV.setLongClickable(state);
- }
-
- @Override
- public void setStylusButtonPressable(boolean state) {
- mV.setStylusButtonPressable(state);
- }
-
- @Override
- public void setFocusable(boolean state) {
- mV.setFocusable(state);
- }
-
- @Override
- public void setFocused(boolean state) {
- mV.setFocused(state);
- }
-
- @Override
- public void setAccessibilityFocused(boolean state) {
- mV.setAccessibilityFocused(state);
- }
-
- @Override
- public void setCheckable(boolean state) {
- mV.setCheckable(state);
- }
-
- @Override
- public void setChecked(boolean state) {
- mV.setChecked(state);
- }
-
- @Override
- public void setSelected(boolean state) {
- mV.setSelected(state);
- }
-
- @Override
- public void setActivated(boolean state) {
- mV.setActivated(state);
- }
-
- @Override
- public void setClassName(String className) {
- mV.setClassName(className);
- }
-
- @Override
- public void setContentDescription(CharSequence contentDescription) {
- mV.setContentDescription(contentDescription);
- }
-
- @Override
- public void setText(CharSequence text) {
- mV.setText(text);
- }
-
- @Override
- public void setText(CharSequence text, int selectionStart, int selectionEnd) {
- mV.setText(text, selectionStart, selectionEnd);
- }
-
- @Override
- public void setTextPaint(TextPaint paint) {
- mV.setTextPaint(paint);
- }
-
- @Override
- public void setTextStyle(int size, int fgColor, int bgColor, int style) {
- mV.setTextStyle(size, fgColor, bgColor, style);
- }
-
- @Override
- public void setHint(CharSequence hint) {
- mV.setHint(hint);
- }
-
- @Override
- public CharSequence getText() {
- return mV.getText();
- }
-
- @Override
- public int getTextSelectionStart() {
- return mV.getTextSelectionStart();
- }
-
- @Override
- public int getTextSelectionEnd() {
- return mV.getTextSelectionEnd();
- }
-
- @Override
- public CharSequence getHint() {
- return mV.getHint();
- }
-
- @Override
- public Bundle getExtras() {
- return mV.getExtras();
- }
-
- @Override
- public boolean hasExtras() {
- return mV.hasExtras();
- }
-
- @Override
- public void setChildCount(int num) {
- mV.setChildCount(num);
- }
-
- @Override
- public int getChildCount() {
- return mV.getChildCount();
- }
-
- @Override
- public android.view.ViewAssistStructure newChild(int index) {
- return mV.newChild(index);
- }
-
- @Override
- public android.view.ViewAssistStructure asyncNewChild(int index) {
- return mV.asyncNewChild(index);
- }
-
- @Override
- public void asyncCommit() {
- mV.asyncCommit();
- }
-
- @Override
- public Rect getTempRect() {
- return mV.getTempRect();
- }
-}
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index ccb98b4..5080fcc 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -2436,8 +2436,7 @@ public class WebView extends AbsoluteLayout
@Override
public void onProvideVirtualStructure(ViewStructure structure) {
- ViewAssistStructure s = new ViewAssistStructure(structure);
- mProvider.getViewDelegate().onProvideVirtualAssistStructure(s);
+ mProvider.getViewDelegate().onProvideVirtualStructure(structure);
}
/** @hide */
diff --git a/core/java/android/webkit/WebViewProvider.java b/core/java/android/webkit/WebViewProvider.java
index 00aba2a..09afcf1 100644
--- a/core/java/android/webkit/WebViewProvider.java
+++ b/core/java/android/webkit/WebViewProvider.java
@@ -298,7 +298,7 @@ public interface WebViewProvider {
interface ViewDelegate {
public boolean shouldDelayChildPressedState();
- public void onProvideVirtualAssistStructure(android.view.ViewAssistStructure structure);
+ public void onProvideVirtualStructure(android.view.ViewStructure structure);
public AccessibilityNodeProvider getAccessibilityNodeProvider();
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index e963f53..a3332fa 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -820,44 +820,36 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
mOwnerThread = Thread.currentThread();
final TypedArray a = context.obtainStyledAttributes(
- attrs, com.android.internal.R.styleable.AbsListView, defStyleAttr, defStyleRes);
+ attrs, R.styleable.AbsListView, defStyleAttr, defStyleRes);
- Drawable d = a.getDrawable(com.android.internal.R.styleable.AbsListView_listSelector);
- if (d != null) {
- setSelector(d);
- }
-
- mDrawSelectorOnTop = a.getBoolean(
- com.android.internal.R.styleable.AbsListView_drawSelectorOnTop, false);
-
- boolean stackFromBottom = a.getBoolean(R.styleable.AbsListView_stackFromBottom, false);
- setStackFromBottom(stackFromBottom);
-
- boolean scrollingCacheEnabled = a.getBoolean(R.styleable.AbsListView_scrollingCache, true);
- setScrollingCacheEnabled(scrollingCacheEnabled);
-
- boolean useTextFilter = a.getBoolean(R.styleable.AbsListView_textFilterEnabled, false);
- setTextFilterEnabled(useTextFilter);
-
- int transcriptMode = a.getInt(R.styleable.AbsListView_transcriptMode,
- TRANSCRIPT_MODE_DISABLED);
- setTranscriptMode(transcriptMode);
-
- int color = a.getColor(R.styleable.AbsListView_cacheColorHint, 0);
- setCacheColorHint(color);
-
- boolean enableFastScroll = a.getBoolean(R.styleable.AbsListView_fastScrollEnabled, false);
- setFastScrollEnabled(enableFastScroll);
-
- int fastScrollStyle = a.getResourceId(R.styleable.AbsListView_fastScrollStyle, 0);
- setFastScrollStyle(fastScrollStyle);
-
- boolean smoothScrollbar = a.getBoolean(R.styleable.AbsListView_smoothScrollbar, true);
- setSmoothScrollbarEnabled(smoothScrollbar);
-
- setChoiceMode(a.getInt(R.styleable.AbsListView_choiceMode, CHOICE_MODE_NONE));
- setFastScrollAlwaysVisible(
- a.getBoolean(R.styleable.AbsListView_fastScrollAlwaysVisible, false));
+ final Drawable selector = a.getDrawable(R.styleable.AbsListView_listSelector);
+ if (selector != null) {
+ setSelector(selector);
+ }
+
+ mDrawSelectorOnTop = a.getBoolean(R.styleable.AbsListView_drawSelectorOnTop, false);
+
+ setStackFromBottom(a.getBoolean(
+ R.styleable.AbsListView_stackFromBottom, false));
+ setScrollingCacheEnabled(a.getBoolean(
+ R.styleable.AbsListView_scrollingCache, true));
+ setTextFilterEnabled(a.getBoolean(
+ R.styleable.AbsListView_textFilterEnabled, false));
+ setTranscriptMode(a.getInt(
+ R.styleable.AbsListView_transcriptMode, TRANSCRIPT_MODE_DISABLED));
+ setCacheColorHint(a.getColor(
+ R.styleable.AbsListView_cacheColorHint, 0));
+ setSmoothScrollbarEnabled(a.getBoolean(
+ R.styleable.AbsListView_smoothScrollbar, true));
+ setChoiceMode(a.getInt(
+ R.styleable.AbsListView_choiceMode, CHOICE_MODE_NONE));
+
+ setFastScrollEnabled(a.getBoolean(
+ R.styleable.AbsListView_fastScrollEnabled, false));
+ setFastScrollStyle(a.getResourceId(
+ R.styleable.AbsListView_fastScrollStyle, 0));
+ setFastScrollAlwaysVisible(a.getBoolean(
+ R.styleable.AbsListView_fastScrollAlwaysVisible, false));
a.recycle();
}
diff --git a/core/java/android/widget/AbsSeekBar.java b/core/java/android/widget/AbsSeekBar.java
index ff74c60..a4c8d1c 100644
--- a/core/java/android/widget/AbsSeekBar.java
+++ b/core/java/android/widget/AbsSeekBar.java
@@ -86,10 +86,10 @@ public abstract class AbsSeekBar extends ProgressBar {
public AbsSeekBar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
- TypedArray a = context.obtainStyledAttributes(
- attrs, com.android.internal.R.styleable.SeekBar, defStyleAttr, defStyleRes);
+ final TypedArray a = context.obtainStyledAttributes(
+ attrs, R.styleable.SeekBar, defStyleAttr, defStyleRes);
- final Drawable thumb = a.getDrawable(com.android.internal.R.styleable.SeekBar_thumb);
+ final Drawable thumb = a.getDrawable(R.styleable.SeekBar_thumb);
setThumb(thumb);
if (a.hasValue(R.styleable.SeekBar_thumbTintMode)) {
@@ -103,18 +103,22 @@ public abstract class AbsSeekBar extends ProgressBar {
mHasThumbTint = true;
}
+ mSplitTrack = a.getBoolean(R.styleable.SeekBar_splitTrack, false);
+
// Guess thumb offset if thumb != null, but allow layout to override.
- final int thumbOffset = a.getDimensionPixelOffset(
- com.android.internal.R.styleable.SeekBar_thumbOffset, getThumbOffset());
+ final int thumbOffset = a.getDimensionPixelOffset(R.styleable.SeekBar_thumbOffset, getThumbOffset());
setThumbOffset(thumbOffset);
- mSplitTrack = a.getBoolean(com.android.internal.R.styleable.SeekBar_splitTrack, false);
+ final boolean useDisabledAlpha = a.getBoolean(R.styleable.SeekBar_useDisabledAlpha, true);
a.recycle();
- a = context.obtainStyledAttributes(attrs,
- com.android.internal.R.styleable.Theme, 0, 0);
- mDisabledAlpha = a.getFloat(com.android.internal.R.styleable.Theme_disabledAlpha, 0.5f);
- a.recycle();
+ if (useDisabledAlpha) {
+ final TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.Theme, 0, 0);
+ mDisabledAlpha = ta.getFloat(R.styleable.Theme_disabledAlpha, 0.5f);
+ ta.recycle();
+ } else {
+ mDisabledAlpha = 1.0f;
+ }
applyThumbTint();
@@ -360,7 +364,7 @@ public abstract class AbsSeekBar extends ProgressBar {
super.drawableStateChanged();
final Drawable progressDrawable = getProgressDrawable();
- if (progressDrawable != null) {
+ if (progressDrawable != null && mDisabledAlpha < 1.0f) {
progressDrawable.setAlpha(isEnabled() ? NO_ALPHA : (int) (NO_ALPHA * mDisabledAlpha));
}
diff --git a/core/java/android/widget/AdapterView.java b/core/java/android/widget/AdapterView.java
index 54e3996..6962711 100644
--- a/core/java/android/widget/AdapterView.java
+++ b/core/java/android/widget/AdapterView.java
@@ -304,16 +304,19 @@ public abstract class AdapterView<T extends Adapter> extends ViewGroup {
* called, false otherwise is returned.
*/
public boolean performItemClick(View view, int position, long id) {
+ final boolean result;
if (mOnItemClickListener != null) {
playSoundEffect(SoundEffectConstants.CLICK);
mOnItemClickListener.onItemClick(this, view, position, id);
- if (view != null) {
- view.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
- }
- return true;
+ result = true;
+ } else {
+ result = false;
}
- return false;
+ if (view != null) {
+ view.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
+ }
+ return result;
}
/**
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index fc84cf9..0cac529 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -390,6 +390,7 @@ public class Editor {
mPreserveDetachedSelection = true;
hideControllers();
+ stopSelectionActionMode();
mPreserveDetachedSelection = false;
mTemporaryDetach = false;
}
@@ -624,7 +625,6 @@ public class Editor {
mSuggestionsPopupWindow.hide();
}
hideInsertionPointCursorController();
- stopSelectionActionMode();
}
/**
@@ -1101,10 +1101,12 @@ public class Editor {
final int selStart = mTextView.getSelectionStart();
final int selEnd = mTextView.getSelectionEnd();
hideControllers();
+ stopSelectionActionMode();
Selection.setSelection((Spannable) mTextView.getText(), selStart, selEnd);
} else {
if (mTemporaryDetach) mPreserveDetachedSelection = true;
hideControllers();
+ stopSelectionActionMode();
if (mTemporaryDetach) mPreserveDetachedSelection = false;
downgradeEasyCorrectionSpans();
}
@@ -1147,6 +1149,7 @@ public class Editor {
// We do not hide the span controllers, since they can be added when a new text is
// inserted into the text view (voice IME).
hideCursorControllers();
+ stopSelectionActionMode();
}
private int getLastTapPosition() {
@@ -1878,6 +1881,7 @@ public class Editor {
void onTouchUpEvent(MotionEvent event) {
boolean selectAllGotFocus = mSelectAllOnFocus && mTextView.didTouchFocusSelect();
hideControllers();
+ stopSelectionActionMode();
CharSequence text = mTextView.getText();
if (!selectAllGotFocus && text.length() > 0) {
// Move cursor
@@ -1890,6 +1894,11 @@ public class Editor {
if (!extractedTextModeWillBeStarted()) {
if (isCursorInsideEasyCorrectionSpan()) {
+ // Cancel the single tap delayed runnable.
+ if (mSelectionModeWithoutSelectionRunnable != null) {
+ mTextView.removeCallbacks(mSelectionModeWithoutSelectionRunnable);
+ }
+
mShowSuggestionRunnable = new Runnable() {
public void run() {
showSuggestions();
@@ -1993,6 +2002,7 @@ public class Editor {
mSuggestionsPopupWindow = new SuggestionsPopupWindow();
}
hideControllers();
+ stopSelectionActionMode();
mSuggestionsPopupWindow.show();
}
@@ -3110,35 +3120,30 @@ public class Editor {
if (mTextView.canCut()) {
menu.add(0, TextView.ID_CUT, 0, com.android.internal.R.string.cut).
setAlphabeticShortcut('x').
- setShowAsAction(
- MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
+ setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
}
if (mTextView.canCopy()) {
menu.add(0, TextView.ID_COPY, 0, com.android.internal.R.string.copy).
setAlphabeticShortcut('c').
- setShowAsAction(
- MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
+ setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
}
if (mTextView.canPaste()) {
menu.add(0, TextView.ID_PASTE, 0, com.android.internal.R.string.paste).
setAlphabeticShortcut('v').
- setShowAsAction(
- MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
+ setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
}
if (mTextView.canShare()) {
menu.add(0, TextView.ID_SHARE, 0, com.android.internal.R.string.share).
- setShowAsAction(
- MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
+ setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
}
if (mTextView.canSelectAllText()) {
menu.add(0, TextView.ID_SELECT_ALL, 0, com.android.internal.R.string.selectAll).
setAlphabeticShortcut('a').
- setShowAsAction(
- MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
+ setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
}
updateReplaceItem(menu);
@@ -3152,8 +3157,7 @@ public class Editor {
for (ResolveInfo info : supportedActivities) {
menu.add(info.loadLabel(packageManager))
.setIntent(createProcessTextIntentForResolveInfo(info))
- .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM
- | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
+ .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
}
}
}
@@ -3185,8 +3189,7 @@ public class Editor {
boolean replaceItemExists = menu.findItem(TextView.ID_REPLACE) != null;
if (canReplace && !replaceItemExists) {
menu.add(0, TextView.ID_REPLACE, 0, com.android.internal.R.string.replace).
- setShowAsAction(
- MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
+ setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
} else if (!canReplace && replaceItemExists) {
menu.removeItem(TextView.ID_REPLACE);
}
@@ -3819,13 +3822,15 @@ public class Editor {
SystemClock.uptimeMillis() - TextView.sLastCutCopyOrTextChangedTime;
// Cancel the single tap delayed runnable.
- if (mDoubleTap && mSelectionModeWithoutSelectionRunnable != null) {
+ if (mSelectionModeWithoutSelectionRunnable != null
+ && (mDoubleTap || isCursorInsideEasyCorrectionSpan())) {
mTextView.removeCallbacks(mSelectionModeWithoutSelectionRunnable);
}
// Prepare and schedule the single tap runnable to run exactly after the double tap
// timeout has passed.
- if (!mDoubleTap && (durationSinceCutOrCopy < RECENT_CUT_COPY_DURATION)) {
+ if (!mDoubleTap && !isCursorInsideEasyCorrectionSpan()
+ && (durationSinceCutOrCopy < RECENT_CUT_COPY_DURATION)) {
if (mSelectionModeWithoutSelectionRunnable == null) {
mSelectionModeWithoutSelectionRunnable = new Runnable() {
public void run() {
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index 7dcaa1f..f8b965f 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -16,6 +16,7 @@
package android.widget;
+import android.annotation.Nullable;
import android.os.Bundle;
import android.os.Trace;
import com.android.internal.R;
@@ -144,7 +145,7 @@ public class ListView extends AbsListView {
}
public ListView(Context context, AttributeSet attrs) {
- this(context, attrs, com.android.internal.R.attr.listViewStyle);
+ this(context, attrs, R.attr.listViewStyle);
}
public ListView(Context context, AttributeSet attrs, int defStyleAttr) {
@@ -155,38 +156,37 @@ public class ListView extends AbsListView {
super(context, attrs, defStyleAttr, defStyleRes);
final TypedArray a = context.obtainStyledAttributes(
- attrs, com.android.internal.R.styleable.ListView, defStyleAttr, defStyleRes);
+ attrs, R.styleable.ListView, defStyleAttr, defStyleRes);
- CharSequence[] entries = a.getTextArray(
- com.android.internal.R.styleable.ListView_entries);
+ final CharSequence[] entries = a.getTextArray(R.styleable.ListView_entries);
if (entries != null) {
- setAdapter(new ArrayAdapter<CharSequence>(context,
- com.android.internal.R.layout.simple_list_item_1, entries));
+ setAdapter(new ArrayAdapter<>(context, R.layout.simple_list_item_1, entries));
}
- final Drawable d = a.getDrawable(com.android.internal.R.styleable.ListView_divider);
+ final Drawable d = a.getDrawable(R.styleable.ListView_divider);
if (d != null) {
- // If a divider is specified use its intrinsic height for divider height
+ // Use an implicit divider height which may be explicitly
+ // overridden by android:dividerHeight further down.
setDivider(d);
}
-
- final Drawable osHeader = a.getDrawable(
- com.android.internal.R.styleable.ListView_overScrollHeader);
+
+ final Drawable osHeader = a.getDrawable(R.styleable.ListView_overScrollHeader);
if (osHeader != null) {
setOverscrollHeader(osHeader);
}
- final Drawable osFooter = a.getDrawable(
- com.android.internal.R.styleable.ListView_overScrollFooter);
+ final Drawable osFooter = a.getDrawable(R.styleable.ListView_overScrollFooter);
if (osFooter != null) {
setOverscrollFooter(osFooter);
}
- // Use the height specified, zero being the default
- final int dividerHeight = a.getDimensionPixelSize(
- com.android.internal.R.styleable.ListView_dividerHeight, 0);
- if (dividerHeight != 0) {
- setDividerHeight(dividerHeight);
+ // Use an explicit divider height, if specified.
+ if (a.hasValueOrEmpty(R.styleable.ListView_dividerHeight)) {
+ final int dividerHeight = a.getDimensionPixelSize(
+ R.styleable.ListView_dividerHeight, 0);
+ if (dividerHeight != 0) {
+ setDividerHeight(dividerHeight);
+ }
}
mHeaderDividersEnabled = a.getBoolean(R.styleable.ListView_headerDividersEnabled, true);
@@ -3434,18 +3434,23 @@ public class ListView extends AbsListView {
* Returns the drawable that will be drawn between each item in the list.
*
* @return the current drawable drawn between list elements
+ * @attr ref R.styleable#ListView_divider
*/
+ @Nullable
public Drawable getDivider() {
return mDivider;
}
/**
- * Sets the drawable that will be drawn between each item in the list. If the drawable does
- * not have an intrinsic height, you should also call {@link #setDividerHeight(int)}
+ * Sets the drawable that will be drawn between each item in the list.
+ * <p>
+ * <strong>Note:</strong> If the drawable does not have an intrinsic
+ * height, you should also call {@link #setDividerHeight(int)}.
*
- * @param divider The drawable to use.
+ * @param divider the drawable to use
+ * @attr ref R.styleable#ListView_divider
*/
- public void setDivider(Drawable divider) {
+ public void setDivider(@Nullable Drawable divider) {
if (divider != null) {
mDividerHeight = divider.getIntrinsicHeight();
} else {
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index dc75fd0..74843ee 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -867,13 +867,13 @@ public class RemoteViews implements Parcelable, Filter {
if (targetDrawable != null) {
// Perform modifications only if values are set correctly
if (alpha != -1) {
- targetDrawable.setAlpha(alpha);
+ targetDrawable.mutate().setAlpha(alpha);
}
if (filterMode != null) {
- targetDrawable.setColorFilter(colorFilter, filterMode);
+ targetDrawable.mutate().setColorFilter(colorFilter, filterMode);
}
if (level != -1) {
- targetDrawable.setLevel(level);
+ targetDrawable.mutate().setLevel(level);
}
}
}
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index 2709f25..ca57d1a 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -1704,12 +1704,26 @@ public class ScrollView extends FrameLayout {
super.draw(canvas);
if (mEdgeGlowTop != null) {
final int scrollY = mScrollY;
+ final boolean clipToPadding = getClipToPadding();
if (!mEdgeGlowTop.isFinished()) {
final int restoreCount = canvas.save();
- final int width = getWidth() - mPaddingLeft - mPaddingRight;
-
- canvas.translate(mPaddingLeft, Math.min(0, scrollY));
- mEdgeGlowTop.setSize(width, getHeight());
+ final int width;
+ final int height;
+ final float translateX;
+ final float translateY;
+ if (clipToPadding) {
+ width = getWidth() - mPaddingLeft - mPaddingRight;
+ height = getHeight() - mPaddingTop - mPaddingBottom;
+ translateX = mPaddingLeft;
+ translateY = mPaddingTop;
+ } else {
+ width = getWidth();
+ height = getHeight();
+ translateX = 0;
+ translateY = 0;
+ }
+ canvas.translate(translateX, Math.min(0, scrollY) + translateY);
+ mEdgeGlowTop.setSize(width, height);
if (mEdgeGlowTop.draw(canvas)) {
postInvalidateOnAnimation();
}
@@ -1717,11 +1731,23 @@ public class ScrollView extends FrameLayout {
}
if (!mEdgeGlowBottom.isFinished()) {
final int restoreCount = canvas.save();
- final int width = getWidth() - mPaddingLeft - mPaddingRight;
- final int height = getHeight();
-
- canvas.translate(-width + mPaddingLeft,
- Math.max(getScrollRange(), scrollY) + height);
+ final int width;
+ final int height;
+ final float translateX;
+ final float translateY;
+ if (clipToPadding) {
+ width = getWidth() - mPaddingLeft - mPaddingRight;
+ height = getHeight() - mPaddingTop - mPaddingBottom;
+ translateX = mPaddingLeft;
+ translateY = mPaddingTop;
+ } else {
+ width = getWidth();
+ height = getHeight();
+ translateX = 0;
+ translateY = 0;
+ }
+ canvas.translate(-width + translateX,
+ Math.max(getScrollRange(), scrollY) + height + translateY);
canvas.rotate(180, width, 0);
mEdgeGlowBottom.setSize(width, height);
if (mEdgeGlowBottom.draw(canvas)) {
diff --git a/core/java/android/widget/Switch.java b/core/java/android/widget/Switch.java
index f42959f..49226cd 100644
--- a/core/java/android/widget/Switch.java
+++ b/core/java/android/widget/Switch.java
@@ -1374,7 +1374,9 @@ public class Switch extends CompoundButton {
newText.append(oldText).append(' ').append(switchText);
structure.setText(newText);
}
- structure.setTextPaint(mTextPaint);
+ // The style of the label text is provided via the base TextView class. This is more
+ // relevant than the style of the (optional) on/off text on the switch button itself,
+ // so ignore the size/color/style stored this.mTextPaint.
}
}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index a93e7ef..e14e39c 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -25,6 +25,7 @@ import android.annotation.StringRes;
import android.annotation.StyleRes;
import android.annotation.XmlRes;
import android.app.Activity;
+import android.app.AssistStructure;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
@@ -6422,6 +6423,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
// extracted mode will start. Some text is selected though, and will trigger an action mode
// in the extracted view.
mEditor.hideControllers();
+ stopSelectionActionMode();
}
/**
@@ -8015,8 +8017,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* through a thunk.
*/
void sendAfterTextChanged(Editable text) {
- sLastCutCopyOrTextChangedTime = 0;
-
if (mListeners != null) {
final ArrayList<TextWatcher> list = mListeners;
final int count = list.size();
@@ -8049,6 +8049,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* through a thunk.
*/
void handleTextChanged(CharSequence buffer, int start, int before, int after) {
+ sLastCutCopyOrTextChangedTime = 0;
+
final Editor.InputMethodState ims = mEditor == null ? null : mEditor.mInputMethodState;
if (ims == null || ims.mBatchEditNesting == 0) {
updateAfterEdit();
@@ -8256,6 +8258,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
super.onVisibilityChanged(changedView, visibility);
if (mEditor != null && visibility != VISIBLE) {
mEditor.hideControllers();
+ stopSelectionActionMode();
}
}
@@ -8785,7 +8788,33 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
final boolean isPassword = hasPasswordTransformationMethod();
if (!isPassword) {
structure.setText(getText(), getSelectionStart(), getSelectionEnd());
- structure.setTextPaint(mTextPaint);
+
+ // Extract style information that applies to the TextView as a whole.
+ int style = 0;
+ int typefaceStyle = getTypefaceStyle();
+ if ((typefaceStyle & Typeface.BOLD) != 0) {
+ style |= AssistStructure.ViewNode.TEXT_STYLE_BOLD;
+ }
+ if ((typefaceStyle & Typeface.ITALIC) != 0) {
+ style |= AssistStructure.ViewNode.TEXT_STYLE_ITALIC;
+ }
+
+ // Global styles can also be set via TextView.setPaintFlags().
+ int paintFlags = mTextPaint.getFlags();
+ if ((paintFlags & Paint.FAKE_BOLD_TEXT_FLAG) != 0) {
+ style |= AssistStructure.ViewNode.TEXT_STYLE_BOLD;
+ }
+ if ((paintFlags & Paint.UNDERLINE_TEXT_FLAG) != 0) {
+ style |= AssistStructure.ViewNode.TEXT_STYLE_UNDERLINE;
+ }
+ if ((paintFlags & Paint.STRIKE_THRU_TEXT_FLAG) != 0) {
+ style |= AssistStructure.ViewNode.TEXT_STYLE_STRIKE_THRU;
+ }
+
+ // TextView does not have its own text background color. A background is either part
+ // of the View (and can be any drawable) or a BackgroundColorSpan inside the text.
+ structure.setTextStyle(getTextSize(), getCurrentTextColor(),
+ AssistStructure.ViewNode.TEXT_COLOR_UNDEFINED /* bgColor */, style);
}
structure.setHint(getHint());
}
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index ea18c12..c1ec6e6 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -659,11 +659,16 @@ public class ChooserActivity extends ResolverActivity {
return super.getCount() + mServiceTargets.size() + mCallerTargets.size();
}
- public int getCallerTargetsCount() {
+ @Override
+ public int getUnfilteredCount() {
+ return super.getUnfilteredCount() + mServiceTargets.size() + mCallerTargets.size();
+ }
+
+ public int getCallerTargetCount() {
return mCallerTargets.size();
}
- public int getServiceTargetsCount() {
+ public int getServiceTargetCount() {
return mServiceTargets.size();
}
@@ -696,6 +701,11 @@ public class ChooserActivity extends ResolverActivity {
@Override
public TargetInfo getItem(int position) {
+ return targetInfoForPosition(position, true);
+ }
+
+ @Override
+ public TargetInfo targetInfoForPosition(int position, boolean filtered) {
int offset = 0;
final int callerTargetCount = mCallerTargets.size();
@@ -710,7 +720,8 @@ public class ChooserActivity extends ResolverActivity {
}
offset += serviceTargetCount;
- return super.getItem(position - offset);
+ return filtered ? super.getItem(position - offset)
+ : getDisplayInfoAt(position - offset);
}
public void addServiceResults(DisplayResolveInfo origTarget, List<ChooserTarget> targets) {
@@ -764,8 +775,8 @@ public class ChooserActivity extends ResolverActivity {
@Override
public int getCount() {
return (int) (
- Math.ceil((float) mChooserListAdapter.getCallerTargetsCount() / mColumnCount)
- + Math.ceil((float) mChooserListAdapter.getServiceTargetsCount() / mColumnCount)
+ Math.ceil((float) mChooserListAdapter.getCallerTargetCount() / mColumnCount)
+ + Math.ceil((float) mChooserListAdapter.getServiceTargetCount() / mColumnCount)
+ Math.ceil((float) mChooserListAdapter.getStandardTargetCount() / mColumnCount)
);
}
@@ -845,14 +856,14 @@ public class ChooserActivity extends ResolverActivity {
}
int getFirstRowPosition(int row) {
- final int callerCount = mChooserListAdapter.getCallerTargetsCount();
+ final int callerCount = mChooserListAdapter.getCallerTargetCount();
final int callerRows = (int) Math.ceil((float) callerCount / mColumnCount);
if (row < callerRows) {
return row * mColumnCount;
}
- final int serviceCount = mChooserListAdapter.getServiceTargetsCount();
+ final int serviceCount = mChooserListAdapter.getServiceTargetCount();
final int serviceRows = (int) Math.ceil((float) serviceCount / mColumnCount);
if (row < callerRows + serviceRows) {
diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl
index 7c5c565..929cacd 100644
--- a/core/java/com/android/internal/app/IBatteryStats.aidl
+++ b/core/java/com/android/internal/app/IBatteryStats.aidl
@@ -34,6 +34,12 @@ interface IBatteryStats {
void noteStopAudio(int uid);
void noteResetVideo();
void noteResetAudio();
+ void noteFlashlightOn(int uid);
+ void noteFlashlightOff(int uid);
+ void noteStartCamera(int uid);
+ void noteStopCamera(int uid);
+ void noteResetCamera();
+ void noteResetFlashlight();
// Remaining methods are only used in Java.
byte[] getStatistics();
@@ -72,8 +78,6 @@ interface IBatteryStats {
void noteVibratorOn(int uid, long durationMillis);
void noteVibratorOff(int uid);
- void noteFlashlightOn();
- void noteFlashlightOff();
void noteStartGps(int uid);
void noteStopGps(int uid);
void noteScreenState(int state);
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 4696757..ba4af89 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -785,7 +785,7 @@ public class ResolverActivity extends Activity {
}
mAlwaysUseOption = alwaysUseOption;
- int count = mAdapter.mDisplayList.size();
+ int count = mAdapter.getUnfilteredCount();
if (count > 1 || (count == 1 && mAdapter.getOtherProfile() != null)) {
setContentView(layoutId);
mAdapterView = (AbsListView) findViewById(R.id.resolver_list);
@@ -1392,6 +1392,18 @@ public class ResolverActivity extends Activity {
return result;
}
+ public int getUnfilteredCount() {
+ return mDisplayList.size();
+ }
+
+ public int getDisplayInfoCount() {
+ return mDisplayList.size();
+ }
+
+ public DisplayResolveInfo getDisplayInfoAt(int index) {
+ return mDisplayList.get(index);
+ }
+
public TargetInfo getItem(int position) {
if (mFilterLastUsed && mLastChosenPosition >= 0 && position >= mLastChosenPosition) {
position++;
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index eaca43b..62745d4 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -211,6 +211,8 @@ public final class BatteryStatsImpl extends BatteryStats {
final SparseArray<ArrayList<StopwatchTimer>> mWifiBatchedScanTimers = new SparseArray<>();
final ArrayList<StopwatchTimer> mAudioTurnedOnTimers = new ArrayList<>();
final ArrayList<StopwatchTimer> mVideoTurnedOnTimers = new ArrayList<>();
+ final ArrayList<StopwatchTimer> mFlashlightTurnedOnTimers = new ArrayList<>();
+ final ArrayList<StopwatchTimer> mCameraTurnedOnTimers = new ArrayList<>();
// Last partial timers we use for distributing CPU usage.
final ArrayList<StopwatchTimer> mLastPartialTimers = new ArrayList<>();
@@ -343,9 +345,12 @@ public final class BatteryStatsImpl extends BatteryStats {
int mVideoOnNesting;
StopwatchTimer mVideoOnTimer;
- boolean mFlashlightOn;
+ int mFlashlightOnNesting;
StopwatchTimer mFlashlightOnTimer;
+ int mCameraOnNesting;
+ StopwatchTimer mCameraOnTimer;
+
int mPhoneSignalStrengthBin = -1;
int mPhoneSignalStrengthBinRaw = -1;
final StopwatchTimer[] mPhoneSignalStrengthsTimer =
@@ -3710,30 +3715,100 @@ public final class BatteryStatsImpl extends BatteryStats {
getUidStatsLocked(uid).noteVibratorOffLocked();
}
- public void noteFlashlightOnLocked() {
- if (!mFlashlightOn) {
- final long elapsedRealtime = SystemClock.elapsedRealtime();
- final long uptime = SystemClock.uptimeMillis();
+ public void noteFlashlightOnLocked(int uid) {
+ uid = mapUid(uid);
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ if (mFlashlightOnNesting++ == 0) {
mHistoryCur.states2 |= HistoryItem.STATE2_FLASHLIGHT_FLAG;
if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight on to: "
- + Integer.toHexString(mHistoryCur.states));
+ + Integer.toHexString(mHistoryCur.states2));
addHistoryRecordLocked(elapsedRealtime, uptime);
- mFlashlightOn = true;
mFlashlightOnTimer.startRunningLocked(elapsedRealtime);
}
+ getUidStatsLocked(uid).noteFlashlightTurnedOnLocked(elapsedRealtime);
}
- public void noteFlashlightOffLocked() {
+ public void noteFlashlightOffLocked(int uid) {
+ if (mFlashlightOnNesting == 0) {
+ return;
+ }
+ uid = mapUid(uid);
final long elapsedRealtime = SystemClock.elapsedRealtime();
final long uptime = SystemClock.uptimeMillis();
- if (mFlashlightOn) {
+ if (--mFlashlightOnNesting == 0) {
mHistoryCur.states2 &= ~HistoryItem.STATE2_FLASHLIGHT_FLAG;
if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight off to: "
- + Integer.toHexString(mHistoryCur.states));
+ + Integer.toHexString(mHistoryCur.states2));
addHistoryRecordLocked(elapsedRealtime, uptime);
- mFlashlightOn = false;
mFlashlightOnTimer.stopRunningLocked(elapsedRealtime);
}
+ getUidStatsLocked(uid).noteFlashlightTurnedOffLocked(elapsedRealtime);
+ }
+
+ public void noteCameraOnLocked(int uid) {
+ uid = mapUid(uid);
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ if (mCameraOnNesting++ == 0) {
+ mHistoryCur.states2 |= HistoryItem.STATE2_CAMERA_FLAG;
+ if (DEBUG_HISTORY) Slog.v(TAG, "Camera on to: "
+ + Integer.toHexString(mHistoryCur.states2));
+ addHistoryRecordLocked(elapsedRealtime, uptime);
+ mCameraOnTimer.startRunningLocked(elapsedRealtime);
+ }
+ getUidStatsLocked(uid).noteCameraTurnedOnLocked(elapsedRealtime);
+ }
+
+ public void noteCameraOffLocked(int uid) {
+ if (mCameraOnNesting == 0) {
+ return;
+ }
+ uid = mapUid(uid);
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ if (--mCameraOnNesting == 0) {
+ mHistoryCur.states2 &= ~HistoryItem.STATE2_CAMERA_FLAG;
+ if (DEBUG_HISTORY) Slog.v(TAG, "Camera off to: "
+ + Integer.toHexString(mHistoryCur.states2));
+ addHistoryRecordLocked(elapsedRealtime, uptime);
+ mCameraOnTimer.stopRunningLocked(elapsedRealtime);
+ }
+ getUidStatsLocked(uid).noteCameraTurnedOffLocked(elapsedRealtime);
+ }
+
+ public void noteResetCameraLocked() {
+ if (mCameraOnNesting > 0) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mCameraOnNesting = 0;
+ mHistoryCur.states2 &= ~HistoryItem.STATE2_CAMERA_FLAG;
+ if (DEBUG_HISTORY) Slog.v(TAG, "Camera off to: "
+ + Integer.toHexString(mHistoryCur.states2));
+ addHistoryRecordLocked(elapsedRealtime, uptime);
+ mCameraOnTimer.stopAllRunningLocked(elapsedRealtime);
+ for (int i=0; i<mUidStats.size(); i++) {
+ BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
+ uid.noteResetCameraLocked(elapsedRealtime);
+ }
+ }
+ }
+
+ public void noteResetFlashlightLocked() {
+ if (mFlashlightOnNesting > 0) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mFlashlightOnNesting = 0;
+ mHistoryCur.states2 &= ~HistoryItem.STATE2_FLASHLIGHT_FLAG;
+ if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight off to: "
+ + Integer.toHexString(mHistoryCur.states2));
+ addHistoryRecordLocked(elapsedRealtime, uptime);
+ mFlashlightOnTimer.stopAllRunningLocked(elapsedRealtime);
+ for (int i=0; i<mUidStats.size(); i++) {
+ BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
+ uid.noteResetFlashlightLocked(elapsedRealtime);
+ }
+ }
}
public void noteWifiRadioPowerState(int powerState, long timestampNs) {
@@ -4350,6 +4425,9 @@ public final class BatteryStatsImpl extends BatteryStats {
StopwatchTimer mAudioTurnedOnTimer;
StopwatchTimer mVideoTurnedOnTimer;
+ StopwatchTimer mFlashlightTurnedOnTimer;
+ StopwatchTimer mCameraTurnedOnTimer;
+
StopwatchTimer mForegroundActivityTimer;
@@ -4650,6 +4728,54 @@ public final class BatteryStatsImpl extends BatteryStats {
}
}
+ public StopwatchTimer createFlashlightTurnedOnTimerLocked() {
+ if (mFlashlightTurnedOnTimer == null) {
+ mFlashlightTurnedOnTimer = new StopwatchTimer(Uid.this, FLASHLIGHT_TURNED_ON,
+ mFlashlightTurnedOnTimers, mOnBatteryTimeBase);
+ }
+ return mFlashlightTurnedOnTimer;
+ }
+
+ public void noteFlashlightTurnedOnLocked(long elapsedRealtimeMs) {
+ createFlashlightTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs);
+ }
+
+ public void noteFlashlightTurnedOffLocked(long elapsedRealtimeMs) {
+ if (mFlashlightTurnedOnTimer != null) {
+ mFlashlightTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs);
+ }
+ }
+
+ public void noteResetFlashlightLocked(long elapsedRealtimeMs) {
+ if (mFlashlightTurnedOnTimer != null) {
+ mFlashlightTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs);
+ }
+ }
+
+ public StopwatchTimer createCameraTurnedOnTimerLocked() {
+ if (mCameraTurnedOnTimer == null) {
+ mCameraTurnedOnTimer = new StopwatchTimer(Uid.this, CAMERA_TURNED_ON,
+ mCameraTurnedOnTimers, mOnBatteryTimeBase);
+ }
+ return mCameraTurnedOnTimer;
+ }
+
+ public void noteCameraTurnedOnLocked(long elapsedRealtimeMs) {
+ createCameraTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs);
+ }
+
+ public void noteCameraTurnedOffLocked(long elapsedRealtimeMs) {
+ if (mCameraTurnedOnTimer != null) {
+ mCameraTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs);
+ }
+ }
+
+ public void noteResetCameraLocked(long elapsedRealtimeMs) {
+ if (mCameraTurnedOnTimer != null) {
+ mCameraTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs);
+ }
+ }
+
public StopwatchTimer createForegroundActivityTimerLocked() {
if (mForegroundActivityTimer == null) {
mForegroundActivityTimer = new StopwatchTimer(
@@ -4762,19 +4888,23 @@ public final class BatteryStatsImpl extends BatteryStats {
}
@Override
- public long getAudioTurnedOnTime(long elapsedRealtimeUs, int which) {
- if (mAudioTurnedOnTimer == null) {
- return 0;
- }
- return mAudioTurnedOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
+ public Timer getAudioTurnedOnTimer() {
+ return mAudioTurnedOnTimer;
}
@Override
- public long getVideoTurnedOnTime(long elapsedRealtimeUs, int which) {
- if (mVideoTurnedOnTimer == null) {
- return 0;
- }
- return mVideoTurnedOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
+ public Timer getVideoTurnedOnTimer() {
+ return mVideoTurnedOnTimer;
+ }
+
+ @Override
+ public Timer getFlashlightTurnedOnTimer() {
+ return mFlashlightTurnedOnTimer;
+ }
+
+ @Override
+ public Timer getCameraTurnedOnTimer() {
+ return mCameraTurnedOnTimer;
}
@Override
@@ -4994,6 +5124,12 @@ public final class BatteryStatsImpl extends BatteryStats {
if (mVideoTurnedOnTimer != null) {
active |= !mVideoTurnedOnTimer.reset(false);
}
+ if (mFlashlightTurnedOnTimer != null) {
+ active |= !mFlashlightTurnedOnTimer.reset(false);
+ }
+ if (mCameraTurnedOnTimer != null) {
+ active |= !mCameraTurnedOnTimer.reset(false);
+ }
if (mForegroundActivityTimer != null) {
active |= !mForegroundActivityTimer.reset(false);
}
@@ -5155,6 +5291,14 @@ public final class BatteryStatsImpl extends BatteryStats {
mVideoTurnedOnTimer.detach();
mVideoTurnedOnTimer = null;
}
+ if (mFlashlightTurnedOnTimer != null) {
+ mFlashlightTurnedOnTimer.detach();
+ mFlashlightTurnedOnTimer = null;
+ }
+ if (mCameraTurnedOnTimer != null) {
+ mCameraTurnedOnTimer.detach();
+ mCameraTurnedOnTimer = null;
+ }
if (mForegroundActivityTimer != null) {
mForegroundActivityTimer.detach();
mForegroundActivityTimer = null;
@@ -5291,6 +5435,18 @@ public final class BatteryStatsImpl extends BatteryStats {
} else {
out.writeInt(0);
}
+ if (mFlashlightTurnedOnTimer != null) {
+ out.writeInt(1);
+ mFlashlightTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs);
+ } else {
+ out.writeInt(0);
+ }
+ if (mCameraTurnedOnTimer != null) {
+ out.writeInt(1);
+ mCameraTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs);
+ } else {
+ out.writeInt(0);
+ }
if (mForegroundActivityTimer != null) {
out.writeInt(1);
mForegroundActivityTimer.writeToParcel(out, elapsedRealtimeUs);
@@ -5469,6 +5625,18 @@ public final class BatteryStatsImpl extends BatteryStats {
mVideoTurnedOnTimer = null;
}
if (in.readInt() != 0) {
+ mFlashlightTurnedOnTimer = new StopwatchTimer(Uid.this, FLASHLIGHT_TURNED_ON,
+ mFlashlightTurnedOnTimers, mOnBatteryTimeBase, in);
+ } else {
+ mFlashlightTurnedOnTimer = null;
+ }
+ if (in.readInt() != 0) {
+ mCameraTurnedOnTimer = new StopwatchTimer(Uid.this, CAMERA_TURNED_ON,
+ mCameraTurnedOnTimers, mOnBatteryTimeBase, in);
+ } else {
+ mCameraTurnedOnTimer = null;
+ }
+ if (in.readInt() != 0) {
mForegroundActivityTimer = new StopwatchTimer(
Uid.this, FOREGROUND_ACTIVITY, null, mOnBatteryTimeBase, in);
} else {
@@ -6700,6 +6868,7 @@ public final class BatteryStatsImpl extends BatteryStats {
mAudioOnTimer = new StopwatchTimer(null, -7, null, mOnBatteryTimeBase);
mVideoOnTimer = new StopwatchTimer(null, -8, null, mOnBatteryTimeBase);
mFlashlightOnTimer = new StopwatchTimer(null, -9, null, mOnBatteryTimeBase);
+ mCameraOnTimer = new StopwatchTimer(null, -13, null, mOnBatteryTimeBase);
mOnBattery = mOnBatteryInternal = false;
long uptime = SystemClock.uptimeMillis() * 1000;
long realtime = SystemClock.elapsedRealtime() * 1000;
@@ -7285,6 +7454,7 @@ public final class BatteryStatsImpl extends BatteryStats {
mAudioOnTimer.reset(false);
mVideoOnTimer.reset(false);
mFlashlightOnTimer.reset(false);
+ mCameraOnTimer.reset(false);
for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
mPhoneSignalStrengthsTimer[i].reset(false);
}
@@ -8811,8 +8981,10 @@ public final class BatteryStatsImpl extends BatteryStats {
}
mNumConnectivityChange = mLoadedNumConnectivityChange = in.readInt();
- mFlashlightOn = false;
+ mFlashlightOnNesting = 0;
mFlashlightOnTimer.readSummaryFromParcelLocked(in);
+ mCameraOnNesting = 0;
+ mCameraOnTimer.readSummaryFromParcelLocked(in);
int NKW = in.readInt();
if (NKW > 10000) {
@@ -8883,6 +9055,12 @@ public final class BatteryStatsImpl extends BatteryStats {
u.createVideoTurnedOnTimerLocked().readSummaryFromParcelLocked(in);
}
if (in.readInt() != 0) {
+ u.createFlashlightTurnedOnTimerLocked().readSummaryFromParcelLocked(in);
+ }
+ if (in.readInt() != 0) {
+ u.createCameraTurnedOnTimerLocked().readSummaryFromParcelLocked(in);
+ }
+ if (in.readInt() != 0) {
u.createForegroundActivityTimerLocked().readSummaryFromParcelLocked(in);
}
u.mProcessState = Uid.PROCESS_STATE_NONE;
@@ -9132,6 +9310,7 @@ public final class BatteryStatsImpl extends BatteryStats {
}
out.writeInt(mNumConnectivityChange);
mFlashlightOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
+ mCameraOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
out.writeInt(mKernelWakelockStats.size());
for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
@@ -9208,6 +9387,18 @@ public final class BatteryStatsImpl extends BatteryStats {
} else {
out.writeInt(0);
}
+ if (u.mFlashlightTurnedOnTimer != null) {
+ out.writeInt(1);
+ u.mFlashlightTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
+ } else {
+ out.writeInt(0);
+ }
+ if (u.mCameraTurnedOnTimer != null) {
+ out.writeInt(1);
+ u.mCameraTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
+ } else {
+ out.writeInt(0);
+ }
if (u.mForegroundActivityTimer != null) {
out.writeInt(1);
u.mForegroundActivityTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
@@ -9453,8 +9644,10 @@ public final class BatteryStatsImpl extends BatteryStats {
mAudioOnTimer = new StopwatchTimer(null, -7, null, mOnBatteryTimeBase);
mVideoOnNesting = 0;
mVideoOnTimer = new StopwatchTimer(null, -8, null, mOnBatteryTimeBase);
- mFlashlightOn = false;
+ mFlashlightOnNesting = 0;
mFlashlightOnTimer = new StopwatchTimer(null, -9, null, mOnBatteryTimeBase, in);
+ mCameraOnNesting = 0;
+ mCameraOnTimer = new StopwatchTimer(null, -13, null, mOnBatteryTimeBase, in);
mDischargeUnplugLevel = in.readInt();
mDischargePlugLevel = in.readInt();
mDischargeCurrentLevel = in.readInt();
@@ -9499,6 +9692,8 @@ public final class BatteryStatsImpl extends BatteryStats {
mWifiMulticastTimers.clear();
mAudioTurnedOnTimers.clear();
mVideoTurnedOnTimers.clear();
+ mFlashlightTurnedOnTimers.clear();
+ mCameraTurnedOnTimers.clear();
sNumSpeedSteps = in.readInt();
@@ -9598,6 +9793,7 @@ public final class BatteryStatsImpl extends BatteryStats {
out.writeInt(mLoadedNumConnectivityChange);
out.writeInt(mUnpluggedNumConnectivityChange);
mFlashlightOnTimer.writeToParcel(out, uSecRealtime);
+ mCameraOnTimer.writeToParcel(out, uSecRealtime);
out.writeInt(mDischargeUnplugLevel);
out.writeInt(mDischargePlugLevel);
out.writeInt(mDischargeCurrentLevel);
@@ -9732,6 +9928,8 @@ public final class BatteryStatsImpl extends BatteryStats {
}
pr.println("*** Flashlight timer:");
mFlashlightOnTimer.logState(pr, " ");
+ pr.println("*** Camera timer:");
+ mCameraOnTimer.logState(pr, " ");
}
super.dumpLocked(context, pw, flags, reqUid, histStart);
}
diff --git a/core/java/com/android/internal/os/SomeArgs.java b/core/java/com/android/internal/os/SomeArgs.java
index c977997..b0d24fd 100644
--- a/core/java/com/android/internal/os/SomeArgs.java
+++ b/core/java/com/android/internal/os/SomeArgs.java
@@ -46,6 +46,7 @@ public final class SomeArgs {
public Object arg4;
public Object arg5;
public Object arg6;
+ public Object arg7;
public int argi1;
public int argi2;
public int argi3;
@@ -97,6 +98,7 @@ public final class SomeArgs {
arg4 = null;
arg5 = null;
arg6 = null;
+ arg7 = null;
argi1 = 0;
argi2 = 0;
argi3 = 0;
diff --git a/core/java/com/android/internal/policy/IKeyguardService.aidl b/core/java/com/android/internal/policy/IKeyguardService.aidl
index f93b1a1..7ab4651 100644
--- a/core/java/com/android/internal/policy/IKeyguardService.aidl
+++ b/core/java/com/android/internal/policy/IKeyguardService.aidl
@@ -22,6 +22,7 @@ import com.android.internal.policy.IKeyguardExitCallback;
import android.os.Bundle;
oneway interface IKeyguardService {
+
/**
* Sets the Keyguard as occluded when a window dismisses the Keyguard with flag
* FLAG_SHOW_ON_LOCK_SCREEN.
@@ -36,8 +37,27 @@ oneway interface IKeyguardService {
void dismiss();
void onDreamingStarted();
void onDreamingStopped();
- void onScreenTurnedOff(int reason);
- void onScreenTurnedOn(IKeyguardShowCallback callback);
+
+ /**
+ * Called when the device has started going to sleep.
+ *
+ * @param why {@link #OFF_BECAUSE_OF_USER}, {@link #OFF_BECAUSE_OF_ADMIN},
+ * or {@link #OFF_BECAUSE_OF_TIMEOUT}.
+ */
+ void onStartedGoingToSleep(int reason);
+
+ /**
+ * Called when the device has finished going to sleep.
+ *
+ * @param why {@link #OFF_BECAUSE_OF_USER}, {@link #OFF_BECAUSE_OF_ADMIN},
+ * or {@link #OFF_BECAUSE_OF_TIMEOUT}.
+ */
+ void onFinishedGoingToSleep(int reason);
+
+ /**
+ * Called when the device has started waking up.
+ */
+ void onStartedWakingUp(IKeyguardShowCallback callback);
void setKeyguardEnabled(boolean enabled);
void onSystemReady();
void doKeyguardTimeout(in Bundle options);
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index bc64373..22c0680 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -56,7 +56,6 @@ import android.view.Window;
import android.view.WindowInsets;
import android.view.WindowManager;
import com.android.internal.R;
-import com.android.internal.util.ScreenShapeHelper;
import com.android.internal.view.FloatingActionMode;
import com.android.internal.view.RootViewSurfaceTaker;
import com.android.internal.view.StandaloneActionMode;
@@ -156,7 +155,6 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
TypedValue mFixedWidthMinor;
TypedValue mFixedHeightMajor;
TypedValue mFixedHeightMinor;
- int mOutsetBottomPx;
// This is the top-level view of the window, containing the window decor.
private DecorView mDecor;
@@ -289,6 +287,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
private Boolean mSharedElementsUseOverlay;
private Rect mTempRect;
+ private Rect mOutsets = new Rect();
static class WindowManagerHolder {
static final IWindowManager sWindowManager = IWindowManager.Stub.asInterface(
@@ -2220,12 +2219,14 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
private final ColorViewState mStatusColorViewState = new ColorViewState(
SYSTEM_UI_FLAG_FULLSCREEN, FLAG_TRANSLUCENT_STATUS,
Gravity.TOP,
+ Gravity.LEFT,
STATUS_BAR_BACKGROUND_TRANSITION_NAME,
com.android.internal.R.id.statusBarBackground,
FLAG_FULLSCREEN);
private final ColorViewState mNavigationColorViewState = new ColorViewState(
SYSTEM_UI_FLAG_HIDE_NAVIGATION, FLAG_TRANSLUCENT_NAVIGATION,
Gravity.BOTTOM,
+ Gravity.RIGHT,
NAVIGATION_BAR_BACKGROUND_TRANSITION_NAME,
com.android.internal.R.id.navigationBarBackground,
0 /* hideWindowFlag */);
@@ -2241,6 +2242,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
private int mLastRightInset = 0;
private boolean mLastHasTopStableInset = false;
private boolean mLastHasBottomStableInset = false;
+ private boolean mLastHasRightStableInset = false;
private int mLastWindowFlags = 0;
private int mRootScrollY = 0;
@@ -2401,19 +2403,6 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
}
@Override
- public WindowInsets dispatchApplyWindowInsets(WindowInsets insets) {
- if (mOutsetBottomPx != 0) {
- WindowInsets newInsets = insets.replaceSystemWindowInsets(
- insets.getSystemWindowInsetLeft(), insets.getSystemWindowInsetTop(),
- insets.getSystemWindowInsetRight(), mOutsetBottomPx);
- return super.dispatchApplyWindowInsets(newInsets);
- } else {
- return super.dispatchApplyWindowInsets(insets);
- }
- }
-
-
- @Override
public boolean onTouchEvent(MotionEvent event) {
return onInterceptTouchEvent(event);
}
@@ -2624,11 +2613,21 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
}
}
- if (mOutsetBottomPx != 0) {
+ getOutsets(mOutsets);
+ if (mOutsets.top > 0 || mOutsets.bottom > 0) {
int mode = MeasureSpec.getMode(heightMeasureSpec);
if (mode != MeasureSpec.UNSPECIFIED) {
int height = MeasureSpec.getSize(heightMeasureSpec);
- heightMeasureSpec = MeasureSpec.makeMeasureSpec(height + mOutsetBottomPx, mode);
+ heightMeasureSpec = MeasureSpec.makeMeasureSpec(
+ height + mOutsets.top + mOutsets.bottom, mode);
+ }
+ }
+ if (mOutsets.left > 0 || mOutsets.right > 0) {
+ int mode = MeasureSpec.getMode(widthMeasureSpec);
+ if (mode != MeasureSpec.UNSPECIFIED) {
+ int width = MeasureSpec.getSize(widthMeasureSpec);
+ widthMeasureSpec = MeasureSpec.makeMeasureSpec(
+ width + mOutsets.left + mOutsets.right, mode);
}
}
@@ -2666,6 +2665,18 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
}
@Override
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ super.onLayout(changed, left, top, right, bottom);
+ getOutsets(mOutsets);
+ if (mOutsets.left > 0) {
+ offsetLeftAndRight(-mOutsets.left);
+ }
+ if (mOutsets.top > 0) {
+ offsetTopAndBottom(-mOutsets.top);
+ }
+ }
+
+ @Override
public void draw(Canvas canvas) {
super.draw(canvas);
@@ -2674,7 +2685,6 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
}
}
-
@Override
public boolean showContextMenuForChild(View originalView) {
// Reuse the context menu builder
@@ -2875,12 +2885,19 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
boolean hasBottomStableInset = insets.getStableInsetBottom() != 0;
disallowAnimate |= (hasBottomStableInset != mLastHasBottomStableInset);
mLastHasBottomStableInset = hasBottomStableInset;
+
+ boolean hasRightStableInset = insets.getStableInsetRight() != 0;
+ disallowAnimate |= (hasRightStableInset != mLastHasRightStableInset);
+ mLastHasRightStableInset = hasRightStableInset;
}
updateColorViewInt(mStatusColorViewState, sysUiVisibility, mStatusBarColor,
- mLastTopInset, animate && !disallowAnimate);
+ mLastTopInset, false /* matchVertical */, animate && !disallowAnimate);
+
+ boolean navBarToRightEdge = mLastBottomInset == 0 && mLastRightInset > 0;
+ int navBarSize = navBarToRightEdge ? mLastRightInset : mLastBottomInset;
updateColorViewInt(mNavigationColorViewState, sysUiVisibility, mNavigationBarColor,
- mLastBottomInset, animate && !disallowAnimate);
+ navBarSize, navBarToRightEdge, animate && !disallowAnimate);
}
// When we expand the window with FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS, we still need
@@ -2924,9 +2941,20 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
return insets;
}
+ /**
+ * Update a color view
+ *
+ * @param state the color view to update.
+ * @param sysUiVis the current systemUiVisibility to apply.
+ * @param color the current color to apply.
+ * @param size the current size in the non-parent-matching dimension.
+ * @param verticalBar if true the view is attached to a vertical edge, otherwise to a
+ * horizontal edge,
+ * @param animate if true, the change will be animated.
+ */
private void updateColorViewInt(final ColorViewState state, int sysUiVis, int color,
- int height, boolean animate) {
- boolean show = height > 0 && (sysUiVis & state.systemUiHideFlag) == 0
+ int size, boolean verticalBar, boolean animate) {
+ boolean show = size > 0 && (sysUiVis & state.systemUiHideFlag) == 0
&& (getAttributes().flags & state.hideWindowFlag) == 0
&& (getAttributes().flags & state.translucentFlag) == 0
&& (color & Color.BLACK) != 0
@@ -2935,6 +2963,10 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
boolean visibilityChanged = false;
View view = state.view;
+ int resolvedHeight = verticalBar ? LayoutParams.MATCH_PARENT : size;
+ int resolvedWidth = verticalBar ? size : LayoutParams.MATCH_PARENT;
+ int resolvedGravity = verticalBar ? state.horizontalGravity : state.verticalGravity;
+
if (view == null) {
if (show) {
state.view = view = new View(mContext);
@@ -2945,8 +2977,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
view.setVisibility(INVISIBLE);
state.targetVisibility = VISIBLE;
- addView(view, new LayoutParams(LayoutParams.MATCH_PARENT, height,
- Gravity.START | state.verticalGravity));
+ addView(view, new LayoutParams(resolvedWidth, resolvedHeight, resolvedGravity));
updateColorViewTranslations();
}
} else {
@@ -2955,8 +2986,11 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
state.targetVisibility = vis;
if (show) {
LayoutParams lp = (LayoutParams) view.getLayoutParams();
- if (lp.height != height) {
- lp.height = height;
+ if (lp.height != resolvedHeight || lp.width != resolvedWidth
+ || lp.gravity != resolvedGravity) {
+ lp.height = resolvedHeight;
+ lp.width = resolvedWidth;
+ lp.gravity = resolvedGravity;
view.setLayoutParams(lp);
}
view.setBackgroundColor(color);
@@ -3583,19 +3617,6 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
requestFeature(FEATURE_ACTIVITY_TRANSITIONS);
}
- final WindowManager windowService = (WindowManager) getContext().getSystemService(
- Context.WINDOW_SERVICE);
- if (windowService != null) {
- final Display display = windowService.getDefaultDisplay();
- final boolean shouldUseBottomOutset =
- display.getDisplayId() == Display.DEFAULT_DISPLAY
- || (getForcedWindowFlags() & FLAG_FULLSCREEN) != 0;
- if (shouldUseBottomOutset) {
- mOutsetBottomPx = ScreenShapeHelper.getWindowOutsetBottomPx(
- getContext().getResources().getDisplayMetrics(), a);
- }
- }
-
final Context context = getContext();
final int targetSdk = context.getApplicationInfo().targetSdkVersion;
final boolean targetPreHoneycomb = targetSdk < android.os.Build.VERSION_CODES.HONEYCOMB;
@@ -4884,16 +4905,18 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
final int systemUiHideFlag;
final int translucentFlag;
final int verticalGravity;
+ final int horizontalGravity;
final String transitionName;
final int hideWindowFlag;
ColorViewState(int systemUiHideFlag,
- int translucentFlag, int verticalGravity,
+ int translucentFlag, int verticalGravity, int horizontalGravity,
String transitionName, int id, int hideWindowFlag) {
this.id = id;
this.systemUiHideFlag = systemUiHideFlag;
this.translucentFlag = translucentFlag;
this.verticalGravity = verticalGravity;
+ this.horizontalGravity = horizontalGravity;
this.transitionName = transitionName;
this.hideWindowFlag = hideWindowFlag;
}
diff --git a/core/java/com/android/internal/util/ScreenShapeHelper.java b/core/java/com/android/internal/util/ScreenShapeHelper.java
index 58ae853..4a196f8 100644
--- a/core/java/com/android/internal/util/ScreenShapeHelper.java
+++ b/core/java/com/android/internal/util/ScreenShapeHelper.java
@@ -18,19 +18,13 @@ public class ScreenShapeHelper {
/**
* Return the bottom pixel window outset of a window given its style attributes.
- * @param displayMetrics Display metrics of the current device
- * @param windowStyle Window style attributes for the window.
* @return An outset dimension in pixels or 0 if no outset should be applied.
*/
- public static int getWindowOutsetBottomPx(DisplayMetrics displayMetrics,
- TypedArray windowStyle) {
+ public static int getWindowOutsetBottomPx(Resources resources) {
if (IS_EMULATOR) {
return SystemProperties.getInt(ViewRootImpl.PROPERTY_EMULATOR_WIN_OUTSET_BOTTOM_PX, 0);
- } else if (windowStyle.hasValue(R.styleable.Window_windowOutsetBottom)) {
- TypedValue outsetBottom = new TypedValue();
- windowStyle.getValue(R.styleable.Window_windowOutsetBottom, outsetBottom);
- return (int) outsetBottom.getDimension(displayMetrics);
+ } else {
+ return resources.getInteger(com.android.internal.R.integer.config_windowOutsetBottom);
}
- return 0;
}
}
diff --git a/core/java/com/android/internal/view/BaseIWindow.java b/core/java/com/android/internal/view/BaseIWindow.java
index e27ba13..3eeabcd 100644
--- a/core/java/com/android/internal/view/BaseIWindow.java
+++ b/core/java/com/android/internal/view/BaseIWindow.java
@@ -34,8 +34,8 @@ public class BaseIWindow extends IWindow.Stub {
}
@Override
- public void resized(Rect frame, Rect overscanInsets, Rect contentInsets,
- Rect visibleInsets, Rect stableInsets, boolean reportDraw, Configuration newConfig) {
+ public void resized(Rect frame, Rect overscanInsets, Rect contentInsets, Rect visibleInsets,
+ Rect stableInsets, Rect outsets, boolean reportDraw, Configuration newConfig) {
if (reportDraw) {
try {
mSession.finishDrawing(this);
diff --git a/core/java/com/android/internal/widget/ButtonBarLayout.java b/core/java/com/android/internal/widget/ButtonBarLayout.java
index f58ab03..39613e8 100644
--- a/core/java/com/android/internal/widget/ButtonBarLayout.java
+++ b/core/java/com/android/internal/widget/ButtonBarLayout.java
@@ -33,9 +33,6 @@ public class ButtonBarLayout extends LinearLayout {
/** Whether the current configuration allows stacking. */
private final boolean mAllowStacking;
- /** Whether the layout is currently stacked. */
- private boolean mStacked;
-
private int mLastWidthSize = -1;
public ButtonBarLayout(Context context, AttributeSet attrs) {
@@ -44,15 +41,14 @@ public class ButtonBarLayout extends LinearLayout {
final TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.ButtonBarLayout);
mAllowStacking = ta.getBoolean(R.styleable.ButtonBarLayout_allowStacking, false);
ta.recycle();
-
- mStacked = getOrientation() == VERTICAL;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
+
if (mAllowStacking) {
- final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
- if (widthSize > mLastWidthSize && mStacked) {
+ if (widthSize > mLastWidthSize && isStacked()) {
// We're being measured wider this time, try un-stacking.
setStacked(false);
}
@@ -60,18 +56,37 @@ public class ButtonBarLayout extends LinearLayout {
mLastWidthSize = widthSize;
}
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ boolean needsRemeasure = false;
+
+ // If we're not stacked, make sure the measure spec is AT_MOST rather
+ // than EXACTLY. This ensures that we'll still get TOO_SMALL so that we
+ // know to stack the buttons.
+ final int initialWidthMeasureSpec;
+ if (!isStacked() && MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY) {
+ initialWidthMeasureSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.AT_MOST);
+
+ // We'll need to remeasure again to fill excess space.
+ needsRemeasure = true;
+ } else {
+ initialWidthMeasureSpec = widthMeasureSpec;
+ }
+
+ super.onMeasure(initialWidthMeasureSpec, heightMeasureSpec);
- if (mAllowStacking && !mStacked) {
+ if (mAllowStacking && !isStacked()) {
final int measuredWidth = getMeasuredWidthAndState();
final int measuredWidthState = measuredWidth & MEASURED_STATE_MASK;
if (measuredWidthState == MEASURED_STATE_TOO_SMALL) {
setStacked(true);
// Measure again in the new orientation.
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ needsRemeasure = true;
}
}
+
+ if (needsRemeasure) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ }
}
private void setStacked(boolean stacked) {
@@ -89,7 +104,9 @@ public class ButtonBarLayout extends LinearLayout {
for (int i = childCount - 2; i >= 0; i--) {
bringChildToFront(getChildAt(i));
}
+ }
- mStacked = stacked;
+ private boolean isStacked() {
+ return getOrientation() == LinearLayout.VERTICAL;
}
}
diff --git a/core/java/com/android/internal/widget/FloatingToolbar.java b/core/java/com/android/internal/widget/FloatingToolbar.java
index 3cff59a..1fc0ac3 100644
--- a/core/java/com/android/internal/widget/FloatingToolbar.java
+++ b/core/java/com/android/internal/widget/FloatingToolbar.java
@@ -353,10 +353,14 @@ public final class FloatingToolbar {
* from.
*/
public FloatingToolbarPopup(View parent) {
+ mMarginHorizontal = parent.getResources()
+ .getDimensionPixelSize(R.dimen.floating_toolbar_horizontal_margin);
+ mMarginVertical = parent.getResources()
+ .getDimensionPixelSize(R.dimen.floating_toolbar_vertical_margin);
mParent = Preconditions.checkNotNull(parent);
mContentContainer = createContentContainer(parent.getContext());
mPopupWindow = createPopupWindow(mContentContainer);
- mShowAnimation = createGrowFadeInFromBottom(mContentContainer);
+ mShowAnimation = createGrowFadeInFromBottom(mContentContainer, mMarginHorizontal);
mDismissAnimation = createShrinkFadeOutFromBottomAnimation(
mContentContainer,
150, // startDelay
@@ -376,17 +380,15 @@ public final class FloatingToolbar {
mPopupWindow.dismiss();
}
});
- mMarginHorizontal = parent.getResources()
- .getDimensionPixelSize(R.dimen.floating_toolbar_horizontal_margin);
- mMarginVertical = parent.getResources()
- .getDimensionPixelSize(R.dimen.floating_toolbar_vertical_margin);
}
/**
* Lays out buttons for the specified menu items.
*/
- public void layoutMenuItems(List<MenuItem> menuItems,
- MenuItem.OnMenuItemClickListener menuItemClickListener, int suggestedWidth) {
+ public void layoutMenuItems(
+ List<MenuItem> menuItems,
+ MenuItem.OnMenuItemClickListener menuItemClickListener,
+ int suggestedWidth) {
Preconditions.checkNotNull(menuItems);
mContentContainer.removeAllViews();
@@ -593,7 +595,9 @@ public final class FloatingToolbar {
final int startWidth = mContentContainer.getWidth();
final int startHeight = mContentContainer.getHeight();
final float startY = mContentContainer.getY();
- final float right = mContentContainer.getX() + mContentContainer.getWidth();
+ final float left = mContentContainer.getX();
+ final float right = left + mContentContainer.getWidth();
+ final boolean rtl = mContentContainer.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
Animation widthAnimation = new Animation() {
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
@@ -601,7 +605,11 @@ public final class FloatingToolbar {
int deltaWidth = (int) (interpolatedTime * (targetWidth - startWidth));
params.width = startWidth + deltaWidth;
mContentContainer.setLayoutParams(params);
- mContentContainer.setX(right - mContentContainer.getWidth());
+ if (rtl) {
+ mContentContainer.setX(left);
+ } else {
+ mContentContainer.setX(right - mContentContainer.getWidth());
+ }
}
};
Animation heightAnimation = new Animation() {
@@ -644,9 +652,11 @@ public final class FloatingToolbar {
final int targetHeight = mainPanelSize.getHeight();
final int startWidth = mContentContainer.getWidth();
final int startHeight = mContentContainer.getHeight();
- final float right = mContentContainer.getX() + mContentContainer.getWidth();
final float bottom = mContentContainer.getY() + mContentContainer.getHeight();
final boolean morphedUpwards = (mOverflowDirection == OVERFLOW_DIRECTION_UP);
+ final float left = mContentContainer.getX();
+ final float right = left + mContentContainer.getWidth();
+ final boolean rtl = mContentContainer.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
Animation widthAnimation = new Animation() {
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
@@ -654,7 +664,11 @@ public final class FloatingToolbar {
int deltaWidth = (int) (interpolatedTime * (targetWidth - startWidth));
params.width = startWidth + deltaWidth;
mContentContainer.setLayoutParams(params);
- mContentContainer.setX(right - mContentContainer.getWidth());
+ if (rtl) {
+ mContentContainer.setX(left);
+ } else {
+ mContentContainer.setX(right - mContentContainer.getWidth());
+ }
}
};
Animation heightAnimation = new Animation() {
@@ -747,9 +761,7 @@ public final class FloatingToolbar {
*/
private void positionMainPanel() {
Preconditions.checkNotNull(mMainPanel);
- float x = mPopupWindow.getWidth()
- - (mMainPanel.getView().getMeasuredWidth() + mMarginHorizontal);
- mContentContainer.setX(x);
+ mContentContainer.setX(mMarginHorizontal);
float y = mMarginVertical;
if (mOverflowDirection == OVERFLOW_DIRECTION_UP) {
@@ -1320,12 +1332,14 @@ public final class FloatingToolbar {
*
* @param view The view to animate
*/
- private static AnimatorSet createGrowFadeInFromBottom(View view) {
+ private static AnimatorSet createGrowFadeInFromBottom(View view, int x) {
AnimatorSet growFadeInFromBottomAnimation = new AnimatorSet();
growFadeInFromBottomAnimation.playTogether(
ObjectAnimator.ofFloat(view, View.SCALE_X, 0.5f, 1).setDuration(125),
ObjectAnimator.ofFloat(view, View.SCALE_Y, 0.5f, 1).setDuration(125),
- ObjectAnimator.ofFloat(view, View.ALPHA, 0, 1).setDuration(75));
+ ObjectAnimator.ofFloat(view, View.ALPHA, 0, 1).setDuration(75),
+ // Make sure that view.x is always fixed throughout the duration of this animation.
+ ObjectAnimator.ofFloat(view, View.X, x, x));
growFadeInFromBottomAnimation.setStartDelay(50);
return growFadeInFromBottomAnimation;
}
diff --git a/core/java/com/android/internal/widget/ILockSettings.aidl b/core/java/com/android/internal/widget/ILockSettings.aidl
index bfafff6..dfb7c50 100644
--- a/core/java/com/android/internal/widget/ILockSettings.aidl
+++ b/core/java/com/android/internal/widget/ILockSettings.aidl
@@ -16,6 +16,8 @@
package com.android.internal.widget;
+import com.android.internal.widget.VerifyCredentialResponse;
+
/** {@hide} */
interface ILockSettings {
void setBoolean(in String key, in boolean value, in int userId);
@@ -25,11 +27,11 @@ interface ILockSettings {
long getLong(in String key, in long defaultValue, in int userId);
String getString(in String key, in String defaultValue, in int userId);
void setLockPattern(in String pattern, in String savedPattern, int userId);
- boolean checkPattern(in String pattern, int userId);
- byte[] verifyPattern(in String pattern, long challenge, int userId);
+ VerifyCredentialResponse checkPattern(in String pattern, int userId);
+ VerifyCredentialResponse verifyPattern(in String pattern, long challenge, int userId);
void setLockPassword(in String password, in String savedPassword, int userId);
- boolean checkPassword(in String password, int userId);
- byte[] verifyPassword(in String password, long challenge, int userId);
+ VerifyCredentialResponse checkPassword(in String password, int userId);
+ VerifyCredentialResponse verifyPassword(in String password, long challenge, int userId);
boolean checkVoldPassword(int userId);
boolean havePattern(int userId);
boolean havePassword(int userId);
diff --git a/core/java/com/android/internal/widget/LockPatternChecker.java b/core/java/com/android/internal/widget/LockPatternChecker.java
index ac0f5fe..4880664 100644
--- a/core/java/com/android/internal/widget/LockPatternChecker.java
+++ b/core/java/com/android/internal/widget/LockPatternChecker.java
@@ -2,6 +2,8 @@ package com.android.internal.widget;
import android.os.AsyncTask;
+import com.android.internal.widget.LockPatternUtils.RequestThrottledException;
+
import java.util.List;
/**
@@ -16,8 +18,10 @@ public final class LockPatternChecker {
* Invoked when a security check is finished.
*
* @param matched Whether the PIN/Password/Pattern matches the stored one.
+ * @param throttleTimeoutMs The amount of time in ms to wait before reattempting
+ * the call. Only non-0 if matched is false.
*/
- void onChecked(boolean matched);
+ void onChecked(boolean matched, int throttleTimeoutMs);
}
/**
@@ -28,8 +32,10 @@ public final class LockPatternChecker {
* Invoked when a security verification is finished.
*
* @param attestation The attestation that the challenge was verified, or null.
+ * @param throttleTimeoutMs The amount of time in ms to wait before reattempting
+ * the call. Only non-0 if attestation is null.
*/
- void onVerified(byte[] attestation);
+ void onVerified(byte[] attestation, int throttleTimeoutMs);
}
/**
@@ -47,14 +53,21 @@ public final class LockPatternChecker {
final int userId,
final OnVerifyCallback callback) {
AsyncTask<Void, Void, byte[]> task = new AsyncTask<Void, Void, byte[]>() {
+ private int mThrottleTimeout;
+
@Override
protected byte[] doInBackground(Void... args) {
- return utils.verifyPattern(pattern, challenge, userId);
+ try {
+ return utils.verifyPattern(pattern, challenge, userId);
+ } catch (RequestThrottledException ex) {
+ mThrottleTimeout = ex.getTimeoutMs();
+ return null;
+ }
}
@Override
protected void onPostExecute(byte[] result) {
- callback.onVerified(result);
+ callback.onVerified(result, mThrottleTimeout);
}
};
task.execute();
@@ -74,14 +87,21 @@ public final class LockPatternChecker {
final int userId,
final OnCheckCallback callback) {
AsyncTask<Void, Void, Boolean> task = new AsyncTask<Void, Void, Boolean>() {
+ private int mThrottleTimeout;
+
@Override
protected Boolean doInBackground(Void... args) {
- return utils.checkPattern(pattern, userId);
+ try {
+ return utils.checkPattern(pattern, userId);
+ } catch (RequestThrottledException ex) {
+ mThrottleTimeout = ex.getTimeoutMs();
+ return false;
+ }
}
@Override
protected void onPostExecute(Boolean result) {
- callback.onChecked(result);
+ callback.onChecked(result, mThrottleTimeout);
}
};
task.execute();
@@ -103,14 +123,21 @@ public final class LockPatternChecker {
final int userId,
final OnVerifyCallback callback) {
AsyncTask<Void, Void, byte[]> task = new AsyncTask<Void, Void, byte[]>() {
+ private int mThrottleTimeout;
+
@Override
protected byte[] doInBackground(Void... args) {
- return utils.verifyPassword(password, challenge, userId);
+ try {
+ return utils.verifyPassword(password, challenge, userId);
+ } catch (RequestThrottledException ex) {
+ mThrottleTimeout = ex.getTimeoutMs();
+ return null;
+ }
}
@Override
protected void onPostExecute(byte[] result) {
- callback.onVerified(result);
+ callback.onVerified(result, mThrottleTimeout);
}
};
task.execute();
@@ -130,14 +157,21 @@ public final class LockPatternChecker {
final int userId,
final OnCheckCallback callback) {
AsyncTask<Void, Void, Boolean> task = new AsyncTask<Void, Void, Boolean>() {
+ private int mThrottleTimeout;
+
@Override
protected Boolean doInBackground(Void... args) {
- return utils.checkPassword(password, userId);
+ try {
+ return utils.checkPassword(password, userId);
+ } catch (RequestThrottledException ex) {
+ mThrottleTimeout = ex.getTimeoutMs();
+ return false;
+ }
}
@Override
protected void onPostExecute(Boolean result) {
- callback.onChecked(result);
+ callback.onChecked(result, mThrottleTimeout);
}
};
task.execute();
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 55b058c..aee0ff6 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -60,24 +60,12 @@ public class LockPatternUtils {
private static final boolean DEBUG = false;
/**
- * The maximum number of incorrect attempts before the user is prevented
- * from trying again for {@link #FAILED_ATTEMPT_TIMEOUT_MS}.
- */
- public static final int FAILED_ATTEMPTS_BEFORE_TIMEOUT = 5;
-
- /**
* The number of incorrect attempts before which we fall back on an alternative
* method of verifying the user, and resetting their lock pattern.
*/
public static final int FAILED_ATTEMPTS_BEFORE_RESET = 20;
/**
- * How long the user is prevented from trying again after entering the
- * wrong pattern too many times.
- */
- public static final long FAILED_ATTEMPT_TIMEOUT_MS = 30000L;
-
- /**
* The interval of the countdown for showing progress of the lockout.
*/
public static final long FAILED_ATTEMPT_COUNTDOWN_INTERVAL_MS = 1000L;
@@ -109,6 +97,7 @@ public class LockPatternUtils {
@Deprecated
public final static String LOCKOUT_PERMANENT_KEY = "lockscreen.lockedoutpermanently";
public final static String LOCKOUT_ATTEMPT_DEADLINE = "lockscreen.lockoutattemptdeadline";
+ public final static String LOCKOUT_ATTEMPT_TIMEOUT_MS = "lockscreen.lockoutattempttimeoutmss";
public final static String PATTERN_EVER_CHOSEN_KEY = "lockscreen.patterneverchosen";
public final static String PASSWORD_TYPE_KEY = "lockscreen.password_type";
@Deprecated
@@ -144,6 +133,23 @@ public class LockPatternUtils {
private DevicePolicyManager mDevicePolicyManager;
private ILockSettings mLockSettingsService;
+
+ public static final class RequestThrottledException extends Exception {
+ private int mTimeoutMs;
+ public RequestThrottledException(int timeoutMs) {
+ mTimeoutMs = timeoutMs;
+ }
+
+ /**
+ * @return The amount of time in ms before another request may
+ * be executed
+ */
+ public int getTimeoutMs() {
+ return mTimeoutMs;
+ }
+
+ }
+
public DevicePolicyManager getDevicePolicyManager() {
if (mDevicePolicyManager == null) {
mDevicePolicyManager =
@@ -239,9 +245,23 @@ public class LockPatternUtils {
* @param challenge The challenge to verify against the pattern
* @return the attestation that the challenge was verified, or null.
*/
- public byte[] verifyPattern(List<LockPatternView.Cell> pattern, long challenge, int userId) {
+ public byte[] verifyPattern(List<LockPatternView.Cell> pattern, long challenge, int userId)
+ throws RequestThrottledException {
try {
- return getLockSettings().verifyPattern(patternToString(pattern), challenge, userId);
+ VerifyCredentialResponse response =
+ getLockSettings().verifyPattern(patternToString(pattern), challenge, userId);
+ if (response == null) {
+ // Shouldn't happen
+ return null;
+ }
+
+ if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
+ return response.getPayload();
+ } else if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_RETRY) {
+ throw new RequestThrottledException(response.getTimeout());
+ } else {
+ return null;
+ }
} catch (RemoteException re) {
return null;
}
@@ -253,9 +273,19 @@ public class LockPatternUtils {
* @param pattern The pattern to check.
* @return Whether the pattern matches the stored one.
*/
- public boolean checkPattern(List<LockPatternView.Cell> pattern, int userId) {
+ public boolean checkPattern(List<LockPatternView.Cell> pattern, int userId)
+ throws RequestThrottledException {
try {
- return getLockSettings().checkPattern(patternToString(pattern), userId);
+ VerifyCredentialResponse response =
+ getLockSettings().checkPattern(patternToString(pattern), userId);
+
+ if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
+ return true;
+ } else if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_RETRY) {
+ throw new RequestThrottledException(response.getTimeout());
+ } else {
+ return false;
+ }
} catch (RemoteException re) {
return true;
}
@@ -270,9 +300,19 @@ public class LockPatternUtils {
* @param challenge The challenge to verify against the password
* @return the attestation that the challenge was verified, or null.
*/
- public byte[] verifyPassword(String password, long challenge, int userId) {
+ public byte[] verifyPassword(String password, long challenge, int userId)
+ throws RequestThrottledException {
try {
- return getLockSettings().verifyPassword(password, challenge, userId);
+ VerifyCredentialResponse response =
+ getLockSettings().verifyPassword(password, challenge, userId);
+
+ if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
+ return response.getPayload();
+ } else if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_RETRY) {
+ throw new RequestThrottledException(response.getTimeout());
+ } else {
+ return null;
+ }
} catch (RemoteException re) {
return null;
}
@@ -284,9 +324,17 @@ public class LockPatternUtils {
* @param password The password to check.
* @return Whether the password matches the stored one.
*/
- public boolean checkPassword(String password, int userId) {
+ public boolean checkPassword(String password, int userId) throws RequestThrottledException {
try {
- return getLockSettings().checkPassword(password, userId);
+ VerifyCredentialResponse response =
+ getLockSettings().checkPassword(password, userId);
+ if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
+ return true;
+ } else if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_RETRY) {
+ throw new RequestThrottledException(response.getTimeout());
+ } else {
+ return false;
+ }
} catch (RemoteException re) {
return true;
}
@@ -992,9 +1040,10 @@ public class LockPatternUtils {
* pattern until the deadline has passed.
* @return the chosen deadline.
*/
- public long setLockoutAttemptDeadline(int userId) {
- final long deadline = SystemClock.elapsedRealtime() + FAILED_ATTEMPT_TIMEOUT_MS;
+ public long setLockoutAttemptDeadline(int userId, int timeoutMs) {
+ final long deadline = SystemClock.elapsedRealtime() + timeoutMs;
setLong(LOCKOUT_ATTEMPT_DEADLINE, deadline, userId);
+ setLong(LOCKOUT_ATTEMPT_TIMEOUT_MS, timeoutMs, userId);
return deadline;
}
@@ -1005,8 +1054,9 @@ public class LockPatternUtils {
*/
public long getLockoutAttemptDeadline(int userId) {
final long deadline = getLong(LOCKOUT_ATTEMPT_DEADLINE, 0L, userId);
+ final long timeoutMs = getLong(LOCKOUT_ATTEMPT_TIMEOUT_MS, 0L, userId);
final long now = SystemClock.elapsedRealtime();
- if (deadline < now || deadline > (now + FAILED_ATTEMPT_TIMEOUT_MS)) {
+ if (deadline < now || deadline > (now + timeoutMs)) {
return 0L;
}
return deadline;
diff --git a/core/java/com/android/internal/widget/SwipeDismissLayout.java b/core/java/com/android/internal/widget/SwipeDismissLayout.java
index 6d4e058..35ed63b 100644
--- a/core/java/com/android/internal/widget/SwipeDismissLayout.java
+++ b/core/java/com/android/internal/widget/SwipeDismissLayout.java
@@ -16,9 +16,11 @@
package com.android.internal.widget;
-import android.animation.TimeInterpolator;
import android.app.Activity;
+import android.content.BroadcastReceiver;
import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.util.Log;
@@ -28,8 +30,6 @@ import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
-import android.view.animation.AccelerateInterpolator;
-import android.view.animation.DecelerateInterpolator;
import android.widget.FrameLayout;
/**
@@ -62,10 +62,6 @@ public class SwipeDismissLayout extends FrameLayout {
// Cached ViewConfiguration and system-wide constant values
private int mSlop;
private int mMinFlingVelocity;
- private int mMaxFlingVelocity;
- private long mAnimationTime;
- private TimeInterpolator mCancelInterpolator;
- private TimeInterpolator mDismissInterpolator;
// Transient properties
private int mActiveTouchId;
@@ -92,6 +88,18 @@ public class SwipeDismissLayout extends FrameLayout {
}
}
};
+ private BroadcastReceiver mScreenOffReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (mDismissed) {
+ dismiss();
+ } else {
+ cancel();
+ }
+ resetMembers();
+ }
+ };
+ private IntentFilter mScreenOffFilter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
private float mLastX;
@@ -114,11 +122,6 @@ public class SwipeDismissLayout extends FrameLayout {
ViewConfiguration vc = ViewConfiguration.get(context);
mSlop = vc.getScaledTouchSlop();
mMinFlingVelocity = vc.getScaledMinimumFlingVelocity();
- mMaxFlingVelocity = vc.getScaledMaximumFlingVelocity();
- mAnimationTime = getContext().getResources().getInteger(
- android.R.integer.config_shortAnimTime);
- mCancelInterpolator = new DecelerateInterpolator(1.5f);
- mDismissInterpolator = new AccelerateInterpolator(1.5f);
TypedArray a = context.getTheme().obtainStyledAttributes(
com.android.internal.R.styleable.Theme);
mUseDynamicTranslucency = !a.hasValue(
@@ -141,15 +144,17 @@ public class SwipeDismissLayout extends FrameLayout {
getViewTreeObserver().addOnEnterAnimationCompleteListener(
mOnEnterAnimationCompleteListener);
}
+ getContext().registerReceiver(mScreenOffReceiver, mScreenOffFilter);
}
@Override
protected void onDetachedFromWindow() {
- super.onDetachedFromWindow();
+ getContext().unregisterReceiver(mScreenOffReceiver);
if (getContext() instanceof Activity) {
getViewTreeObserver().removeOnEnterAnimationCompleteListener(
mOnEnterAnimationCompleteListener);
}
+ super.onDetachedFromWindow();
}
@Override
diff --git a/core/java/com/android/internal/widget/VerifyCredentialResponse.aidl b/core/java/com/android/internal/widget/VerifyCredentialResponse.aidl
new file mode 100644
index 0000000..59a4bba
--- /dev/null
+++ b/core/java/com/android/internal/widget/VerifyCredentialResponse.aidl
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.widget;
+
+/**
+ * Response object for an ILockSettings verification request.
+ * @hide
+ */
+parcelable VerifyCredentialResponse;
+
diff --git a/core/java/com/android/internal/widget/VerifyCredentialResponse.java b/core/java/com/android/internal/widget/VerifyCredentialResponse.java
new file mode 100644
index 0000000..48109ca
--- /dev/null
+++ b/core/java/com/android/internal/widget/VerifyCredentialResponse.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.widget;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Response object for a ILockSettings credential verification request.
+ * @hide
+ */
+public final class VerifyCredentialResponse implements Parcelable {
+
+ public static final int RESPONSE_ERROR = -1;
+ public static final int RESPONSE_OK = 0;
+ public static final int RESPONSE_RETRY = 1;
+
+ public static final VerifyCredentialResponse OK = new VerifyCredentialResponse();
+ public static final VerifyCredentialResponse ERROR
+ = new VerifyCredentialResponse(RESPONSE_ERROR, 0, null);
+
+ private int mResponseCode;
+ private byte[] mPayload;
+ private int mTimeout;
+
+ public static final Parcelable.Creator<VerifyCredentialResponse> CREATOR
+ = new Parcelable.Creator<VerifyCredentialResponse>() {
+ @Override
+ public VerifyCredentialResponse createFromParcel(Parcel source) {
+ int responseCode = source.readInt();
+ VerifyCredentialResponse response = new VerifyCredentialResponse(responseCode, 0, null);
+ if (responseCode == RESPONSE_RETRY) {
+ response.setTimeout(source.readInt());
+ } else if (responseCode == RESPONSE_OK) {
+ int size = source.readInt();
+ if (size > 0) {
+ byte[] payload = new byte[size];
+ source.readByteArray(payload);
+ response.setPayload(payload);
+ }
+ }
+ return response;
+ }
+
+ @Override
+ public VerifyCredentialResponse[] newArray(int size) {
+ return new VerifyCredentialResponse[size];
+ }
+
+ };
+
+ public VerifyCredentialResponse() {
+ mResponseCode = RESPONSE_OK;
+ mPayload = null;
+ }
+
+
+ public VerifyCredentialResponse(byte[] payload) {
+ mPayload = payload;
+ mResponseCode = RESPONSE_OK;
+ }
+
+ public VerifyCredentialResponse(int timeout) {
+ mTimeout = timeout;
+ mResponseCode = RESPONSE_RETRY;
+ mPayload = null;
+ }
+
+ private VerifyCredentialResponse(int responseCode, int timeout, byte[] payload) {
+ mResponseCode = responseCode;
+ mTimeout = timeout;
+ mPayload = payload;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mResponseCode);
+ if (mResponseCode == RESPONSE_RETRY) {
+ dest.writeInt(mTimeout);
+ } else if (mResponseCode == RESPONSE_OK) {
+ if (mPayload != null) {
+ dest.writeInt(mPayload.length);
+ dest.writeByteArray(mPayload);
+ }
+ }
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ public byte[] getPayload() {
+ return mPayload;
+ }
+
+ public int getTimeout() {
+ return mTimeout;
+ }
+
+ public int getResponseCode() {
+ return mResponseCode;
+ }
+
+ private void setTimeout(int timeout) {
+ mTimeout = timeout;
+ }
+
+ private void setPayload(byte[] payload) {
+ mPayload = payload;
+ }
+}