summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl4
-rw-r--r--core/java/android/animation/AnimatorInflater.java52
-rw-r--r--core/java/android/animation/KeyframeSet.java4
-rw-r--r--core/java/android/app/ActivityOptions.java5
-rw-r--r--core/java/android/app/ActivityTransitionCoordinator.java24
-rw-r--r--core/java/android/app/ContextImpl.java4
-rw-r--r--core/java/android/app/EnterTransitionCoordinator.java10
-rw-r--r--core/java/android/app/ExitTransitionCoordinator.java10
-rw-r--r--core/java/android/app/IWallpaperManager.aidl6
-rw-r--r--core/java/android/app/Notification.java73
-rw-r--r--core/java/android/app/WallpaperManager.java43
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java26
-rw-r--r--core/java/android/app/backup/BackupManager.java1
-rw-r--r--core/java/android/content/ContentProvider.java22
-rw-r--r--core/java/android/content/pm/LauncherApps.java66
-rw-r--r--core/java/android/content/pm/PackageInstaller.java72
-rw-r--r--core/java/android/content/pm/PackageManager.java32
-rw-r--r--core/java/android/content/pm/PackageParser.java5
-rw-r--r--core/java/android/content/pm/UserInfo.java4
-rw-r--r--core/java/android/hardware/camera2/CameraCaptureSession.java15
-rw-r--r--core/java/android/hardware/camera2/CaptureRequest.java12
-rw-r--r--core/java/android/hardware/camera2/CaptureResult.java12
-rw-r--r--core/java/android/hardware/camera2/dispatch/MethodNameInvoker.java8
-rw-r--r--core/java/android/hardware/camera2/impl/CallbackProxies.java4
-rw-r--r--core/java/android/hardware/camera2/impl/CameraDeviceImpl.java8
-rw-r--r--core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java38
-rw-r--r--core/java/android/hardware/camera2/legacy/LegacyResultMapper.java4
-rw-r--r--core/java/android/os/FileBridge.java18
-rw-r--r--core/java/android/os/Process.java10
-rw-r--r--core/java/android/os/UserManager.java193
-rw-r--r--core/java/android/provider/CallLog.java2
-rw-r--r--core/java/android/provider/Settings.java7
-rw-r--r--core/java/android/service/notification/Condition.java2
-rw-r--r--core/java/android/service/notification/ConditionProviderService.java2
-rw-r--r--core/java/android/service/notification/IStatusBarNotificationHolder.aidl1
-rw-r--r--core/java/android/service/notification/NotificationListenerService.java9
-rw-r--r--core/java/android/service/notification/ZenModeConfig.java23
-rw-r--r--core/java/android/service/voice/AlwaysOnHotwordDetector.java39
-rw-r--r--core/java/android/service/wallpaper/IWallpaperEngine.aidl2
-rw-r--r--core/java/android/service/wallpaper/IWallpaperService.aidl3
-rw-r--r--core/java/android/service/wallpaper/WallpaperService.java172
-rw-r--r--core/java/android/transition/Transition.java18
-rw-r--r--core/java/android/transition/TransitionSet.java2
-rw-r--r--core/java/android/view/AccessibilityInteractionController.java146
-rw-r--r--core/java/android/view/IWindowSession.aidl5
-rw-r--r--core/java/android/view/SurfaceControl.java15
-rw-r--r--core/java/android/view/View.java142
-rw-r--r--core/java/android/view/ViewGroup.java106
-rw-r--r--core/java/android/view/ViewRootImpl.java26
-rw-r--r--core/java/android/view/WindowInsets.java54
-rw-r--r--core/java/android/view/accessibility/AccessibilityInteractionClient.java69
-rw-r--r--core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl5
-rw-r--r--core/java/android/view/accessibility/IAccessibilityInteractionConnectionCallback.aidl9
-rw-r--r--core/java/android/view/inputmethod/InputMethodSubtype.java12
-rw-r--r--core/java/android/widget/AbsListView.java17
-rw-r--r--core/java/android/widget/ActionMenuView.java1
-rw-r--r--core/java/android/widget/GridView.java4
-rw-r--r--core/java/android/widget/ListView.java7
-rw-r--r--core/java/android/widget/TextView.java27
-rw-r--r--core/java/com/android/internal/app/ResolverActivity.java61
-rw-r--r--core/java/com/android/internal/content/PackageHelper.java5
-rw-r--r--core/java/com/android/internal/os/Zygote.java14
-rw-r--r--core/java/com/android/internal/os/ZygoteConnection.java10
-rw-r--r--core/java/com/android/internal/util/ParcelableString.java52
-rw-r--r--core/java/com/android/internal/util/XmlUtils.java10
-rw-r--r--core/java/com/android/internal/widget/ResolverDrawerLayout.java82
-rw-r--r--core/jni/Android.mk1
-rw-r--r--core/jni/AndroidRuntime.cpp2
-rw-r--r--core/jni/android/graphics/pdf/PdfEditor.cpp161
-rw-r--r--core/jni/android_view_SurfaceControl.cpp21
-rw-r--r--core/jni/com_android_internal_net_NetworkStatsFactory.cpp36
-rw-r--r--core/jni/com_android_internal_os_Zygote.cpp18
-rw-r--r--core/res/AndroidManifest.xml4
-rw-r--r--core/res/res/drawable/emulator_circular_window_overlay.xml20
-rw-r--r--core/res/res/layout/alert_dialog_material.xml29
-rw-r--r--core/res/res/layout/alert_dialog_progress_material.xml21
-rw-r--r--core/res/res/layout/dialog_custom_title_material.xml8
-rw-r--r--core/res/res/layout/dialog_title_icons_material.xml14
-rw-r--r--core/res/res/layout/dialog_title_material.xml10
-rw-r--r--core/res/res/layout/notification_template_material_inbox.xml2
-rw-r--r--core/res/res/layout/notification_template_part_line2.xml4
-rw-r--r--core/res/res/layout/notification_template_progressbar.xml23
-rw-r--r--core/res/res/layout/progress_dialog_material.xml16
-rw-r--r--core/res/res/layout/resolve_list_item.xml38
-rw-r--r--core/res/res/layout/resolver_different_item_header.xml34
-rw-r--r--core/res/res/layout/resolver_list.xml29
-rw-r--r--core/res/res/layout/resolver_list_with_default.xml40
-rw-r--r--core/res/res/values-mcc302-mnc220/config.xml2
-rw-r--r--core/res/res/values-mcc310-mnc004/config.xml7
-rw-r--r--core/res/res/values-mcc310-mnc120/config.xml6
-rw-r--r--core/res/res/values-mcc310-mnc150/config.xml6
-rw-r--r--core/res/res/values-mcc310-mnc260/config.xml7
-rw-r--r--core/res/res/values-mcc310-mnc410/config.xml6
-rw-r--r--core/res/res/values-mcc311-mnc190/config.xml7
-rw-r--r--core/res/res/values-mcc311-mnc480/config.xml7
-rw-r--r--core/res/res/values/attrs.xml6
-rw-r--r--core/res/res/values/config.xml31
-rw-r--r--core/res/res/values/dimens_material.xml3
-rw-r--r--core/res/res/values/strings.xml18
-rw-r--r--core/res/res/values/styles_material.xml9
-rw-r--r--core/res/res/values/symbols.xml8
-rw-r--r--core/res/res/values/themes_material.xml4
-rw-r--r--core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestBase.java9
-rw-r--r--core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestRunner.java29
-rw-r--r--core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java37
-rw-r--r--core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/downloadmanagertests/DownloadManagerTestApp.java22
-rw-r--r--core/tests/inputmethodtests/src/android/os/CursorAnchorInfoTest.java36
-rw-r--r--core/tests/inputmethodtests/src/android/os/InputMethodTest.java12
108 files changed, 2067 insertions, 682 deletions
diff --git a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
index 5f7a17d..27a03b6 100644
--- a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
+++ b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
@@ -54,6 +54,10 @@ interface IAccessibilityServiceConnection {
int action, in Bundle arguments, int interactionId,
IAccessibilityInteractionConnectionCallback callback, long threadId);
+ boolean computeClickPointInScreen(int accessibilityWindowId, long accessibilityNodeId,
+ int interactionId, IAccessibilityInteractionConnectionCallback callback,
+ long threadId);
+
AccessibilityWindowInfo getWindow(int windowId);
List<AccessibilityWindowInfo> getWindows();
diff --git a/core/java/android/animation/AnimatorInflater.java b/core/java/android/animation/AnimatorInflater.java
index f4e4671..25417ed 100644
--- a/core/java/android/animation/AnimatorInflater.java
+++ b/core/java/android/animation/AnimatorInflater.java
@@ -92,21 +92,27 @@ public class AnimatorInflater {
*/
public static Animator loadAnimator(Resources resources, Theme theme, int id)
throws NotFoundException {
+ return loadAnimator(resources, theme, id, 1);
+ }
+
+ /** @hide */
+ public static Animator loadAnimator(Resources resources, Theme theme, int id,
+ float pathErrorScale) throws NotFoundException {
XmlResourceParser parser = null;
try {
parser = resources.getAnimation(id);
- return createAnimatorFromXml(resources, theme, parser);
+ return createAnimatorFromXml(resources, theme, parser, pathErrorScale);
} catch (XmlPullParserException ex) {
Resources.NotFoundException rnf =
new Resources.NotFoundException("Can't load animation resource ID #0x" +
- Integer.toHexString(id));
+ Integer.toHexString(id));
rnf.initCause(ex);
throw rnf;
} catch (IOException ex) {
Resources.NotFoundException rnf =
new Resources.NotFoundException("Can't load animation resource ID #0x" +
- Integer.toHexString(id));
+ Integer.toHexString(id));
rnf.initCause(ex);
throw rnf;
} finally {
@@ -177,7 +183,7 @@ public class AnimatorInflater {
}
if (animator == null) {
animator = createAnimatorFromXml(context.getResources(),
- context.getTheme(), parser);
+ context.getTheme(), parser, 1f);
}
if (animator == null) {
@@ -248,9 +254,11 @@ public class AnimatorInflater {
* @param arrayAnimator Incoming typed array for Animator's attributes.
* @param arrayObjectAnimator Incoming typed array for Object Animator's
* attributes.
+ * @param pixelSize The relative pixel size, used to calculate the
+ * maximum error for path animations.
*/
private static void parseAnimatorFromTypeArray(ValueAnimator anim,
- TypedArray arrayAnimator, TypedArray arrayObjectAnimator) {
+ TypedArray arrayAnimator, TypedArray arrayObjectAnimator, float pixelSize) {
long duration = arrayAnimator.getInt(R.styleable.Animator_duration, 300);
long startDelay = arrayAnimator.getInt(R.styleable.Animator_startOffset, 0);
@@ -303,7 +311,7 @@ public class AnimatorInflater {
}
if (arrayObjectAnimator != null) {
- setupObjectAnimator(anim, arrayObjectAnimator, getFloats);
+ setupObjectAnimator(anim, arrayObjectAnimator, getFloats, pixelSize);
}
}
@@ -351,9 +359,11 @@ public class AnimatorInflater {
* @param anim The target Animator which will be updated.
* @param arrayObjectAnimator TypedArray for the ObjectAnimator.
* @param getFloats True if the value type is float.
+ * @param pixelSize The relative pixel size, used to calculate the
+ * maximum error for path animations.
*/
private static void setupObjectAnimator(ValueAnimator anim, TypedArray arrayObjectAnimator,
- boolean getFloats) {
+ boolean getFloats, float pixelSize) {
ObjectAnimator oa = (ObjectAnimator) anim;
String pathData = arrayObjectAnimator.getString(R.styleable.PropertyAnimator_pathData);
@@ -370,7 +380,8 @@ public class AnimatorInflater {
+ " propertyXName or propertyYName is needed for PathData");
} else {
Path path = PathParser.createPathFromPathData(pathData);
- PathKeyframes keyframeSet = KeyframeSet.ofPath(path);
+ float error = 0.5f * pixelSize; // max half a pixel error
+ PathKeyframes keyframeSet = KeyframeSet.ofPath(path, error);
Keyframes xKeyframes;
Keyframes yKeyframes;
if (getFloats) {
@@ -487,13 +498,15 @@ public class AnimatorInflater {
}
}
- private static Animator createAnimatorFromXml(Resources res, Theme theme, XmlPullParser parser)
+ private static Animator createAnimatorFromXml(Resources res, Theme theme, XmlPullParser parser,
+ float pixelSize)
throws XmlPullParserException, IOException {
- return createAnimatorFromXml(res, theme, parser, Xml.asAttributeSet(parser), null, 0);
+ return createAnimatorFromXml(res, theme, parser, Xml.asAttributeSet(parser), null, 0,
+ pixelSize);
}
private static Animator createAnimatorFromXml(Resources res, Theme theme, XmlPullParser parser,
- AttributeSet attrs, AnimatorSet parent, int sequenceOrdering)
+ AttributeSet attrs, AnimatorSet parent, int sequenceOrdering, float pixelSize)
throws XmlPullParserException, IOException {
Animator anim = null;
@@ -513,9 +526,9 @@ public class AnimatorInflater {
String name = parser.getName();
if (name.equals("objectAnimator")) {
- anim = loadObjectAnimator(res, theme, attrs);
+ anim = loadObjectAnimator(res, theme, attrs, pixelSize);
} else if (name.equals("animator")) {
- anim = loadAnimator(res, theme, attrs, null);
+ anim = loadAnimator(res, theme, attrs, null, pixelSize);
} else if (name.equals("set")) {
anim = new AnimatorSet();
TypedArray a;
@@ -526,7 +539,8 @@ public class AnimatorInflater {
}
int ordering = a.getInt(R.styleable.AnimatorSet_ordering,
TOGETHER);
- createAnimatorFromXml(res, theme, parser, attrs, (AnimatorSet) anim, ordering);
+ createAnimatorFromXml(res, theme, parser, attrs, (AnimatorSet) anim, ordering,
+ pixelSize);
a.recycle();
} else {
throw new RuntimeException("Unknown animator name: " + parser.getName());
@@ -556,11 +570,11 @@ public class AnimatorInflater {
}
- private static ObjectAnimator loadObjectAnimator(Resources res, Theme theme, AttributeSet attrs)
- throws NotFoundException {
+ private static ObjectAnimator loadObjectAnimator(Resources res, Theme theme, AttributeSet attrs,
+ float pathErrorScale) throws NotFoundException {
ObjectAnimator anim = new ObjectAnimator();
- loadAnimator(res, theme, attrs, anim);
+ loadAnimator(res, theme, attrs, anim, pathErrorScale);
return anim;
}
@@ -575,7 +589,7 @@ public class AnimatorInflater {
* ObjectAnimator
*/
private static ValueAnimator loadAnimator(Resources res, Theme theme,
- AttributeSet attrs, ValueAnimator anim)
+ AttributeSet attrs, ValueAnimator anim, float pathErrorScale)
throws NotFoundException {
TypedArray arrayAnimator = null;
@@ -601,7 +615,7 @@ public class AnimatorInflater {
anim = new ValueAnimator();
}
- parseAnimatorFromTypeArray(anim, arrayAnimator, arrayObjectAnimator);
+ parseAnimatorFromTypeArray(anim, arrayAnimator, arrayObjectAnimator, pathErrorScale);
final int resID =
arrayAnimator.getResourceId(R.styleable.Animator_interpolator, 0);
diff --git a/core/java/android/animation/KeyframeSet.java b/core/java/android/animation/KeyframeSet.java
index fc9bbb1..8d15db2 100644
--- a/core/java/android/animation/KeyframeSet.java
+++ b/core/java/android/animation/KeyframeSet.java
@@ -154,6 +154,10 @@ class KeyframeSet implements Keyframes {
return new PathKeyframes(path);
}
+ public static PathKeyframes ofPath(Path path, float error) {
+ return new PathKeyframes(path, error);
+ }
+
/**
* Sets the TypeEvaluator to be used when calculating animated values. This object
* is required only for KeyframeSets that are not either IntKeyframeSet or FloatKeyframeSet,
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index ffffb6c..213c7f6 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -520,11 +520,6 @@ public class ActivityOptions {
return opts;
}
- @Deprecated
- public static ActivityOptions makeLaunchTaskBehindAnimation() {
- return makeTaskLaunchBehind();
- }
-
/** @hide */
public boolean getLaunchTaskBehind() {
return mAnimationType == ANIM_LAUNCH_TASK_BEHIND;
diff --git a/core/java/android/app/ActivityTransitionCoordinator.java b/core/java/android/app/ActivityTransitionCoordinator.java
index 9e80a4b..43fa3f0 100644
--- a/core/java/android/app/ActivityTransitionCoordinator.java
+++ b/core/java/android/app/ActivityTransitionCoordinator.java
@@ -205,6 +205,7 @@ abstract class ActivityTransitionCoordinator extends ResultReceiver {
private boolean mIsStartingTransition;
private ArrayList<GhostViewListeners> mGhostViewListeners =
new ArrayList<GhostViewListeners>();
+ private ArrayMap<View, Float> mOriginalAlphas = new ArrayMap<View, Float>();
public ActivityTransitionCoordinator(Window window,
ArrayList<String> allSharedElementNames,
@@ -580,6 +581,7 @@ abstract class ActivityTransitionCoordinator extends ResultReceiver {
mWindow = null;
mSharedElements.clear();
mTransitioningViews.clear();
+ mOriginalAlphas.clear();
mResultReceiver = null;
mPendingTransition = null;
mListener = null;
@@ -589,10 +591,28 @@ abstract class ActivityTransitionCoordinator extends ResultReceiver {
return getWindow().getTransitionBackgroundFadeDuration();
}
- protected static void setTransitionAlpha(ArrayList<View> views, float alpha) {
+ protected void hideViews(ArrayList<View> views) {
int count = views.size();
for (int i = 0; i < count; i++) {
- views.get(i).setTransitionAlpha(alpha);
+ View view = views.get(i);
+ if (!mOriginalAlphas.containsKey(view)) {
+ mOriginalAlphas.put(view, view.getAlpha());
+ }
+ view.setAlpha(0f);
+ }
+ }
+
+ protected void showViews(ArrayList<View> views, boolean setTransitionAlpha) {
+ int count = views.size();
+ for (int i = 0; i < count; i++) {
+ View view = views.get(i);
+ Float alpha = mOriginalAlphas.remove(view);
+ if (alpha != null) {
+ view.setAlpha(alpha);
+ }
+ if (setTransitionAlpha) {
+ view.setTransitionAlpha(1f);
+ }
}
}
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index cc5c643..91a0aed 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -2121,9 +2121,7 @@ class ContextImpl extends Context {
public Context createPackageContextAsUser(String packageName, int flags, UserHandle user)
throws NameNotFoundException {
final boolean restricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
- if ((packageName.equals("system") || packageName.equals("android"))
- && user.getIdentifier() == UserHandle.getUserId(
- mPackageInfo.getApplicationInfo().uid)) {
+ if (packageName.equals("system") || packageName.equals("android")) {
return new ContextImpl(this, mMainThread, mPackageInfo, mActivityToken,
user, restricted, mDisplay, mOverrideConfiguration);
}
diff --git a/core/java/android/app/EnterTransitionCoordinator.java b/core/java/android/app/EnterTransitionCoordinator.java
index f432c49..9c7728e 100644
--- a/core/java/android/app/EnterTransitionCoordinator.java
+++ b/core/java/android/app/EnterTransitionCoordinator.java
@@ -112,9 +112,9 @@ class EnterTransitionCoordinator extends ActivityTransitionCoordinator {
protected void viewsReady(ArrayMap<String, View> sharedElements) {
super.viewsReady(sharedElements);
mIsReadyForTransition = true;
- setTransitionAlpha(mSharedElements, 0);
+ hideViews(mSharedElements);
if (getViewsTransition() != null) {
- setTransitionAlpha(mTransitioningViews, 0);
+ hideViews(mTransitioningViews);
}
if (mIsReturning) {
sendSharedElementDestination();
@@ -240,7 +240,7 @@ class EnterTransitionCoordinator extends ActivityTransitionCoordinator {
if (!mIsCanceled) {
mIsCanceled = true;
if (getViewsTransition() == null || mIsViewsTransitionStarted) {
- setTransitionAlpha(mSharedElements, 1);
+ showViews(mSharedElements, true);
} else {
mTransitioningViews.addAll(mSharedElements);
}
@@ -300,7 +300,7 @@ class EnterTransitionCoordinator extends ActivityTransitionCoordinator {
// Now start shared element transition
ArrayList<View> sharedElementSnapshots = createSnapshots(sharedElementState,
mSharedElementNames);
- setTransitionAlpha(mSharedElements, 1);
+ showViews(mSharedElements, true);
scheduleSetSharedElementEnd(sharedElementSnapshots);
ArrayList<SharedElementOriginalState> originalImageViewState =
setSharedElementState(sharedElementState, sharedElementSnapshots);
@@ -411,7 +411,7 @@ class EnterTransitionCoordinator extends ActivityTransitionCoordinator {
@Override
public void onTransitionStart(Transition transition) {
mEnterViewsTransition = transition;
- setTransitionAlpha(mTransitioningViews, 1);
+ showViews(mTransitioningViews, false);
super.onTransitionStart(transition);
}
diff --git a/core/java/android/app/ExitTransitionCoordinator.java b/core/java/android/app/ExitTransitionCoordinator.java
index a59a927..e85ec63 100644
--- a/core/java/android/app/ExitTransitionCoordinator.java
+++ b/core/java/android/app/ExitTransitionCoordinator.java
@@ -126,8 +126,8 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator {
}
public void resetViews() {
- setTransitionAlpha(mTransitioningViews, 1);
- setTransitionAlpha(mSharedElements, 1);
+ showViews(mTransitioningViews, true);
+ showViews(mSharedElements, true);
mIsHidden = true;
if (!mIsReturning && getDecor() != null) {
getDecor().suppressLayout(false);
@@ -187,7 +187,7 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator {
private void hideSharedElements() {
moveSharedElementsFromOverlay();
if (!mIsHidden) {
- setTransitionAlpha(mSharedElements, 0);
+ hideViews(mSharedElements);
}
mSharedElementsHidden = true;
finishIfNecessary();
@@ -296,7 +296,7 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator {
transition.removeListener(this);
exitTransitionComplete();
if (mIsHidden) {
- setTransitionAlpha(mTransitioningViews, 1);
+ showViews(mTransitioningViews, true);
}
if (mSharedElementBundle != null) {
delayCancel();
@@ -323,7 +323,7 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator {
transition.removeListener(this);
sharedElementTransitionComplete();
if (mIsHidden) {
- setTransitionAlpha(mSharedElements, 1);
+ showViews(mSharedElements, true);
}
}
});
diff --git a/core/java/android/app/IWallpaperManager.aidl b/core/java/android/app/IWallpaperManager.aidl
index 181eb63..3b5900b 100644
--- a/core/java/android/app/IWallpaperManager.aidl
+++ b/core/java/android/app/IWallpaperManager.aidl
@@ -16,6 +16,7 @@
package android.app;
+import android.graphics.Rect;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.app.IWallpaperManagerCallback;
@@ -73,6 +74,11 @@ interface IWallpaperManager {
int getHeightHint();
/**
+ * Sets extra padding that we would like the wallpaper to have outside of the display.
+ */
+ void setDisplayPadding(in Rect padding);
+
+ /**
* Returns the name of the wallpaper. Private API.
*/
String getName();
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 1083943..f9e4895 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -545,8 +545,26 @@ public class Notification implements Parcelable
*/
public int visibility;
+ /**
+ * Notification visibility: Show this notification in its entirety on all lockscreens.
+ *
+ * {@see #visibility}
+ */
public static final int VISIBILITY_PUBLIC = 1;
+
+ /**
+ * Notification visibility: Show this notification on all lockscreens, but conceal sensitive or
+ * private information on secure lockscreens.
+ *
+ * {@see #visibility}
+ */
public static final int VISIBILITY_PRIVATE = 0;
+
+ /**
+ * Notification visibility: Do not reveal any part of this notification on a secure lockscreen.
+ *
+ * {@see #visibility}
+ */
public static final int VISIBILITY_SECRET = -1;
/**
@@ -824,6 +842,13 @@ public class Notification implements Parcelable
public static final String EXTRA_COMPACT_ACTIONS = "android.compactActions";
/**
+ * {@link #extras} key: the user that built the notification.
+ *
+ * @hide
+ */
+ public static final String EXTRA_ORIGINATING_USERID = "android.originatingUserId";
+
+ /**
* Value for {@link #EXTRA_AS_HEADS_UP} that indicates this notification should not be
* displayed in the heads up space.
*
@@ -1862,6 +1887,11 @@ public class Notification implements Parcelable
private int mColor = COLOR_DEFAULT;
/**
+ * The user that built the notification originally.
+ */
+ private int mOriginatingUserId;
+
+ /**
* Contains extras related to rebuilding during the build phase.
*/
private Bundle mRebuildBundle = new Bundle();
@@ -2581,7 +2611,7 @@ public class Notification implements Parcelable
// Note: This assumes that the current user can read the profile badge of the
// originating user.
return mContext.getPackageManager().getUserBadgeForDensity(
- new UserHandle(mContext.getUserId()), 0);
+ new UserHandle(mOriginatingUserId), 0);
}
private Bitmap getProfileBadge() {
@@ -2721,9 +2751,9 @@ public class Notification implements Parcelable
} else {
contentView.setViewVisibility(R.id.text2, View.GONE);
if (hasProgress && (mProgressMax != 0 || mProgressIndeterminate)) {
+ contentView.setViewVisibility(R.id.progress, View.VISIBLE);
contentView.setProgressBar(
R.id.progress, mProgressMax, mProgress, mProgressIndeterminate);
- contentView.setViewVisibility(R.id.progress, View.VISIBLE);
showLine2 = true;
} else {
contentView.setViewVisibility(R.id.progress, View.GONE);
@@ -3052,6 +3082,7 @@ public class Notification implements Parcelable
*/
public void populateExtras(Bundle extras) {
// Store original information used in the construction of this object
+ extras.putInt(EXTRA_ORIGINATING_USERID, mOriginatingUserId);
extras.putParcelable(EXTRA_REBUILD_CONTEXT_APPLICATION_INFO,
mContext.getApplicationInfo());
extras.putCharSequence(EXTRA_TITLE, mContentTitle);
@@ -3283,6 +3314,7 @@ public class Notification implements Parcelable
// Extras.
Bundle extras = n.extras;
+ mOriginatingUserId = extras.getInt(EXTRA_ORIGINATING_USERID);
mContentTitle = extras.getCharSequence(EXTRA_TITLE);
mContentText = extras.getCharSequence(EXTRA_TEXT);
mSubText = extras.getCharSequence(EXTRA_SUB_TEXT);
@@ -3315,6 +3347,7 @@ public class Notification implements Parcelable
* object.
*/
public Notification build() {
+ mOriginatingUserId = mContext.getUserId();
mHasThreeLines = hasThreeLines();
Notification n = buildUnstyled();
@@ -3386,8 +3419,16 @@ public class Notification implements Parcelable
*/
public static abstract class Style {
private CharSequence mBigContentTitle;
- private CharSequence mSummaryText = null;
- private boolean mSummaryTextSet = false;
+
+ /**
+ * @hide
+ */
+ protected CharSequence mSummaryText = null;
+
+ /**
+ * @hide
+ */
+ protected boolean mSummaryTextSet = false;
protected Builder mBuilder;
@@ -3679,6 +3720,11 @@ public class Notification implements Parcelable
* @see Notification#bigContentView
*/
public static class BigTextStyle extends Style {
+
+ private static final int MAX_LINES = 13;
+ private static final int LINES_CONSUMED_BY_ACTIONS = 3;
+ private static final int LINES_CONSUMED_BY_SUMMARY = 2;
+
private CharSequence mBigText;
public BigTextStyle() {
@@ -3745,6 +3791,7 @@ public class Notification implements Parcelable
contentView.setTextViewText(R.id.big_text, mBuilder.processLegacyText(mBigText));
contentView.setViewVisibility(R.id.big_text, View.VISIBLE);
+ contentView.setInt(R.id.big_text, "setMaxLines", calculateMaxLines());
contentView.setViewVisibility(R.id.text2, View.GONE);
applyTopPadding(contentView);
@@ -3756,6 +3803,24 @@ public class Notification implements Parcelable
return contentView;
}
+ private int calculateMaxLines() {
+ int lineCount = MAX_LINES;
+ boolean hasActions = mBuilder.mActions.size() > 0;
+ boolean hasSummary = (mSummaryTextSet ? mSummaryText : mBuilder.mSubText) != null;
+ if (hasActions) {
+ lineCount -= LINES_CONSUMED_BY_ACTIONS;
+ }
+ if (hasSummary) {
+ lineCount -= LINES_CONSUMED_BY_SUMMARY;
+ }
+
+ // If we have less top padding at the top, we can fit less lines.
+ if (!mBuilder.mHasThreeLines) {
+ lineCount--;
+ }
+ return lineCount;
+ }
+
/**
* @hide
*/
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index 48ff5b6..8bfe6d3 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -16,6 +16,7 @@
package android.app;
+import android.annotation.SystemApi;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
@@ -951,6 +952,48 @@ public class WallpaperManager {
}
/**
+ * Specify extra padding that the wallpaper should have outside of the display.
+ * That is, the given padding supplies additional pixels the wallpaper should extend
+ * outside of the display itself.
+ * @param padding The number of pixels the wallpaper should extend beyond the display,
+ * on its left, top, right, and bottom sides.
+ * @hide
+ */
+ @SystemApi
+ public void setDisplayPadding(Rect padding) {
+ try {
+ if (sGlobals.mService == null) {
+ Log.w(TAG, "WallpaperService not running");
+ } else {
+ sGlobals.mService.setDisplayPadding(padding);
+ }
+ } catch (RemoteException e) {
+ // Ignore
+ }
+ }
+
+ /**
+ * Apply a raw offset to the wallpaper window. Should only be used in
+ * combination with {@link #setDisplayPadding(android.graphics.Rect)} when you
+ * have ensured that the wallpaper will extend outside of the display area so that
+ * it can be moved without leaving part of the display uncovered.
+ * @param x The offset, in pixels, to apply to the left edge.
+ * @param y The offset, in pixels, to apply to the top edge.
+ * @hide
+ */
+ @SystemApi
+ public void setDisplayOffset(IBinder windowToken, int x, int y) {
+ try {
+ //Log.v(TAG, "Sending new wallpaper display offsets from app...");
+ WindowManagerGlobal.getWindowSession().setWallpaperDisplayOffset(
+ windowToken, x, y);
+ //Log.v(TAG, "...app returning after sending display offset!");
+ } catch (RemoteException e) {
+ // Ignore.
+ }
+ }
+
+ /**
* Set the position of the current wallpaper within any larger space, when
* that wallpaper is visible behind the given window. The X and Y offsets
* are floating point numbers ranging from 0 to 1, representing where the
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 112fc82..5b02313 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -97,8 +97,7 @@ public class DevicePolicyManager {
* Provisioning adds a managed profile and sets the mdm as the profile owner who has full
* control over the profile
*
- * <p>This intent must contain the extras {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME}
- * {@link #EXTRA_PROVISIONING_DEFAULT_MANAGED_PROFILE_NAME} and {@link #EXTRA_DEVICE_ADMIN}.
+ * <p>This intent must contain the extra {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME}.
*
* <p> When managed provisioning has completed, an intent of the type
* {@link DeviceAdminReceiver#ACTION_PROFILE_PROVISIONING_COMPLETE} is broadcasted to the
@@ -142,18 +141,15 @@ public class DevicePolicyManager {
= "android.app.extra.deviceAdminPackageName";
/**
- * A String extra holding the default name of the profile that is created during managed profile
- * provisioning.
+ * A String extra that, holds the email address of the account which a managed profile is
+ * created for. Used with {@link #ACTION_PROVISION_MANAGED_PROFILE} and
+ * {@link DeviceAdminReceiver#ACTION_PROFILE_PROVISIONING_COMPLETE}.
*
- * <p>Use with {@link #ACTION_PROVISION_MANAGED_PROFILE}
- */
- public static final String EXTRA_PROVISIONING_DEFAULT_MANAGED_PROFILE_NAME
- = "android.app.extra.PROVISIONING_DEFAULT_MANAGED_PROFILE_NAME";
-
- /**
- * A bundle key, used in the bundle extra {@link #EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE}. The
- * corresponding value holds the email address of the account which the managed profile is
- * created for.
+ * <p> If the {@link #ACTION_PROVISION_MANAGED_PROFILE} intent that starts managed provisioning
+ * contains this extra, it is forwarded in the
+ * {@link DeviceAdminReceiver#ACTION_PROFILE_PROVISIONING_COMPLETE} intent to the mobile
+ * device management application that was set as the profile owner during provisioning.
+ * It is usually used to avoid that the user has to enter their email address twice.
*/
public static final String KEY_PROVISIONING_EMAIL_ADDRESS
= "android.app.key.PROVISIONING_EMAIL_ADDRESS";
@@ -441,13 +437,13 @@ public class DevicePolicyManager {
* Flag used by {@link #addCrossProfileIntentFilter} to allow access of certain intents from a
* managed profile to its parent.
*/
- public static int FLAG_PARENT_CAN_ACCESS_MANAGED = 0x0001;
+ public static final int FLAG_PARENT_CAN_ACCESS_MANAGED = 0x0001;
/**
* Flag used by {@link #addCrossProfileIntentFilter} to allow access of certain intents from the
* parent to its managed profile.
*/
- public static int FLAG_MANAGED_CAN_ACCESS_PARENT = 0x0002;
+ public static final int FLAG_MANAGED_CAN_ACCESS_PARENT = 0x0002;
/**
* Return true if the given administrator component is currently
diff --git a/core/java/android/app/backup/BackupManager.java b/core/java/android/app/backup/BackupManager.java
index 1bb4eba..9151a16 100644
--- a/core/java/android/app/backup/BackupManager.java
+++ b/core/java/android/app/backup/BackupManager.java
@@ -218,6 +218,7 @@ public class BackupManager {
*/
@SystemApi
public boolean isBackupEnabled() {
+ checkServiceBinder();
if (sService != null) {
try {
return sService.isBackupEnabled();
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index fde8b2e..2853c58 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -639,12 +639,14 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
* @param authorities the semi-colon separated authorities of the ContentProvider.
*/
protected final void setAuthorities(String authorities) {
- if (authorities.indexOf(';') == -1) {
- mAuthority = authorities;
- mAuthorities = null;
- } else {
- mAuthority = null;
- mAuthorities = authorities.split(";");
+ if (authorities != null) {
+ if (authorities.indexOf(';') == -1) {
+ mAuthority = authorities;
+ mAuthorities = null;
+ } else {
+ mAuthority = null;
+ mAuthorities = authorities.split(";");
+ }
}
}
@@ -653,9 +655,11 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
if (mAuthority != null) {
return mAuthority.equals(authority);
}
- int length = mAuthorities.length;
- for (int i = 0; i < length; i++) {
- if (mAuthorities[i].equals(authority)) return true;
+ if (mAuthorities != null) {
+ int length = mAuthorities.length;
+ for (int i = 0; i < length; i++) {
+ if (mAuthorities[i].equals(authority)) return true;
+ }
}
return false;
}
diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java
index f9370b3..d49bc50 100644
--- a/core/java/android/content/pm/LauncherApps.java
+++ b/core/java/android/content/pm/LauncherApps.java
@@ -278,21 +278,21 @@ public class LauncherApps {
/**
- * Adds a callback for changes to packages in current and managed profiles.
+ * Registers a callback for changes to packages in current and managed profiles.
*
- * @param callback The callback to add.
+ * @param callback The callback to register.
*/
- public void addCallback(Callback callback) {
- addCallback(callback, null);
+ public void registerCallback(Callback callback) {
+ registerCallback(callback, null);
}
/**
- * Adds a callback for changes to packages in current and managed profiles.
+ * Registers a callback for changes to packages in current and managed profiles.
*
- * @param callback The callback to add.
+ * @param callback The callback to register.
* @param handler that should be used to post callbacks on, may be null.
*/
- public void addCallback(Callback callback, Handler handler) {
+ public void registerCallback(Callback callback, Handler handler) {
synchronized (this) {
if (callback != null && !mCallbacks.contains(callback)) {
boolean addedFirstCallback = mCallbacks.size() == 0;
@@ -308,12 +308,12 @@ public class LauncherApps {
}
/**
- * Removes a callback that was previously added.
+ * Unregisters a callback that was previously registered.
*
- * @param callback The callback to remove.
- * @see #addCallback(Callback)
+ * @param callback The callback to unregister.
+ * @see #registerCallback(Callback)
*/
- public void removeCallback(Callback callback) {
+ public void unregisterCallback(Callback callback) {
synchronized (this) {
removeCallbackLocked(callback);
if (mCallbacks.size() == 0) {
@@ -500,44 +500,12 @@ public class LauncherApps {
}
}
- /** Remove after unbundled apps have migrated STOP SHIP */
- public static abstract class OnAppsChangedCallback extends Callback {
- }
-
- /** Remove after unbundled apps have migrated STOP SHIP */
- public void addOnAppsChangedCallback(OnAppsChangedCallback callback) {
- addCallback(callback, null);
- }
-
- /** Remove after unbundled apps have migrated STOP SHIP */
- public void addOnAppsChangedCallback(OnAppsChangedCallback callback, Handler handler) {
- addCallback(callback, handler);
- }
-
- /** Remove after unbundled apps have migrated STOP SHIP */
- public void removeOnAppsChangedCallback(OnAppsChangedCallback callback) {
- removeCallback(callback);
- }
-
- /** Remove after unbundled apps have migrated STOP SHIP */
- public void startActivityForProfile(ComponentName component, UserHandle user, Rect sourceBounds,
- Bundle opts) {
- startMainActivity(component, user, sourceBounds, opts);
- }
-
- /** Remove after unbundled apps have migrated STOP SHIP */
- public void showAppDetailsForProfile(ComponentName component, UserHandle user,
- Rect sourceBounds, Bundle opts) {
- startAppDetailsActivity(component, user, sourceBounds, opts);
- }
-
- /** Remove after unbundled apps have migrated STOP SHIP */
- public boolean isPackageEnabledForProfile(String packageName, UserHandle user) {
- return isPackageEnabled(packageName, user);
+ /** STOPSHIP remove when launcher 3 has been updated */
+ public void addCallback(Callback callback) {
+ registerCallback(callback);
}
-
- /** Remove after unbundled apps have migrated STOP SHIP */
- public boolean isActivityEnabledForProfile(ComponentName component, UserHandle user) {
- return isActivityEnabled(component, user);
+ /** STOPSHIP remove when launcher 3 has been updated */
+ public void removeCallback(Callback callback) {
+ unregisterCallback(callback);
}
}
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 0a211cf..06d4c4a 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -285,6 +285,9 @@ public class PackageInstaller {
*
* @throws IOException if parameters were unsatisfiable, such as lack of
* disk space or unavailable media.
+ * @throws SecurityException when installation services are unavailable,
+ * such as when called from a restricted user.
+ * @throws IllegalArgumentException when {@link SessionParams} is invalid.
* @return positive, non-zero unique ID that represents the created session.
* This ID remains consistent across device reboots until the
* session is finalized. IDs are not reused during a given boot.
@@ -303,6 +306,11 @@ public class PackageInstaller {
/**
* Open an existing session to actively perform work. To succeed, the caller
* must be the owner of the install session.
+ *
+ * @throws IOException if parameters were unsatisfiable, such as lack of
+ * disk space or unavailable media.
+ * @throws SecurityException when the caller does not own the session, or
+ * the session is invalid.
*/
public @NonNull Session openSession(int sessionId) throws IOException {
try {
@@ -319,6 +327,9 @@ public class PackageInstaller {
* Update the icon representing the app being installed in a specific
* session. This should be roughly
* {@link ActivityManager#getLauncherLargeIconSize()} in both dimensions.
+ *
+ * @throws SecurityException when the caller does not own the session, or
+ * the session is invalid.
*/
public void updateSessionAppIcon(int sessionId, @Nullable Bitmap appIcon) {
try {
@@ -331,6 +342,9 @@ public class PackageInstaller {
/**
* Update the label representing the app being installed in a specific
* session.
+ *
+ * @throws SecurityException when the caller does not own the session, or
+ * the session is invalid.
*/
public void updateSessionAppLabel(int sessionId, @Nullable CharSequence appLabel) {
try {
@@ -341,6 +355,15 @@ public class PackageInstaller {
}
}
+ /**
+ * Completely abandon the given session, destroying all staged data and
+ * rendering it invalid. Abandoned sessions will be reported to
+ * {@link SessionCallback} listeners as failures. This is equivalent to
+ * opening the session and calling {@link Session#abandon()}.
+ *
+ * @throws SecurityException when the caller does not own the session, or
+ * the session is invalid.
+ */
public void abandonSession(int sessionId) {
try {
mInstaller.abandonSession(sessionId);
@@ -350,7 +373,11 @@ public class PackageInstaller {
}
/**
- * Return details for a specific session.
+ * Return details for a specific session. No special permissions are
+ * required to retrieve these details.
+ *
+ * @return details for the requested session, or {@code null} if the session
+ * does not exist.
*/
public @Nullable SessionInfo getSessionInfo(int sessionId) {
try {
@@ -361,7 +388,7 @@ public class PackageInstaller {
}
/**
- * Return list of all active install sessions, regardless of the installer.
+ * Return list of all known install sessions, regardless of the installer.
*/
public @NonNull List<SessionInfo> getAllSessions() {
final ApplicationInfo info = mContext.getApplicationInfo();
@@ -379,7 +406,7 @@ public class PackageInstaller {
}
/**
- * Return list of all install sessions owned by the calling app.
+ * Return list of all known install sessions owned by the calling app.
*/
public @NonNull List<SessionInfo> getMySessions() {
try {
@@ -547,7 +574,8 @@ public class PackageInstaller {
}
/**
- * Register to watch for session lifecycle events.
+ * Register to watch for session lifecycle events. No special permissions
+ * are required to watch for these events.
*/
public void registerSessionCallback(@NonNull SessionCallback callback) {
registerSessionCallback(callback, new Handler());
@@ -560,7 +588,8 @@ public class PackageInstaller {
}
/**
- * Register to watch for session lifecycle events.
+ * Register to watch for session lifecycle events. No special permissions
+ * are required to watch for these events.
*
* @param handler to dispatch callback events through, otherwise uses
* calling thread.
@@ -593,7 +622,7 @@ public class PackageInstaller {
}
/**
- * Unregister an existing callback.
+ * Unregister a previously registered callback.
*/
public void unregisterSessionCallback(@NonNull SessionCallback callback) {
synchronized (mDelegates) {
@@ -686,6 +715,12 @@ public class PackageInstaller {
* start at the beginning of the file.
* @param lengthBytes total size of the file being written, used to
* preallocate the underlying disk space, or -1 if unknown.
+ * The system may clear various caches as needed to allocate
+ * this space.
+ * @throws IOException if trouble opening the file for writing, such as
+ * lack of disk space or unavailable media.
+ * @throws SecurityException if called after the session has been
+ * committed or abandoned.
*/
public @NonNull OutputStream openWrite(@NonNull String name, long offsetBytes,
long lengthBytes) throws IOException {
@@ -719,6 +754,9 @@ public class PackageInstaller {
* <p>
* This returns all names which have been previously written through
* {@link #openWrite(String, long, long)} as part of this session.
+ *
+ * @throws SecurityException if called after the session has been
+ * committed or abandoned.
*/
public @NonNull String[] getNames() throws IOException {
try {
@@ -738,6 +776,9 @@ public class PackageInstaller {
* through {@link #openWrite(String, long, long)} as part of this
* session. For example, this stream may be used to calculate a
* {@link MessageDigest} of a written APK before committing.
+ *
+ * @throws SecurityException if called after the session has been
+ * committed or abandoned.
*/
public @NonNull InputStream openRead(@NonNull String name) throws IOException {
try {
@@ -759,6 +800,9 @@ public class PackageInstaller {
* Once this method is called, no additional mutations may be performed
* on the session. If the device reboots before the session has been
* finalized, you may commit the session again.
+ *
+ * @throws SecurityException if streams opened through
+ * {@link #openWrite(String, long, long)} are still open.
*/
public void commit(@NonNull IntentSender statusReceiver) {
try {
@@ -783,7 +827,9 @@ public class PackageInstaller {
/**
* Completely abandon this session, destroying all staged data and
- * rendering it invalid.
+ * rendering it invalid. Abandoned sessions will be reported to
+ * {@link SessionCallback} listeners as failures. This is equivalent to
+ * opening the session and calling {@link Session#abandon()}.
*/
public void abandon() {
try {
@@ -937,6 +983,18 @@ public class PackageInstaller {
}
/** {@hide} */
+ public void setInstallFlagsInternal() {
+ installFlags |= PackageManager.INSTALL_INTERNAL;
+ installFlags &= ~PackageManager.INSTALL_EXTERNAL;
+ }
+
+ /** {@hide} */
+ public void setInstallFlagsExternal() {
+ installFlags |= PackageManager.INSTALL_EXTERNAL;
+ installFlags &= ~PackageManager.INSTALL_INTERNAL;
+ }
+
+ /** {@hide} */
public void dump(IndentingPrintWriter pw) {
pw.printPair("mode", mode);
pw.printHexPair("installFlags", installFlags);
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 748fca2..5ce968b 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -201,12 +201,6 @@ public abstract class PackageManager {
public static final int MATCH_DEFAULT_ONLY = 0x00010000;
/**
- * Resolution and querying flag: do not resolve intents cross-profile.
- * @hide
- */
- public static final int NO_CROSS_PROFILE = 0x00020000;
-
- /**
* Flag for {@link addCrossProfileIntentFilter}: if this flag is set:
* when resolving an intent that matches the {@link CrossProfileIntentFilter}, the current
* profile will be skipped.
@@ -1531,6 +1525,22 @@ public abstract class PackageManager {
/**
* Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}:
+ * The device supports verified boot.
+ */
+ @SdkConstant(SdkConstantType.FEATURE)
+ public static final String FEATURE_VERIFIED_BOOT = "android.software.verified_boot";
+
+ /**
+ * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}:
+ * The device supports secure removal of users. When a user is deleted the data associated
+ * with that user is securely deleted and no longer available.
+ */
+ @SdkConstant(SdkConstantType.FEATURE)
+ public static final String FEATURE_SECURELY_REMOVES_USERS
+ = "android.software.securely_removes_users";
+
+ /**
+ * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}:
* The device has a full implementation of the android.webkit.* APIs. Devices
* lacking this feature will not have a functioning WebView implementation.
*/
@@ -1554,6 +1564,15 @@ public abstract class PackageManager {
public static final String FEATURE_HDMI_CEC = "android.hardware.hdmi.cec";
/**
+ * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}:
+ * The device has all of the inputs necessary to be considered a compatible game controller, or
+ * includes a compatible game controller in the box.
+ */
+ @SdkConstant(SdkConstantType.FEATURE)
+ public static final String FEATURE_GAMEPAD = "android.hardware.gamepad";
+
+
+ /**
* Action to external storage service to clean out removed apps.
* @hide
*/
@@ -2431,7 +2450,6 @@ public abstract class PackageManager {
* @see #MATCH_DEFAULT_ONLY
* @see #GET_INTENT_FILTERS
* @see #GET_RESOLVED_FILTER
- * @see #NO_CROSS_PROFILE
* @hide
*/
public abstract List<ResolveInfo> queryIntentActivitiesAsUser(Intent intent,
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index e0fd532..ddb0a6d 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -1099,9 +1099,12 @@ public class PackageParser {
}
}
}
- } catch (GeneralSecurityException | IOException | RuntimeException e) {
+ } catch (GeneralSecurityException e) {
throw new PackageParserException(INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING,
"Failed to collect certificates from " + apkPath, e);
+ } catch (IOException | RuntimeException e) {
+ throw new PackageParserException(INSTALL_PARSE_FAILED_NO_CERTIFICATES,
+ "Failed to collect certificates from " + apkPath, e);
} finally {
closeQuietly(jarFile);
}
diff --git a/core/java/android/content/pm/UserInfo.java b/core/java/android/content/pm/UserInfo.java
index c0383a3..c03be32 100644
--- a/core/java/android/content/pm/UserInfo.java
+++ b/core/java/android/content/pm/UserInfo.java
@@ -89,6 +89,7 @@ public class UserInfo implements Parcelable {
/** User is only partially created. */
public boolean partial;
+ public boolean guestToRemove;
public UserInfo(int id, String name, int flags) {
this(id, name, null, flags);
@@ -147,6 +148,7 @@ public class UserInfo implements Parcelable {
lastLoggedInTime = orig.lastLoggedInTime;
partial = orig.partial;
profileGroupId = orig.profileGroupId;
+ guestToRemove = orig.guestToRemove;
}
public UserHandle getUserHandle() {
@@ -172,6 +174,7 @@ public class UserInfo implements Parcelable {
dest.writeLong(lastLoggedInTime);
dest.writeInt(partial ? 1 : 0);
dest.writeInt(profileGroupId);
+ dest.writeInt(guestToRemove ? 1 : 0);
}
public static final Parcelable.Creator<UserInfo> CREATOR
@@ -194,5 +197,6 @@ public class UserInfo implements Parcelable {
lastLoggedInTime = source.readLong();
partial = source.readInt() != 0;
profileGroupId = source.readInt();
+ guestToRemove = source.readInt() != 0;
}
}
diff --git a/core/java/android/hardware/camera2/CameraCaptureSession.java b/core/java/android/hardware/camera2/CameraCaptureSession.java
index 29e42ea..ce83028 100644
--- a/core/java/android/hardware/camera2/CameraCaptureSession.java
+++ b/core/java/android/hardware/camera2/CameraCaptureSession.java
@@ -483,7 +483,9 @@ public abstract class CameraCaptureSession implements AutoCloseable {
* 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
- * {@link android.graphics.SurfaceTexture#getTimestamp()}.</p>
+ * {@link android.graphics.SurfaceTexture#getTimestamp()}.
+ * The frame number included is equal to the frame number that will be included in
+ * {@link CaptureResult#getFrameNumber}.</p>
*
* <p>For the simplest way to play a shutter sound camera shutter or a
* video recording start/stop sound, see the
@@ -494,10 +496,21 @@ 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 frameNumber the frame number for this capture
*
* @see android.media.MediaActionSound
*/
public void onCaptureStarted(CameraCaptureSession session,
+ CaptureRequest request, long timestamp, long frameNumber) {
+ // Temporary trampoline for API change transition
+ onCaptureStarted(session, request, timestamp);
+ }
+
+ /**
+ * Temporary for API change transition
+ * @hide
+ */
+ public void onCaptureStarted(CameraCaptureSession session,
CaptureRequest request, long timestamp) {
// default empty implementation
}
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index 6d0d505..93eb3de 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -731,6 +731,8 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>>
/**
* <p>List of areas to use for
* metering.</p>
+ * <p>Optional. Not available if {@link CameraCharacteristics#CONTROL_MAX_REGIONS_AE android.control.maxRegionsAe} is 0.
+ * Otherwise will always be present.</p>
* <p>The coordinate system is based on the active pixel array,
* with (0,0) being the top-left pixel in the active pixel array, and
* ({@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.width - 1,
@@ -746,7 +748,9 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>>
* outside the used {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion} returned in capture result metadata,
* the camera device will ignore the sections outside the region and output the
* used sections in the result metadata.</p>
+ * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
*
+ * @see CameraCharacteristics#CONTROL_MAX_REGIONS_AE
* @see CaptureRequest#SCALER_CROP_REGION
* @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
*/
@@ -820,6 +824,8 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>>
/**
* <p>List of areas to use for focus
* estimation.</p>
+ * <p>Optional. Not available if {@link CameraCharacteristics#CONTROL_MAX_REGIONS_AF android.control.maxRegionsAf} is 0.
+ * Otherwise will always be present.</p>
* <p>The coordinate system is based on the active pixel array,
* with (0,0) being the top-left pixel in the active pixel array, and
* ({@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.width - 1,
@@ -835,7 +841,9 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>>
* outside the used {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion} returned in capture result metadata,
* the camera device will ignore the sections outside the region and output the
* used sections in the result metadata.</p>
+ * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
*
+ * @see CameraCharacteristics#CONTROL_MAX_REGIONS_AF
* @see CaptureRequest#SCALER_CROP_REGION
* @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
*/
@@ -921,6 +929,8 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>>
/**
* <p>List of areas to use for illuminant
* estimation.</p>
+ * <p>Optional. Not available if {@link CameraCharacteristics#CONTROL_MAX_REGIONS_AWB android.control.maxRegionsAwb} is 0.
+ * Otherwise will always be present.</p>
* <p>The coordinate system is based on the active pixel array,
* with (0,0) being the top-left pixel in the active pixel array, and
* ({@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.width - 1,
@@ -936,7 +946,9 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>>
* outside the used {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion} returned in capture result metadata,
* the camera device will ignore the sections outside the region and output the
* used sections in the result metadata.</p>
+ * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
*
+ * @see CameraCharacteristics#CONTROL_MAX_REGIONS_AWB
* @see CaptureRequest#SCALER_CROP_REGION
* @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
*/
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index 754d83e..01276a2 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -582,6 +582,8 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> {
/**
* <p>List of areas to use for
* metering.</p>
+ * <p>Optional. Not available if {@link CameraCharacteristics#CONTROL_MAX_REGIONS_AE android.control.maxRegionsAe} is 0.
+ * Otherwise will always be present.</p>
* <p>The coordinate system is based on the active pixel array,
* with (0,0) being the top-left pixel in the active pixel array, and
* ({@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.width - 1,
@@ -597,7 +599,9 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> {
* outside the used {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion} returned in capture result metadata,
* the camera device will ignore the sections outside the region and output the
* used sections in the result metadata.</p>
+ * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
*
+ * @see CameraCharacteristics#CONTROL_MAX_REGIONS_AE
* @see CaptureRequest#SCALER_CROP_REGION
* @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
*/
@@ -870,6 +874,8 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> {
/**
* <p>List of areas to use for focus
* estimation.</p>
+ * <p>Optional. Not available if {@link CameraCharacteristics#CONTROL_MAX_REGIONS_AF android.control.maxRegionsAf} is 0.
+ * Otherwise will always be present.</p>
* <p>The coordinate system is based on the active pixel array,
* with (0,0) being the top-left pixel in the active pixel array, and
* ({@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.width - 1,
@@ -885,7 +891,9 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> {
* outside the used {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion} returned in capture result metadata,
* the camera device will ignore the sections outside the region and output the
* used sections in the result metadata.</p>
+ * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
*
+ * @see CameraCharacteristics#CONTROL_MAX_REGIONS_AF
* @see CaptureRequest#SCALER_CROP_REGION
* @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
*/
@@ -1369,6 +1377,8 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> {
/**
* <p>List of areas to use for illuminant
* estimation.</p>
+ * <p>Optional. Not available if {@link CameraCharacteristics#CONTROL_MAX_REGIONS_AWB android.control.maxRegionsAwb} is 0.
+ * Otherwise will always be present.</p>
* <p>The coordinate system is based on the active pixel array,
* with (0,0) being the top-left pixel in the active pixel array, and
* ({@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.width - 1,
@@ -1384,7 +1394,9 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> {
* outside the used {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion} returned in capture result metadata,
* the camera device will ignore the sections outside the region and output the
* used sections in the result metadata.</p>
+ * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
*
+ * @see CameraCharacteristics#CONTROL_MAX_REGIONS_AWB
* @see CaptureRequest#SCALER_CROP_REGION
* @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
*/
diff --git a/core/java/android/hardware/camera2/dispatch/MethodNameInvoker.java b/core/java/android/hardware/camera2/dispatch/MethodNameInvoker.java
index 02c3d87..c66a3a4 100644
--- a/core/java/android/hardware/camera2/dispatch/MethodNameInvoker.java
+++ b/core/java/android/hardware/camera2/dispatch/MethodNameInvoker.java
@@ -48,7 +48,8 @@ public class MethodNameInvoker<T> {
/**
* Invoke a method by its name.
*
- * <p>If more than one method exists in {@code targetClass}, the first method will be used.</p>
+ * <p>If more than one method exists in {@code targetClass}, the first method with the right
+ * number of arguments will be used, and later calls will all use that method.</p>
*
* @param methodName
* The name of the method, which will be matched 1:1 to the destination method
@@ -68,8 +69,9 @@ public class MethodNameInvoker<T> {
Method targetMethod = mMethods.get(methodName);
if (targetMethod == null) {
for (Method method : mTargetClass.getMethods()) {
- // TODO future: match by # of params and types of params if possible
- if (method.getName().equals(methodName)) {
+ // TODO future: match types of params if possible
+ if (method.getName().equals(methodName) &&
+ (params.length == method.getParameterTypes().length) ) {
targetMethod = method;
mMethods.put(methodName, targetMethod);
break;
diff --git a/core/java/android/hardware/camera2/impl/CallbackProxies.java b/core/java/android/hardware/camera2/impl/CallbackProxies.java
index e5ddb7a..f0217ac 100644
--- a/core/java/android/hardware/camera2/impl/CallbackProxies.java
+++ b/core/java/android/hardware/camera2/impl/CallbackProxies.java
@@ -98,8 +98,8 @@ public class CallbackProxies {
@Override
public void onCaptureStarted(CameraDevice camera,
- CaptureRequest request, long timestamp) {
- mProxy.invoke("onCaptureStarted", camera, request, timestamp);
+ CaptureRequest request, long timestamp, long frameNumber) {
+ mProxy.invoke("onCaptureStarted", camera, request, timestamp, frameNumber);
}
@Override
diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
index d454092..f011d60 100644
--- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
@@ -803,7 +803,7 @@ public class CameraDeviceImpl extends CameraDevice {
* @see android.media.MediaActionSound
*/
public void onCaptureStarted(CameraDevice camera,
- CaptureRequest request, long timestamp) {
+ CaptureRequest request, long timestamp, long frameNumber) {
// default empty implementation
}
@@ -1237,8 +1237,10 @@ public class CameraDeviceImpl extends CameraDevice {
@Override
public void onCaptureStarted(final CaptureResultExtras resultExtras, final long timestamp) {
int requestId = resultExtras.getRequestId();
+ final long frameNumber = resultExtras.getFrameNumber();
+
if (DEBUG) {
- Log.d(TAG, "Capture started for id " + requestId);
+ Log.d(TAG, "Capture started for id " + requestId + " frame number " + frameNumber);
}
final CaptureCallbackHolder holder;
@@ -1263,7 +1265,7 @@ public class CameraDeviceImpl extends CameraDevice {
holder.getCallback().onCaptureStarted(
CameraDeviceImpl.this,
holder.getRequest(resultExtras.getSubsequenceId()),
- timestamp);
+ timestamp, frameNumber);
}
}
});
diff --git a/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java b/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java
index a8d1018..3c0e0e4 100644
--- a/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java
+++ b/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java
@@ -675,15 +675,13 @@ public class LegacyMetadataMapper {
* request.availableRequestKeys
*/
{
- CaptureRequest.Key<?> availableKeys[] = new CaptureRequest.Key<?>[] {
+ CaptureRequest.Key<?> defaultAvailableKeys[] = new CaptureRequest.Key<?>[] {
CaptureRequest.CONTROL_AE_ANTIBANDING_MODE,
CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION,
CaptureRequest.CONTROL_AE_LOCK,
CaptureRequest.CONTROL_AE_MODE,
- CaptureRequest.CONTROL_AE_REGIONS,
CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE,
CaptureRequest.CONTROL_AF_MODE,
- CaptureRequest.CONTROL_AF_REGIONS,
CaptureRequest.CONTROL_AF_TRIGGER,
CaptureRequest.CONTROL_AWB_LOCK,
CaptureRequest.CONTROL_AWB_MODE,
@@ -704,21 +702,32 @@ public class LegacyMetadataMapper {
CaptureRequest.SCALER_CROP_REGION,
CaptureRequest.STATISTICS_FACE_DETECT_MODE,
};
- m.set(REQUEST_AVAILABLE_REQUEST_KEYS, getTagsForKeys(availableKeys));
+ ArrayList<CaptureRequest.Key<?>> availableKeys =
+ new ArrayList<CaptureRequest.Key<?>>(Arrays.asList(defaultAvailableKeys));
+
+ if (p.getMaxNumMeteringAreas() > 0) {
+ availableKeys.add(CaptureRequest.CONTROL_AE_REGIONS);
+ }
+ if (p.getMaxNumFocusAreas() > 0) {
+ availableKeys.add(CaptureRequest.CONTROL_AF_REGIONS);
+ }
+
+ CaptureRequest.Key<?> availableRequestKeys[] =
+ new CaptureRequest.Key<?>[availableKeys.size()];
+ availableKeys.toArray(availableRequestKeys);
+ m.set(REQUEST_AVAILABLE_REQUEST_KEYS, getTagsForKeys(availableRequestKeys));
}
/*
* request.availableResultKeys
*/
{
- CaptureResult.Key<?> availableKeys[] = new CaptureResult.Key<?>[] {
+ CaptureResult.Key<?> defaultAvailableKeys[] = new CaptureResult.Key<?>[] {
CaptureResult.CONTROL_AE_ANTIBANDING_MODE ,
CaptureResult.CONTROL_AE_EXPOSURE_COMPENSATION ,
CaptureResult.CONTROL_AE_LOCK ,
CaptureResult.CONTROL_AE_MODE ,
- CaptureResult.CONTROL_AE_REGIONS ,
CaptureResult.CONTROL_AF_MODE ,
- CaptureResult.CONTROL_AF_REGIONS ,
CaptureResult.CONTROL_AF_STATE ,
CaptureResult.CONTROL_AWB_MODE ,
CaptureResult.CONTROL_AWB_LOCK ,
@@ -737,7 +746,20 @@ public class LegacyMetadataMapper {
CaptureResult.STATISTICS_FACE_DETECT_MODE ,
// CaptureResult.STATISTICS_FACES ,
};
- m.set(REQUEST_AVAILABLE_RESULT_KEYS, getTagsForKeys(availableKeys));
+ List<CaptureResult.Key<?>> availableKeys =
+ new ArrayList<CaptureResult.Key<?>>(Arrays.asList(defaultAvailableKeys));
+
+ if (p.getMaxNumMeteringAreas() > 0) {
+ availableKeys.add(CaptureResult.CONTROL_AE_REGIONS);
+ }
+ if (p.getMaxNumFocusAreas() > 0) {
+ availableKeys.add(CaptureResult.CONTROL_AF_REGIONS);
+ }
+
+ CaptureResult.Key<?> availableResultKeys[] =
+ new CaptureResult.Key<?>[availableKeys.size()];
+ availableKeys.toArray(availableResultKeys);
+ m.set(REQUEST_AVAILABLE_RESULT_KEYS, getTagsForKeys(availableResultKeys));
}
/*
diff --git a/core/java/android/hardware/camera2/legacy/LegacyResultMapper.java b/core/java/android/hardware/camera2/legacy/LegacyResultMapper.java
index 090a822..ddaa6ee 100644
--- a/core/java/android/hardware/camera2/legacy/LegacyResultMapper.java
+++ b/core/java/android/hardware/camera2/legacy/LegacyResultMapper.java
@@ -322,7 +322,7 @@ public class LegacyResultMapper {
}
// control.aeRegions
- {
+ if (p.getMaxNumMeteringAreas() > 0) {
if (VERBOSE) {
String meteringAreas = p.get("metering-areas");
Log.v(TAG, "mapAe - parameter dump; metering-areas: " + meteringAreas);
@@ -342,7 +342,7 @@ public class LegacyResultMapper {
m.set(CaptureResult.CONTROL_AF_MODE, convertLegacyAfMode(p.getFocusMode()));
// control.afRegions
- {
+ if (p.getMaxNumFocusAreas() > 0) {
if (VERBOSE) {
String focusAreas = p.get("focus-areas");
Log.v(TAG, "mapAe - parameter dump; focus-areas: " + focusAreas);
diff --git a/core/java/android/os/FileBridge.java b/core/java/android/os/FileBridge.java
index 022a106..0acf24b 100644
--- a/core/java/android/os/FileBridge.java
+++ b/core/java/android/os/FileBridge.java
@@ -75,6 +75,13 @@ public class FileBridge extends Thread {
return mClosed;
}
+ public void forceClose() {
+ IoUtils.closeQuietly(mTarget);
+ IoUtils.closeQuietly(mServer);
+ IoUtils.closeQuietly(mClient);
+ mClosed = true;
+ }
+
public void setTargetFile(FileDescriptor target) {
mTarget = target;
}
@@ -89,7 +96,6 @@ public class FileBridge extends Thread {
try {
while (IoBridge.read(mServer, temp, 0, MSG_LENGTH) == MSG_LENGTH) {
final int cmd = Memory.peekInt(temp, 0, ByteOrder.BIG_ENDIAN);
-
if (cmd == CMD_WRITE) {
// Shuttle data into local file
int len = Memory.peekInt(temp, 4, ByteOrder.BIG_ENDIAN);
@@ -118,15 +124,10 @@ public class FileBridge extends Thread {
}
}
- } catch (ErrnoException e) {
- Log.wtf(TAG, "Failed during bridge", e);
- } catch (IOException e) {
+ } catch (ErrnoException | IOException e) {
Log.wtf(TAG, "Failed during bridge", e);
} finally {
- IoUtils.closeQuietly(mTarget);
- IoUtils.closeQuietly(mServer);
- IoUtils.closeQuietly(mClient);
- mClosed = true;
+ forceClose();
}
}
@@ -151,6 +152,7 @@ public class FileBridge extends Thread {
writeCommandAndBlock(CMD_CLOSE, "close()");
} finally {
IoBridge.closeAndSignalBlockedThreads(mClient);
+ IoUtils.closeQuietly(mClientPfd);
}
}
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index c3ac012..b2ebc31 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -468,6 +468,7 @@ public class Process {
* @param targetSdkVersion The target SDK version for the app.
* @param seInfo null-ok SELinux information for the new process.
* @param abi non-null the ABI this app should be started with.
+ * @param instructionSet null-ok the instruction set to use.
* @param zygoteArgs Additional arguments to supply to the zygote process.
*
* @return An object that describes the result of the attempt to start the process.
@@ -482,11 +483,12 @@ public class Process {
int targetSdkVersion,
String seInfo,
String abi,
+ String instructionSet,
String[] zygoteArgs) {
try {
return startViaZygote(processClass, niceName, uid, gid, gids,
debugFlags, mountExternal, targetSdkVersion, seInfo,
- abi, zygoteArgs);
+ abi, instructionSet, zygoteArgs);
} catch (ZygoteStartFailedEx ex) {
Log.e(LOG_TAG,
"Starting VM process through Zygote failed");
@@ -589,6 +591,7 @@ public class Process {
* @param targetSdkVersion The target SDK version for the app.
* @param seInfo null-ok SELinux information for the new process.
* @param abi the ABI the process should use.
+ * @param instructionSet null-ok the instruction set to use.
* @param extraArgs Additional arguments to supply to the zygote process.
* @return An object that describes the result of the attempt to start the process.
* @throws ZygoteStartFailedEx if process start failed for any reason
@@ -601,6 +604,7 @@ public class Process {
int targetSdkVersion,
String seInfo,
String abi,
+ String instructionSet,
String[] extraArgs)
throws ZygoteStartFailedEx {
synchronized(Process.class) {
@@ -660,6 +664,10 @@ public class Process {
argsForZygote.add("--seinfo=" + seInfo);
}
+ if (instructionSet != null) {
+ argsForZygote.add("--instruction-set=" + instructionSet);
+ }
+
argsForZygote.add(processClass);
if (extraArgs != null) {
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index ec77a5e..33fda4a 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -43,190 +43,208 @@ public class UserManager {
private final Context mContext;
/**
- * Key for user restrictions. Specifies if a user is disallowed from adding and removing
- * accounts.
+ * Specifies if a user is disallowed from adding and removing accounts.
* The default value is <code>false</code>.
- * <p/>
- * Type: Boolean
+ *
+ * <p/>Key for user restrictions.
+ * <p/>Type: Boolean
* @see #setUserRestrictions(Bundle)
* @see #getUserRestrictions()
*/
public static final String DISALLOW_MODIFY_ACCOUNTS = "no_modify_accounts";
/**
- * Key for user restrictions. Specifies if a user is disallowed from changing Wi-Fi
+ * Specifies if a user is disallowed from changing Wi-Fi
* access points. The default value is <code>false</code>.
- * <p/>
- * Type: Boolean
+ *
+ * <p/>Key for user restrictions.
+ * <p/>Type: Boolean
* @see #setUserRestrictions(Bundle)
* @see #getUserRestrictions()
*/
public static final String DISALLOW_CONFIG_WIFI = "no_config_wifi";
/**
- * Key for user restrictions. Specifies if a user is disallowed from installing applications.
+ * Specifies if a user is disallowed from installing applications.
* The default value is <code>false</code>.
- * <p/>
- * Type: Boolean
+ *
+ * <p/>Key for user restrictions.
+ * <p/>Type: Boolean
* @see #setUserRestrictions(Bundle)
* @see #getUserRestrictions()
*/
public static final String DISALLOW_INSTALL_APPS = "no_install_apps";
/**
- * Key for user restrictions. Specifies if a user is disallowed from uninstalling applications.
+ * Specifies if a user is disallowed from uninstalling applications.
* The default value is <code>false</code>.
- * <p/>
- * Type: Boolean
+ *
+ * <p/>Key for user restrictions.
+ * <p/>Type: Boolean
* @see #setUserRestrictions(Bundle)
* @see #getUserRestrictions()
*/
public static final String DISALLOW_UNINSTALL_APPS = "no_uninstall_apps";
/**
- * Key for user restrictions. Specifies if a user is disallowed from toggling location sharing.
+ * Specifies if a user is disallowed from toggling location sharing.
* The default value is <code>false</code>.
- * <p/>
- * Type: Boolean
+ *
+ * <p/>Key for user restrictions.
+ * <p/>Type: Boolean
* @see #setUserRestrictions(Bundle)
* @see #getUserRestrictions()
*/
public static final String DISALLOW_SHARE_LOCATION = "no_share_location";
/**
- * Key for user restrictions. Specifies if a user is disallowed from enabling the
+ * Specifies if a user is disallowed from enabling the
* "Unknown Sources" setting, that allows installation of apps from unknown sources.
* The default value is <code>false</code>.
- * <p/>
- * Type: Boolean
+ *
+ * <p/>Key for user restrictions.
+ * <p/>Type: Boolean
* @see #setUserRestrictions(Bundle)
* @see #getUserRestrictions()
*/
public static final String DISALLOW_INSTALL_UNKNOWN_SOURCES = "no_install_unknown_sources";
/**
- * Key for user restrictions. Specifies if a user is disallowed from configuring bluetooth.
+ * Specifies if a user is disallowed from configuring bluetooth.
* The default value is <code>false</code>.
- * <p/>
- * Type: Boolean
+ *
+ * <p/>Key for user restrictions.
+ * <p/>Type: Boolean
* @see #setUserRestrictions(Bundle)
* @see #getUserRestrictions()
*/
public static final String DISALLOW_CONFIG_BLUETOOTH = "no_config_bluetooth";
/**
- * Key for user restrictions. Specifies if a user is disallowed from transferring files over
+ * Specifies if a user is disallowed from transferring files over
* USB. This can only be set by device owners. The default value is <code>false</code>.
- * <p/>
- * Type: Boolean
+ *
+ * <p/>Key for user restrictions.
+ * <p/>Type: Boolean
* @see #setUserRestrictions(Bundle)
* @see #getUserRestrictions()
*/
public static final String DISALLOW_USB_FILE_TRANSFER = "no_usb_file_transfer";
/**
- * Key for user restrictions. Specifies if a user is disallowed from configuring user
+ * Specifies if a user is disallowed from configuring user
* credentials. The default value is <code>false</code>.
- * <p/>
- * Type: Boolean
+ *
+ * <p/>Key for user restrictions.
+ * <p/>Type: Boolean
* @see #setUserRestrictions(Bundle)
* @see #getUserRestrictions()
*/
public static final String DISALLOW_CONFIG_CREDENTIALS = "no_config_credentials";
/**
- * Key for user restrictions. Specifies if a user is disallowed from removing itself and other
+ * Specifies if a user is disallowed from removing itself and other
* users. The default value is <code>false</code>.
- * <p/>
- * Type: Boolean
+ *
+ * <p/>Key for user restrictions.
+ * <p/>Type: Boolean
* @see #setUserRestrictions(Bundle)
* @see #getUserRestrictions()
*/
public static final String DISALLOW_REMOVE_USER = "no_remove_user";
/**
- * Key for user restrictions. Specifies if a user is disallowed from enabling or
+ * Specifies if a user is disallowed from enabling or
* accessing debugging features. The default value is <code>false</code>.
- * <p/>
- * Type: Boolean
+ *
+ * <p/>Key for user restrictions.
+ * <p/>Type: Boolean
* @see #setUserRestrictions(Bundle)
* @see #getUserRestrictions()
*/
public static final String DISALLOW_DEBUGGING_FEATURES = "no_debugging_features";
/**
- * Key for user restrictions. Specifies if a user is disallowed from configuring VPN.
+ * Specifies if a user is disallowed from configuring VPN.
* The default value is <code>false</code>.
- * <p/>
- * Type: Boolean
+ *
+ * <p/>Key for user restrictions.
+ * <p/>Type: Boolean
* @see #setUserRestrictions(Bundle)
* @see #getUserRestrictions()
*/
public static final String DISALLOW_CONFIG_VPN = "no_config_vpn";
/**
- * Key for user restrictions. Specifies if a user is disallowed from configuring Tethering
+ * Specifies if a user is disallowed from configuring Tethering
* & portable hotspots. This can only be set by device owners. The default value is
* <code>false</code>.
- * <p/>
- * Type: Boolean
+ *
+ * <p/>Key for user restrictions.
+ * <p/>Type: Boolean
* @see #setUserRestrictions(Bundle)
* @see #getUserRestrictions()
*/
public static final String DISALLOW_CONFIG_TETHERING = "no_config_tethering";
/**
- * Key for user restrictions. Specifies if a user is disallowed from factory resetting
+ * Specifies if a user is disallowed from factory resetting
* from Settings. This can only be set by device owners. The default value is
* <code>false</code>.
- * <p>
+ *
+ * <p/>Key for user restrictions.
+ * <p/>Type: Boolean
* @see #setUserRestrictions(Bundle)
* @see #getUserRestrictions()
*/
public static final String DISALLOW_FACTORY_RESET = "no_factory_reset";
/**
- * Key for user restrictions. Specifies if a user is disallowed from adding new users and
+ * Specifies if a user is disallowed from adding new users and
* profiles. This can only be set by device owners. The default value is <code>false</code>.
- * <p>
- * Type: Boolean
+ *
+ * <p/>Key for user restrictions.
+ * <p/>Type: Boolean
* @see #setUserRestrictions(Bundle)
* @see #getUserRestrictions()
*/
public static final String DISALLOW_ADD_USER = "no_add_user";
/**
- * Key for user restrictions. Specifies if a user is disallowed from disabling application
+ * Specifies if a user is disallowed from disabling application
* verification. The default value is <code>false</code>.
- * <p>
- * Type: Boolean
+ *
+ * <p/>Key for user restrictions.
+ * <p/>Type: Boolean
* @see #setUserRestrictions(Bundle)
* @see #getUserRestrictions()
*/
public static final String ENSURE_VERIFY_APPS = "ensure_verify_apps";
/**
- * Key for user restrictions. Specifies if a user is disallowed from configuring cell
+ * Specifies if a user is disallowed from configuring cell
* broadcasts. This can only be set by device owners. The default value is <code>false</code>.
- * <p>
- * Type: Boolean
+ *
+ * <p/>Key for user restrictions.
+ * <p/>Type: Boolean
* @see #setUserRestrictions(Bundle)
* @see #getUserRestrictions()
*/
public static final String DISALLOW_CONFIG_CELL_BROADCASTS = "no_config_cell_broadcasts";
/**
- * Key for user restrictions. Specifies if a user is disallowed from configuring mobile
+ * Specifies if a user is disallowed from configuring mobile
* networks. This can only be set by device owners. The default value is <code>false</code>.
- * <p>
- * Type: Boolean
+ *
+ * <p/>Key for user restrictions.
+ * <p/>Type: Boolean
* @see #setUserRestrictions(Bundle)
* @see #getUserRestrictions()
*/
public static final String DISALLOW_CONFIG_MOBILE_NETWORKS = "no_config_mobile_networks";
/**
- * Key for user restrictions. Specifies if a user is disallowed from modifying
+ * Specifies if a user is disallowed from modifying
* applications in Settings or launchers. The following actions will not be allowed when this
* restriction is enabled:
* <li>uninstalling apps</li>
@@ -237,69 +255,75 @@ public class UserManager {
* <li>clearing app defaults</li>
* <p>
* The default value is <code>false</code>.
- * <p>
- * Type: Boolean
+ *
+ * <p/>Key for user restrictions.
+ * <p/>Type: Boolean
* @see #setUserRestrictions(Bundle)
* @see #getUserRestrictions()
*/
public static final String DISALLOW_APPS_CONTROL = "no_control_apps";
/**
- * Key for user restrictions. Specifies if a user is disallowed from mounting
+ * Specifies if a user is disallowed from mounting
* physical external media. This can only be set by device owners. The default value is
* <code>false</code>.
- * <p/>
- * Type: Boolean
+ *
+ * <p/>Key for user restrictions.
+ * <p/>Type: Boolean
* @see #setUserRestrictions(Bundle)
* @see #getUserRestrictions()
*/
public static final String DISALLOW_MOUNT_PHYSICAL_MEDIA = "no_physical_media";
/**
- * Key for user restrictions. Specifies if a user is disallowed from adjusting microphone
+ * Specifies if a user is disallowed from adjusting microphone
* volume. If set, the microphone will be muted. This can only be set by device owners.
* The default value is <code>false</code>.
- * <p/>
- * Type: Boolean
+ *
+ * <p/>Key for user restrictions.
+ * <p/>Type: Boolean
* @see #setUserRestrictions(Bundle)
* @see #getUserRestrictions()
*/
public static final String DISALLOW_UNMUTE_MICROPHONE = "no_unmute_microphone";
/**
- * Key for user restrictions. Specifies if a user is disallowed from adjusting the master
+ * Specifies if a user is disallowed from adjusting the master
* volume. If set, the master volume will be muted. This can only be set by device owners.
* The default value is <code>false</code>.
- * <p/>
- * Type: Boolean
+ *
+ * <p/>Key for user restrictions.
+ * <p/>Type: Boolean
* @see #setUserRestrictions(Bundle)
* @see #getUserRestrictions()
*/
public static final String DISALLOW_ADJUST_VOLUME = "no_adjust_volume";
/**
- * Key for user restrictions. Specifies that the user is not allowed to make outgoing
+ * Specifies that the user is not allowed to make outgoing
* phone calls. Emergency calls are still permitted.
* The default value is <code>false</code>.
- * <p/>
- * Type: Boolean
+ *
+ * <p/>Key for user restrictions.
+ * <p/>Type: Boolean
* @see #setUserRestrictions(Bundle)
* @see #getUserRestrictions()
*/
public static final String DISALLOW_OUTGOING_CALLS = "no_outgoing_calls";
/**
- * Key for user restrictions. Specifies that the user is not allowed to send or receive
+ * Specifies that the user is not allowed to send or receive
* SMS messages. This can only be set by device owners. The default value is <code>false</code>.
- * <p/>
- * Type: Boolean
+ *
+ * <p/>Key for user restrictions.
+ * <p/>Type: Boolean
* @see #setUserRestrictions(Bundle)
* @see #getUserRestrictions()
*/
public static final String DISALLOW_SMS = "no_sms";
/**
- * Key for user restrictions. Specifies that windows besides app windows should not be
+ * Specifies that windows besides app windows should not be
* created. This will block the creation of the following types of windows.
* <li>{@link LayoutParams#TYPE_TOAST}</li>
* <li>{@link LayoutParams#TYPE_PHONE}</li>
@@ -309,25 +333,38 @@ public class UserManager {
* <li>{@link LayoutParams#TYPE_SYSTEM_OVERLAY}</li>
*
* <p>This can only be set by device owners. The default value is <code>false</code>.
- * <p/>
- * Type: Boolean
+ *
+ * <p/>Key for user restrictions.
+ * <p/>Type: Boolean
* @see #setUserRestrictions(Bundle)
* @see #getUserRestrictions()
*/
public static final String DISALLOW_CREATE_WINDOWS = "no_create_windows";
/**
- * Key for user restrictions. Specifies if what is copied in the clipboard of this profile can
+ * Specifies if what is copied in the clipboard of this profile can
* be pasted in related profiles. Does not restrict if the clipboard of related profiles can be
* pasted in this profile.
* The default value is <code>false</code>.
- * <p/>
- * Type: Boolean
+ *
+ * <p/>Key for user restrictions.
+ * <p/>Type: Boolean
* @see #setUserRestrictions(Bundle)
* @see #getUserRestrictions()
*/
public static final String DISALLOW_CROSS_PROFILE_COPY_PASTE = "no_cross_profile_copy_paste";
+ /**
+ * Specifies if the user is not allowed to use NFC to beam out data from apps.
+ * The default value is <code>false</code>.
+ *
+ * <p/>Key for user restrictions.
+ * <p/>Type: Boolean
+ * @see #setUserRestrictions(Bundle)
+ * @see #getUserRestrictions()
+ */
+ public static final String DISALLOW_OUTGOING_BEAM = "no_outgoing_beam";
+
/** @hide */
public static final int PIN_VERIFICATION_FAILED_INCORRECT = -3;
/** @hide */
diff --git a/core/java/android/provider/CallLog.java b/core/java/android/provider/CallLog.java
index 5fa1cc9..a5e86d8 100644
--- a/core/java/android/provider/CallLog.java
+++ b/core/java/android/provider/CallLog.java
@@ -167,8 +167,6 @@ public class CallLog {
*/
public static final String FEATURES = "features";
- /** Call had no associated features (e.g. voice-only). */
- public static final int FEATURES_NONE = 0x0;
/** Call had video. */
public static final int FEATURES_VIDEO = 0x1;
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index f4c2dc8..01fda47 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3739,6 +3739,13 @@ public final class Settings {
"show_note_about_notification_hiding";
/**
+ * Set to 1 by the system after trust agents have been initialized.
+ * @hide
+ */
+ public static final String TRUST_AGENTS_INITIALIZED =
+ "trust_agents_initialized";
+
+ /**
* The Logging ID (a unique 64-bit value) as a hex string.
* Used as a pseudonymous identifier for logging.
* @deprecated This identifier is poorly initialized and has
diff --git a/core/java/android/service/notification/Condition.java b/core/java/android/service/notification/Condition.java
index aa724f0..3a91d1a 100644
--- a/core/java/android/service/notification/Condition.java
+++ b/core/java/android/service/notification/Condition.java
@@ -16,6 +16,7 @@
package android.service.notification;
+import android.annotation.SystemApi;
import android.content.Context;
import android.net.Uri;
import android.os.Parcel;
@@ -28,6 +29,7 @@ import java.util.Objects;
*
* @hide
*/
+@SystemApi
public class Condition implements Parcelable {
public static final String SCHEME = "condition";
diff --git a/core/java/android/service/notification/ConditionProviderService.java b/core/java/android/service/notification/ConditionProviderService.java
index 326412f..03ee726 100644
--- a/core/java/android/service/notification/ConditionProviderService.java
+++ b/core/java/android/service/notification/ConditionProviderService.java
@@ -17,6 +17,7 @@
package android.service.notification;
import android.annotation.SdkConstant;
+import android.annotation.SystemApi;
import android.app.INotificationManager;
import android.app.Service;
import android.content.Context;
@@ -44,6 +45,7 @@ import android.util.Log;
*
* @hide
*/
+@SystemApi
public abstract class ConditionProviderService extends Service {
private final String TAG = ConditionProviderService.class.getSimpleName()
+ "[" + getClass().getSimpleName() + "]";
diff --git a/core/java/android/service/notification/IStatusBarNotificationHolder.aidl b/core/java/android/service/notification/IStatusBarNotificationHolder.aidl
index fd6b59e..c25cdb2 100644
--- a/core/java/android/service/notification/IStatusBarNotificationHolder.aidl
+++ b/core/java/android/service/notification/IStatusBarNotificationHolder.aidl
@@ -20,5 +20,6 @@ import android.service.notification.StatusBarNotification;
/** @hide */
interface IStatusBarNotificationHolder {
+ /** Fetch the held StatusBarNotification. This method should only be called once per Holder */
StatusBarNotification get();
}
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index d744070..b22fd9c 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -756,15 +756,6 @@ public abstract class NotificationListenerService extends Service {
return mVisibilityOverride;
}
- /**
- * Returns whether the notification meets the user's interruption
- * filter.
- *
- * @removed
- */
- public boolean meetsInterruptionFilter() {
- return mMatchesInterruptionFilter;
- }
/**
* Returns whether the notification matches the user's interruption
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java
index 872f911..9cbedab 100644
--- a/core/java/android/service/notification/ZenModeConfig.java
+++ b/core/java/android/service/notification/ZenModeConfig.java
@@ -17,6 +17,7 @@
package android.service.notification;
import android.content.ComponentName;
+import android.content.res.Resources;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
@@ -55,6 +56,11 @@ public class ZenModeConfig implements Parcelable {
public static final int[] WEEKNIGHT_DAYS = { Calendar.SUNDAY, Calendar.MONDAY, Calendar.TUESDAY,
Calendar.WEDNESDAY, Calendar.THURSDAY };
+ public static final int[] MINUTE_BUCKETS = new int[] { 15, 30, 45, 60, 120, 180, 240, 480 };
+ private static final int SECONDS_MS = 1000;
+ private static final int MINUTES_MS = 60 * SECONDS_MS;
+ private static final int ZERO_VALUE_MS = 20 * SECONDS_MS;
+
private static final int XML_VERSION = 1;
private static final String ZEN_TAG = "zen";
private static final String ZEN_ATT_VERSION = "version";
@@ -445,6 +451,23 @@ public class ZenModeConfig implements Parcelable {
return downtime;
}
+ public static Condition toTimeCondition(int minutesFromNow) {
+ final long now = System.currentTimeMillis();
+ final long millis = minutesFromNow == 0 ? ZERO_VALUE_MS : minutesFromNow * MINUTES_MS;
+ return toTimeCondition(now + millis, minutesFromNow);
+ }
+
+ public static Condition toTimeCondition(long time, int minutes) {
+ final int num = minutes < 60 ? minutes : Math.round(minutes / 60f);
+ final int resId = minutes < 60
+ ? com.android.internal.R.plurals.zen_mode_duration_minutes
+ : com.android.internal.R.plurals.zen_mode_duration_hours;
+ final String caption = Resources.getSystem().getQuantityString(resId, num, num);
+ final Uri id = toCountdownConditionId(time);
+ return new Condition(id, caption, "", "", 0, Condition.STATE_TRUE,
+ Condition.FLAG_RELEVANT_NOW);
+ }
+
// For built-in conditions
private static final String SYSTEM_AUTHORITY = "android";
diff --git a/core/java/android/service/voice/AlwaysOnHotwordDetector.java b/core/java/android/service/voice/AlwaysOnHotwordDetector.java
index 4de5f41..8aa2689 100644
--- a/core/java/android/service/voice/AlwaysOnHotwordDetector.java
+++ b/core/java/android/service/voice/AlwaysOnHotwordDetector.java
@@ -468,19 +468,6 @@ public class AlwaysOnHotwordDetector {
}
/**
- * FIXME: Remove once the prebuilts are updated.
- *
- * @hide
- */
- @Deprecated
- public Intent createIntentToEnroll() {
- if (DBG) Slog.d(TAG, "createIntentToEnroll");
- synchronized (mLock) {
- return getManageIntentLocked(MANAGE_ACTION_ENROLL);
- }
- }
-
- /**
* Creates an intent to start the un-enrollment for the associated keyphrase.
* This intent must be invoked using {@link Activity#startActivityForResult(Intent, int)}.
* Starting re-enrollment is only valid if the keyphrase is already enrolled,
@@ -502,19 +489,6 @@ public class AlwaysOnHotwordDetector {
}
/**
- * FIXME: Remove once the prebuilts are updated.
- *
- * @hide
- */
- @Deprecated
- public Intent createIntentToUnEnroll() {
- if (DBG) Slog.d(TAG, "createIntentToUnEnroll");
- synchronized (mLock) {
- return getManageIntentLocked(MANAGE_ACTION_UN_ENROLL);
- }
- }
-
- /**
* Creates an intent to start the re-enrollment for the associated keyphrase.
* This intent must be invoked using {@link Activity#startActivityForResult(Intent, int)}.
* Starting re-enrollment is only valid if the keyphrase is already enrolled,
@@ -535,19 +509,6 @@ public class AlwaysOnHotwordDetector {
}
}
- /**
- * FIXME: Remove once the prebuilts are updated.
- *
- * @hide
- */
- @Deprecated
- public Intent createIntentToReEnroll() {
- if (DBG) Slog.d(TAG, "createIntentToReEnroll");
- synchronized (mLock) {
- return getManageIntentLocked(MANAGE_ACTION_RE_ENROLL);
- }
- }
-
private Intent getManageIntentLocked(int action) {
if (mAvailability == STATE_INVALID) {
throw new IllegalStateException("getManageIntent called on an invalid detector");
diff --git a/core/java/android/service/wallpaper/IWallpaperEngine.aidl b/core/java/android/service/wallpaper/IWallpaperEngine.aidl
index faccde2..de527e9 100644
--- a/core/java/android/service/wallpaper/IWallpaperEngine.aidl
+++ b/core/java/android/service/wallpaper/IWallpaperEngine.aidl
@@ -16,6 +16,7 @@
package android.service.wallpaper;
+import android.graphics.Rect;
import android.view.MotionEvent;
import android.os.Bundle;
@@ -24,6 +25,7 @@ import android.os.Bundle;
*/
oneway interface IWallpaperEngine {
void setDesiredSize(int width, int height);
+ void setDisplayPadding(in Rect padding);
void setVisibility(boolean visible);
void dispatchPointer(in MotionEvent event);
void dispatchWallpaperCommand(String action, int x, int y,
diff --git a/core/java/android/service/wallpaper/IWallpaperService.aidl b/core/java/android/service/wallpaper/IWallpaperService.aidl
index bc7a1d7..5fd0157 100644
--- a/core/java/android/service/wallpaper/IWallpaperService.aidl
+++ b/core/java/android/service/wallpaper/IWallpaperService.aidl
@@ -16,6 +16,7 @@
package android.service.wallpaper;
+import android.graphics.Rect;
import android.service.wallpaper.IWallpaperConnection;
/**
@@ -24,5 +25,5 @@ import android.service.wallpaper.IWallpaperConnection;
oneway interface IWallpaperService {
void attach(IWallpaperConnection connection,
IBinder windowToken, int windowType, boolean isPreview,
- int reqWidth, int reqHeight);
+ int reqWidth, int reqHeight, in Rect padding);
}
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index f3c26c8..26e9a30 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -16,6 +16,14 @@
package android.service.wallpaper;
+import android.content.res.TypedArray;
+import android.os.Build;
+import android.os.SystemProperties;
+import android.util.DisplayMetrics;
+import android.util.TypedValue;
+import android.view.ViewRootImpl;
+import android.view.WindowInsets;
+import com.android.internal.R;
import com.android.internal.os.HandlerCaller;
import com.android.internal.view.BaseIWindow;
import com.android.internal.view.BaseSurfaceHolder;
@@ -56,6 +64,8 @@ import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
+import static android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN;
+
/**
* A wallpaper service is responsible for showing a live wallpaper behind
* applications that would like to sit on top of it. This service object
@@ -90,7 +100,8 @@ public abstract class WallpaperService extends Service {
private static final int DO_ATTACH = 10;
private static final int DO_DETACH = 20;
private static final int DO_SET_DESIRED_SIZE = 30;
-
+ private static final int DO_SET_DISPLAY_PADDING = 40;
+
private static final int MSG_UPDATE_SURFACE = 10000;
private static final int MSG_VISIBILITY_CHANGED = 10010;
private static final int MSG_WALLPAPER_OFFSETS = 10020;
@@ -150,13 +161,23 @@ public abstract class WallpaperService extends Service {
WindowManager.LayoutParams.PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS;
int mCurWindowFlags = mWindowFlags;
int mCurWindowPrivateFlags = mWindowPrivateFlags;
+ TypedValue mOutsetBottom;
final Rect mVisibleInsets = new Rect();
final Rect mWinFrame = new Rect();
final Rect mOverscanInsets = new Rect();
final Rect mContentInsets = new Rect();
final Rect mStableInsets = new Rect();
+ final Rect mDispatchedOverscanInsets = new Rect();
+ final Rect mDispatchedContentInsets = new Rect();
+ final Rect mDispatchedStableInsets = new Rect();
+ final Rect mFinalSystemInsets = new Rect();
+ final Rect mFinalStableInsets = new Rect();
final Configuration mConfiguration = new Configuration();
-
+
+ private boolean mIsEmulator;
+ private boolean mIsCircularEmulator;
+ private boolean mWindowIsRound;
+
final WindowManager.LayoutParams mLayout
= new WindowManager.LayoutParams();
IWindowSession mSession;
@@ -406,7 +427,7 @@ public abstract class WallpaperService extends Service {
*/
public void onCreate(SurfaceHolder surfaceHolder) {
}
-
+
/**
* Called right before the engine is going away. After this the
* surface will be destroyed and this Engine object is no longer
@@ -414,7 +435,7 @@ public abstract class WallpaperService extends Service {
*/
public void onDestroy() {
}
-
+
/**
* Called to inform you of the wallpaper becoming visible or
* hidden. <em>It is very important that a wallpaper only use
@@ -422,7 +443,17 @@ public abstract class WallpaperService extends Service {
*/
public void onVisibilityChanged(boolean visible) {
}
-
+
+ /**
+ * Called with the current insets that are in effect for the wallpaper.
+ * This gives you the part of the overall wallpaper surface that will
+ * generally be visible to the user (ignoring position offsets applied to it).
+ *
+ * @param insets Insets to apply.
+ */
+ public void onApplyWindowInsets(WindowInsets insets) {
+ }
+
/**
* Called as the user performs touch-screen interaction with the
* window that is currently showing this wallpaper. Note that the
@@ -432,7 +463,7 @@ public abstract class WallpaperService extends Service {
*/
public void onTouchEvent(MotionEvent event) {
}
-
+
/**
* Called to inform you of the wallpaper's offsets changing
* within its contain, corresponding to the container's
@@ -443,7 +474,7 @@ public abstract class WallpaperService extends Service {
float xOffsetStep, float yOffsetStep,
int xPixelOffset, int yPixelOffset) {
}
-
+
/**
* Process a command that was sent to the wallpaper with
* {@link WallpaperManager#sendWallpaperCommand}.
@@ -465,14 +496,14 @@ public abstract class WallpaperService extends Service {
Bundle extras, boolean resultRequested) {
return null;
}
-
+
/**
* Called when an application has changed the desired virtual size of
* the wallpaper.
*/
public void onDesiredSizeChanged(int desiredWidth, int desiredHeight) {
}
-
+
/**
* Convenience for {@link SurfaceHolder.Callback#surfaceChanged
* SurfaceHolder.Callback.surfaceChanged()}.
@@ -561,16 +592,20 @@ public abstract class WallpaperService extends Service {
if (mDestroyed) {
Log.w(TAG, "Ignoring updateSurface: destroyed");
}
-
+
+ boolean fixedSize = false;
int myWidth = mSurfaceHolder.getRequestedWidth();
if (myWidth <= 0) myWidth = ViewGroup.LayoutParams.MATCH_PARENT;
+ else fixedSize = true;
int myHeight = mSurfaceHolder.getRequestedHeight();
if (myHeight <= 0) myHeight = ViewGroup.LayoutParams.MATCH_PARENT;
-
+ else fixedSize = true;
+
final boolean creating = !mCreated;
final boolean surfaceCreating = !mSurfaceCreated;
final boolean formatChanged = mFormat != mSurfaceHolder.getRequestedFormat();
boolean sizeChanged = mWidth != myWidth || mHeight != myHeight;
+ boolean insetsChanged = !mCreated;
final boolean typeChanged = mType != mSurfaceHolder.getRequestedType();
final boolean flagsChanged = mCurWindowFlags != mWindowFlags ||
mCurWindowPrivateFlags != mWindowPrivateFlags;
@@ -607,6 +642,32 @@ public abstract class WallpaperService extends Service {
mLayout.token = mWindowToken;
if (!mCreated) {
+ // Retrieve watch round and outset info
+ final WindowManager windowService = (WindowManager)getSystemService(
+ Context.WINDOW_SERVICE);
+ TypedArray windowStyle = obtainStyledAttributes(
+ com.android.internal.R.styleable.Window);
+ final Display display = windowService.getDefaultDisplay();
+ final boolean shouldUseBottomOutset =
+ display.getDisplayId() == Display.DEFAULT_DISPLAY;
+ if (shouldUseBottomOutset && windowStyle.hasValue(
+ R.styleable.Window_windowOutsetBottom)) {
+ if (mOutsetBottom == null) mOutsetBottom = new TypedValue();
+ windowStyle.getValue(R.styleable.Window_windowOutsetBottom,
+ mOutsetBottom);
+ } else {
+ mOutsetBottom = null;
+ }
+ mWindowIsRound = getResources().getBoolean(
+ com.android.internal.R.bool.config_windowIsRound);
+ windowStyle.recycle();
+
+ // detect emulator
+ mIsEmulator = Build.HARDWARE.contains("goldfish");
+ mIsCircularEmulator = SystemProperties.getBoolean(
+ ViewRootImpl.PROPERTY_EMULATOR_CIRCULAR, false);
+
+ // Add window
mLayout.type = mIWallpaperEngine.mWindowType;
mLayout.gravity = Gravity.START|Gravity.TOP;
mLayout.setTitle(WallpaperService.this.getClass().getName());
@@ -627,6 +688,11 @@ public abstract class WallpaperService extends Service {
mSurfaceHolder.mSurfaceLock.lock();
mDrawingAllowed = true;
+ if (!fixedSize) {
+ mLayout.surfaceInsets.set(mIWallpaperEngine.mDisplayPadding);
+ } 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,
@@ -636,16 +702,39 @@ public abstract class WallpaperService extends Service {
+ ", 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;
+ mOverscanInsets.left += padding.left;
+ mOverscanInsets.top += padding.top;
+ mOverscanInsets.right += padding.right;
+ mOverscanInsets.bottom += padding.bottom;
+ mContentInsets.left += padding.left;
+ mContentInsets.top += padding.top;
+ mContentInsets.right += padding.right;
+ mContentInsets.bottom += padding.bottom;
+ mStableInsets.left += padding.left;
+ mStableInsets.top += padding.top;
+ mStableInsets.right += padding.right;
+ mStableInsets.bottom += padding.bottom;
+ }
+
if (mCurWidth != w) {
sizeChanged = true;
mCurWidth = w;
}
- int h = mWinFrame.height();
if (mCurHeight != h) {
sizeChanged = true;
mCurHeight = h;
}
+ insetsChanged |= !mDispatchedOverscanInsets.equals(mOverscanInsets);
+ insetsChanged |= !mDispatchedContentInsets.equals(mContentInsets);
+ insetsChanged |= !mDispatchedStableInsets.equals(mStableInsets);
+
mSurfaceHolder.setSurfaceFrameSize(w, h);
mSurfaceHolder.mSurfaceLock.unlock();
@@ -702,6 +791,25 @@ public abstract class WallpaperService extends Service {
}
}
+ if (insetsChanged) {
+ mDispatchedOverscanInsets.set(mOverscanInsets);
+ mDispatchedContentInsets.set(mContentInsets);
+ mDispatchedStableInsets.set(mStableInsets);
+ final boolean isRound = (mIsEmulator && mIsCircularEmulator)
+ || mWindowIsRound;
+ mFinalSystemInsets.set(mDispatchedOverscanInsets);
+ mFinalStableInsets.set(mDispatchedStableInsets);
+ if (mOutsetBottom != null) {
+ final DisplayMetrics metrics = getResources().getDisplayMetrics();
+ mFinalSystemInsets.bottom =
+ ( (int) mOutsetBottom.getDimension(metrics) )
+ + mIWallpaperEngine.mDisplayPadding.bottom;
+ }
+ WindowInsets insets = new WindowInsets(mFinalSystemInsets,
+ null, mFinalStableInsets, isRound);
+ onApplyWindowInsets(insets);
+ }
+
if (redrawNeeded) {
onSurfaceRedrawNeeded(mSurfaceHolder);
SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks();
@@ -781,7 +889,7 @@ public abstract class WallpaperService extends Service {
mReportedVisible = false;
updateSurface(false, false, false);
}
-
+
void doDesiredSizeChanged(int desiredWidth, int desiredHeight) {
if (!mDestroyed) {
if (DEBUG) Log.v(TAG, "onDesiredSizeChanged("
@@ -792,14 +900,24 @@ public abstract class WallpaperService extends Service {
doOffsetsChanged(true);
}
}
-
+
+ void doDisplayPaddingChanged(Rect padding) {
+ if (!mDestroyed) {
+ if (DEBUG) Log.v(TAG, "onDisplayPaddingChanged(" + padding + "): " + this);
+ if (!mIWallpaperEngine.mDisplayPadding.equals(padding)) {
+ mIWallpaperEngine.mDisplayPadding.set(padding);
+ updateSurface(true, false, false);
+ }
+ }
+ }
+
void doVisibilityChanged(boolean visible) {
if (!mDestroyed) {
mVisible = visible;
reportVisibility();
}
}
-
+
void reportVisibility() {
if (!mDestroyed) {
boolean visible = mVisible && mScreenOn;
@@ -956,12 +1074,13 @@ public abstract class WallpaperService extends Service {
boolean mShownReported;
int mReqWidth;
int mReqHeight;
-
+ final Rect mDisplayPadding = new Rect();
+
Engine mEngine;
-
+
IWallpaperEngineWrapper(WallpaperService context,
IWallpaperConnection conn, IBinder windowToken,
- int windowType, boolean isPreview, int reqWidth, int reqHeight) {
+ int windowType, boolean isPreview, int reqWidth, int reqHeight, Rect padding) {
mCaller = new HandlerCaller(context, context.getMainLooper(), this, true);
mConnection = conn;
mWindowToken = windowToken;
@@ -969,16 +1088,22 @@ public abstract class WallpaperService extends Service {
mIsPreview = isPreview;
mReqWidth = reqWidth;
mReqHeight = reqHeight;
+ mDisplayPadding.set(padding);
Message msg = mCaller.obtainMessage(DO_ATTACH);
mCaller.sendMessage(msg);
}
-
+
public void setDesiredSize(int width, int height) {
Message msg = mCaller.obtainMessageII(DO_SET_DESIRED_SIZE, width, height);
mCaller.sendMessage(msg);
}
-
+
+ public void setDisplayPadding(Rect padding) {
+ Message msg = mCaller.obtainMessageO(DO_SET_DISPLAY_PADDING, padding);
+ mCaller.sendMessage(msg);
+ }
+
public void setVisibility(boolean visible) {
Message msg = mCaller.obtainMessageI(MSG_VISIBILITY_CHANGED,
visible ? 1 : 0);
@@ -1041,6 +1166,9 @@ public abstract class WallpaperService extends Service {
mEngine.doDesiredSizeChanged(message.arg1, message.arg2);
return;
}
+ case DO_SET_DISPLAY_PADDING: {
+ mEngine.doDisplayPaddingChanged((Rect) message.obj);
+ }
case MSG_UPDATE_SURFACE:
mEngine.updateSurface(true, false, false);
break;
@@ -1102,9 +1230,9 @@ public abstract class WallpaperService extends Service {
@Override
public void attach(IWallpaperConnection conn, IBinder windowToken,
- int windowType, boolean isPreview, int reqWidth, int reqHeight) {
+ int windowType, boolean isPreview, int reqWidth, int reqHeight, Rect padding) {
new IWallpaperEngineWrapper(mTarget, conn, windowToken,
- windowType, isPreview, reqWidth, reqHeight);
+ windowType, isPreview, reqWidth, reqHeight, padding);
}
}
diff --git a/core/java/android/transition/Transition.java b/core/java/android/transition/Transition.java
index 0d1b568..40bb6ec 100644
--- a/core/java/android/transition/Transition.java
+++ b/core/java/android/transition/Transition.java
@@ -1417,9 +1417,9 @@ public abstract class Transition implements Cloneable {
}
capturePropagationValues(values);
if (start) {
- addViewValues(mStartValues, view, values);
+ addViewValues(mStartValues, view, values, true);
} else {
- addViewValues(mEndValues, view, values);
+ addViewValues(mEndValues, view, values, true);
}
}
}
@@ -1460,7 +1460,7 @@ public abstract class Transition implements Cloneable {
}
static void addViewValues(TransitionValuesMaps transitionValuesMaps,
- View view, TransitionValues transitionValues) {
+ View view, TransitionValues transitionValues, boolean setTransientState) {
transitionValuesMaps.viewValues.put(view, transitionValues);
int id = view.getId();
if (id >= 0) {
@@ -1489,11 +1489,15 @@ public abstract class Transition implements Cloneable {
// Duplicate item IDs: cannot match by item ID.
View alreadyMatched = transitionValuesMaps.itemIdValues.get(itemId);
if (alreadyMatched != null) {
- alreadyMatched.setHasTransientState(false);
+ if (setTransientState) {
+ alreadyMatched.setHasTransientState(false);
+ }
transitionValuesMaps.itemIdValues.put(itemId, null);
}
} else {
- view.setHasTransientState(true);
+ if (setTransientState) {
+ view.setHasTransientState(true);
+ }
transitionValuesMaps.itemIdValues.put(itemId, view);
}
}
@@ -1560,9 +1564,9 @@ public abstract class Transition implements Cloneable {
}
capturePropagationValues(values);
if (start) {
- addViewValues(mStartValues, view, values);
+ addViewValues(mStartValues, view, values, true);
} else {
- addViewValues(mEndValues, view, values);
+ addViewValues(mEndValues, view, values, true);
}
}
if (view instanceof ViewGroup) {
diff --git a/core/java/android/transition/TransitionSet.java b/core/java/android/transition/TransitionSet.java
index f6499ae..56db674 100644
--- a/core/java/android/transition/TransitionSet.java
+++ b/core/java/android/transition/TransitionSet.java
@@ -408,7 +408,7 @@ public class TransitionSet extends Transition {
for (int i = 0; i < numValues; i++) {
View view = values.viewValues.keyAt(i);
if (isValidTarget(view)) {
- addViewValues(included, view, values.viewValues.valueAt(i));
+ addViewValues(included, view, values.viewValues.valueAt(i), false);
}
}
return included;
diff --git a/core/java/android/view/AccessibilityInteractionController.java b/core/java/android/view/AccessibilityInteractionController.java
index a10dda3..a283b91 100644
--- a/core/java/android/view/AccessibilityInteractionController.java
+++ b/core/java/android/view/AccessibilityInteractionController.java
@@ -19,7 +19,6 @@ package android.view;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.Region;
-import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
@@ -101,7 +100,7 @@ final class AccessibilityInteractionController {
IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid,
long interrogatingTid, MagnificationSpec spec) {
Message message = mHandler.obtainMessage();
- message.what = PrivateHandler.MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_ACCESSIBILITY_ID;
+ message.what = PrivateHandler.MSG_FIND_ACCESSIBILITY_NODE_INFO_BY_ACCESSIBILITY_ID;
message.arg1 = flags;
SomeArgs args = SomeArgs.obtain();
@@ -176,7 +175,7 @@ final class AccessibilityInteractionController {
IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid,
long interrogatingTid, MagnificationSpec spec) {
Message message = mHandler.obtainMessage();
- message.what = PrivateHandler.MSG_FIND_ACCESSIBLITY_NODE_INFOS_BY_VIEW_ID;
+ message.what = PrivateHandler.MSG_FIND_ACCESSIBILITY_NODE_INFOS_BY_VIEW_ID;
message.arg1 = flags;
message.arg2 = AccessibilityNodeInfo.getAccessibilityViewId(accessibilityNodeId);
@@ -261,7 +260,7 @@ final class AccessibilityInteractionController {
IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid,
long interrogatingTid, MagnificationSpec spec) {
Message message = mHandler.obtainMessage();
- message.what = PrivateHandler.MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_TEXT;
+ message.what = PrivateHandler.MSG_FIND_ACCESSIBILITY_NODE_INFO_BY_TEXT;
message.arg1 = flags;
SomeArgs args = SomeArgs.obtain();
@@ -637,6 +636,95 @@ final class AccessibilityInteractionController {
}
}
+ public void computeClickPointInScreenClientThread(long accessibilityNodeId,
+ Region interactiveRegion, int interactionId,
+ IAccessibilityInteractionConnectionCallback callback, int interrogatingPid,
+ long interrogatingTid, MagnificationSpec spec) {
+ Message message = mHandler.obtainMessage();
+ message.what = PrivateHandler.MSG_COMPUTE_CLICK_POINT_IN_SCREEN;
+
+ SomeArgs args = SomeArgs.obtain();
+ args.argi1 = AccessibilityNodeInfo.getAccessibilityViewId(accessibilityNodeId);
+ args.argi2 = AccessibilityNodeInfo.getVirtualDescendantId(accessibilityNodeId);
+ args.argi3 = interactionId;
+ args.arg1 = callback;
+ args.arg2 = spec;
+ args.arg3 = interactiveRegion;
+
+ message.obj = args;
+
+ // If the interrogation is performed by the same thread as the main UI
+ // thread in this process, set the message as a static reference so
+ // after this call completes the same thread but in the interrogating
+ // client can handle the message to generate the result.
+ if (interrogatingPid == mMyProcessId && interrogatingTid == mMyLooperThreadId) {
+ AccessibilityInteractionClient.getInstanceForThread(
+ interrogatingTid).setSameThreadMessage(message);
+ } else {
+ mHandler.sendMessage(message);
+ }
+ }
+
+ private void computeClickPointInScreenUiThread(Message message) {
+ SomeArgs args = (SomeArgs) message.obj;
+ final int accessibilityViewId = args.argi1;
+ final int virtualDescendantId = args.argi2;
+ final int interactionId = args.argi3;
+ final IAccessibilityInteractionConnectionCallback callback =
+ (IAccessibilityInteractionConnectionCallback) args.arg1;
+ final MagnificationSpec spec = (MagnificationSpec) args.arg2;
+ final Region interactiveRegion = (Region) args.arg3;
+ args.recycle();
+
+ boolean succeeded = false;
+ Point point = mTempPoint;
+ try {
+ if (mViewRootImpl.mView == null || mViewRootImpl.mAttachInfo == null) {
+ return;
+ }
+ View target = null;
+ if (accessibilityViewId != AccessibilityNodeInfo.UNDEFINED_ITEM_ID) {
+ target = findViewByAccessibilityId(accessibilityViewId);
+ } else {
+ target = mViewRootImpl.mView;
+ }
+ if (target != null && isShown(target)) {
+ AccessibilityNodeProvider provider = target.getAccessibilityNodeProvider();
+ if (provider != null) {
+ // For virtual views just use the center of the bounds in screen.
+ AccessibilityNodeInfo node = null;
+ if (virtualDescendantId != AccessibilityNodeInfo.UNDEFINED_ITEM_ID) {
+ node = provider.createAccessibilityNodeInfo(virtualDescendantId);
+ } else {
+ node = provider.createAccessibilityNodeInfo(
+ AccessibilityNodeProvider.HOST_VIEW_ID);
+ }
+ if (node != null) {
+ succeeded = true;
+ Rect boundsInScreen = mTempRect;
+ node.getBoundsInScreen(boundsInScreen);
+ point.set(boundsInScreen.centerX(), boundsInScreen.centerY());
+ }
+ } else if (virtualDescendantId == AccessibilityNodeInfo.UNDEFINED_ITEM_ID) {
+ // For a real view, ask the view to compute the click point.
+ succeeded = target.computeClickPointInScreenForAccessibility(
+ interactiveRegion, point);
+ }
+ }
+ } finally {
+ try {
+ Point result = null;
+ if (succeeded) {
+ applyAppScaleAndMagnificationSpecIfNeeded(point, spec);
+ result = point;
+ }
+ callback.setComputeClickPointInScreenActionResult(result, interactionId);
+ } catch (RemoteException re) {
+ /* ignore - the other side will time out */
+ }
+ }
+ }
+
private View findViewByAccessibilityId(int accessibilityId) {
View root = mViewRootImpl.mView;
if (root == null) {
@@ -688,6 +776,26 @@ final class AccessibilityInteractionController {
}
}
+ private void applyAppScaleAndMagnificationSpecIfNeeded(Point point,
+ MagnificationSpec spec) {
+ final float applicationScale = mViewRootImpl.mAttachInfo.mApplicationScale;
+ if (!shouldApplyAppScaleAndMagnificationSpec(applicationScale, spec)) {
+ return;
+ }
+
+ if (applicationScale != 1.0f) {
+ point.x *= applicationScale;
+ point.y *= applicationScale;
+ }
+
+ if (spec != null) {
+ point.x *= spec.scale;
+ point.y *= spec.scale;
+ point.x += (int) spec.offsetX;
+ point.y += (int) spec.offsetY;
+ }
+ }
+
private void applyAppScaleAndMagnificationSpecIfNeeded(AccessibilityNodeInfo info,
MagnificationSpec spec) {
if (info == null) {
@@ -1080,11 +1188,12 @@ final class AccessibilityInteractionController {
private class PrivateHandler extends Handler {
private final static int MSG_PERFORM_ACCESSIBILITY_ACTION = 1;
- private final static int MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_ACCESSIBILITY_ID = 2;
- private final static int MSG_FIND_ACCESSIBLITY_NODE_INFOS_BY_VIEW_ID = 3;
- private final static int MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_TEXT = 4;
+ private final static int MSG_FIND_ACCESSIBILITY_NODE_INFO_BY_ACCESSIBILITY_ID = 2;
+ private final static int MSG_FIND_ACCESSIBILITY_NODE_INFOS_BY_VIEW_ID = 3;
+ private final static int MSG_FIND_ACCESSIBILITY_NODE_INFO_BY_TEXT = 4;
private final static int MSG_FIND_FOCUS = 5;
private final static int MSG_FOCUS_SEARCH = 6;
+ private final static int MSG_COMPUTE_CLICK_POINT_IN_SCREEN = 7;
public PrivateHandler(Looper looper) {
super(looper);
@@ -1096,16 +1205,18 @@ final class AccessibilityInteractionController {
switch (type) {
case MSG_PERFORM_ACCESSIBILITY_ACTION:
return "MSG_PERFORM_ACCESSIBILITY_ACTION";
- case MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_ACCESSIBILITY_ID:
- return "MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_ACCESSIBILITY_ID";
- case MSG_FIND_ACCESSIBLITY_NODE_INFOS_BY_VIEW_ID:
- return "MSG_FIND_ACCESSIBLITY_NODE_INFOS_BY_VIEW_ID";
- case MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_TEXT:
- return "MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_TEXT";
+ case MSG_FIND_ACCESSIBILITY_NODE_INFO_BY_ACCESSIBILITY_ID:
+ return "MSG_FIND_ACCESSIBILITY_NODE_INFO_BY_ACCESSIBILITY_ID";
+ case MSG_FIND_ACCESSIBILITY_NODE_INFOS_BY_VIEW_ID:
+ return "MSG_FIND_ACCESSIBILITY_NODE_INFOS_BY_VIEW_ID";
+ case MSG_FIND_ACCESSIBILITY_NODE_INFO_BY_TEXT:
+ return "MSG_FIND_ACCESSIBILITY_NODE_INFO_BY_TEXT";
case MSG_FIND_FOCUS:
return "MSG_FIND_FOCUS";
case MSG_FOCUS_SEARCH:
return "MSG_FOCUS_SEARCH";
+ case MSG_COMPUTE_CLICK_POINT_IN_SCREEN:
+ return "MSG_COMPUTE_CLICK_POINT_IN_SCREEN";
default:
throw new IllegalArgumentException("Unknown message type: " + type);
}
@@ -1115,16 +1226,16 @@ final class AccessibilityInteractionController {
public void handleMessage(Message message) {
final int type = message.what;
switch (type) {
- case MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_ACCESSIBILITY_ID: {
+ case MSG_FIND_ACCESSIBILITY_NODE_INFO_BY_ACCESSIBILITY_ID: {
findAccessibilityNodeInfoByAccessibilityIdUiThread(message);
} break;
case MSG_PERFORM_ACCESSIBILITY_ACTION: {
perfromAccessibilityActionUiThread(message);
} break;
- case MSG_FIND_ACCESSIBLITY_NODE_INFOS_BY_VIEW_ID: {
+ case MSG_FIND_ACCESSIBILITY_NODE_INFOS_BY_VIEW_ID: {
findAccessibilityNodeInfosByViewIdUiThread(message);
} break;
- case MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_TEXT: {
+ case MSG_FIND_ACCESSIBILITY_NODE_INFO_BY_TEXT: {
findAccessibilityNodeInfosByTextUiThread(message);
} break;
case MSG_FIND_FOCUS: {
@@ -1133,6 +1244,9 @@ final class AccessibilityInteractionController {
case MSG_FOCUS_SEARCH: {
focusSearchUiThread(message);
} break;
+ case MSG_COMPUTE_CLICK_POINT_IN_SCREEN: {
+ computeClickPointInScreenUiThread(message);
+ } break;
default:
throw new IllegalArgumentException("Unknown message type: " + type);
}
diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl
index 0f3f182..037ed28 100644
--- a/core/java/android/view/IWindowSession.aidl
+++ b/core/java/android/view/IWindowSession.aidl
@@ -177,6 +177,11 @@ interface IWindowSession {
void wallpaperOffsetsComplete(IBinder window);
+ /**
+ * Apply a raw offset to the wallpaper service when shown behind this window.
+ */
+ void setWallpaperDisplayOffset(IBinder windowToken, int x, int y);
+
Bundle sendWallpaperCommand(IBinder window, String action, int x, int y,
int z, in Bundle extras, boolean sync);
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 1e28e33..4074529 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -39,7 +39,7 @@ public class SurfaceControl {
private static native Bitmap nativeScreenshot(IBinder displayToken,
Rect sourceCrop, int width, int height, int minLayer, int maxLayer,
- boolean allLayers, boolean useIdentityTransform);
+ boolean allLayers, boolean useIdentityTransform, int rotation);
private static native void nativeScreenshot(IBinder displayToken, Surface consumer,
Rect sourceCrop, int width, int height, int minLayer, int maxLayer,
boolean allLayers, boolean useIdentityTransform);
@@ -688,17 +688,23 @@ public class SurfaceControl {
* @param useIdentityTransform Replace whatever transformation (rotation,
* scaling, translation) the surface layers are currently using with the
* identity transformation while taking the screenshot.
+ * @param rotation Apply a custom clockwise rotation to the screenshot, i.e.
+ * Surface.ROTATION_0,90,180,270. Surfaceflinger will always take
+ * screenshots in its native portrait orientation by default, so this is
+ * useful for returning screenshots that are independent of device
+ * orientation.
* @return Returns a Bitmap containing the screen contents, or null
* if an error occurs. Make sure to call Bitmap.recycle() as soon as
* possible, once its content is not needed anymore.
*/
public static Bitmap screenshot(Rect sourceCrop, int width, int height,
- int minLayer, int maxLayer, boolean useIdentityTransform) {
+ int minLayer, int maxLayer, boolean useIdentityTransform,
+ int rotation) {
// TODO: should take the display as a parameter
IBinder displayToken = SurfaceControl.getBuiltInDisplay(
SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN);
return nativeScreenshot(displayToken, sourceCrop, width, height,
- minLayer, maxLayer, false, useIdentityTransform);
+ minLayer, maxLayer, false, useIdentityTransform, rotation);
}
/**
@@ -717,7 +723,8 @@ public class SurfaceControl {
// TODO: should take the display as a parameter
IBinder displayToken = SurfaceControl.getBuiltInDisplay(
SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN);
- return nativeScreenshot(displayToken, new Rect(), width, height, 0, 0, true, false);
+ return nativeScreenshot(displayToken, new Rect(), width, height, 0, 0, true,
+ false, Surface.ROTATION_0);
}
private static void screenshot(IBinder display, Surface consumer, Rect sourceCrop,
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 770e78c..82c5425 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -35,6 +35,8 @@ import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Outline;
import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.PathMeasure;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.PorterDuff;
@@ -5731,6 +5733,136 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
/**
+ * Computes a point on which a sequence of a down/up event can be sent to
+ * trigger clicking this view. This method is for the exclusive use by the
+ * accessibility layer to determine where to send a click event in explore
+ * by touch mode.
+ *
+ * @param interactiveRegion The interactive portion of this window.
+ * @param outPoint The point to populate.
+ * @return True of such a point exists.
+ */
+ boolean computeClickPointInScreenForAccessibility(Region interactiveRegion,
+ Point outPoint) {
+ // Since the interactive portion of the view is a region but as a view
+ // may have a transformation matrix which cannot be applied to a
+ // region we compute the view bounds rectangle and all interactive
+ // predecessor's and sibling's (siblings of predecessors included)
+ // rectangles that intersect the view bounds. At the
+ // end if the view was partially covered by another interactive
+ // view we compute the view's interactive region and pick a point
+ // on its boundary path as regions do not offer APIs to get inner
+ // points. Note that the the code is optimized to fail early and
+ // avoid unnecessary allocations plus computations.
+
+ // The current approach has edge cases that may produce false
+ // positives or false negatives. For example, a portion of the
+ // view may be covered by an interactive descendant of a
+ // predecessor, which we do not compute. Also a view may be handling
+ // raw touch events instead registering click listeners, which
+ // we cannot compute. Despite these limitations this approach will
+ // work most of the time and it is a huge improvement over just
+ // blindly sending the down and up events in the center of the
+ // view.
+
+ // Cannot click on an unattached view.
+ if (mAttachInfo == null) {
+ return false;
+ }
+
+ // Attached to an invisible window means this view is not visible.
+ if (mAttachInfo.mWindowVisibility != View.VISIBLE) {
+ return false;
+ }
+
+ RectF bounds = mAttachInfo.mTmpTransformRect;
+ bounds.set(0, 0, getWidth(), getHeight());
+ List<RectF> intersections = mAttachInfo.mTmpRectList;
+ intersections.clear();
+
+ if (mParent instanceof ViewGroup) {
+ ViewGroup parentGroup = (ViewGroup) mParent;
+ if (!parentGroup.translateBoundsAndIntersectionsInWindowCoordinates(
+ this, bounds, intersections)) {
+ intersections.clear();
+ return false;
+ }
+ }
+
+ // Take into account the window location.
+ final int dx = mAttachInfo.mWindowLeft;
+ final int dy = mAttachInfo.mWindowTop;
+ bounds.offset(dx, dy);
+ offsetRects(intersections, dx, dy);
+
+ if (intersections.isEmpty() && interactiveRegion == null) {
+ outPoint.set((int) bounds.centerX(), (int) bounds.centerY());
+ } else {
+ // This view is partially covered by other views, then compute
+ // the not covered region and pick a point on its boundary.
+ Region region = new Region();
+ region.set((int) bounds.left, (int) bounds.top,
+ (int) bounds.right, (int) bounds.bottom);
+
+ final int intersectionCount = intersections.size();
+ for (int i = intersectionCount - 1; i >= 0; i--) {
+ RectF intersection = intersections.remove(i);
+ region.op((int) intersection.left, (int) intersection.top,
+ (int) intersection.right, (int) intersection.bottom,
+ Region.Op.DIFFERENCE);
+ }
+
+ // If the view is completely covered, done.
+ if (region.isEmpty()) {
+ return false;
+ }
+
+ // Take into account the interactive portion of the window
+ // as the rest is covered by other windows. If no such a region
+ // then the whole window is interactive.
+ if (interactiveRegion != null) {
+ region.op(interactiveRegion, Region.Op.INTERSECT);
+ }
+
+ // If the view is completely covered, done.
+ if (region.isEmpty()) {
+ return false;
+ }
+
+ // Try a shortcut here.
+ if (region.isRect()) {
+ Rect regionBounds = mAttachInfo.mTmpInvalRect;
+ region.getBounds(regionBounds);
+ outPoint.set(regionBounds.centerX(), regionBounds.centerY());
+ return true;
+ }
+
+ // Get the a point on the region boundary path.
+ Path path = region.getBoundaryPath();
+ PathMeasure pathMeasure = new PathMeasure(path, false);
+ final float[] coordinates = mAttachInfo.mTmpTransformLocation;
+
+ // Without loss of generality pick a point.
+ final float point = pathMeasure.getLength() * 0.01f;
+ if (!pathMeasure.getPosTan(point, coordinates, null)) {
+ return false;
+ }
+
+ outPoint.set(Math.round(coordinates[0]), Math.round(coordinates[1]));
+ }
+
+ return true;
+ }
+
+ static void offsetRects(List<RectF> rects, float offsetX, float offsetY) {
+ final int rectCount = rects.size();
+ for (int i = 0; i < rectCount; i++) {
+ RectF intersection = rects.get(i);
+ intersection.offset(offsetX, offsetY);
+ }
+ }
+
+ /**
* Returns the delegate for implementing accessibility support via
* composition. For more details see {@link AccessibilityDelegate}.
*
@@ -20154,6 +20286,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
final RectF mTmpTransformRect = new RectF();
/**
+ * Temporary for use in computing hit areas with transformed views
+ */
+ final RectF mTmpTransformRect1 = new RectF();
+
+ /**
+ * Temporary list of rectanges.
+ */
+ final List<RectF> mTmpRectList = new ArrayList<>();
+
+ /**
* Temporary for use in transforming invalidation rect
*/
final Matrix mTmpMatrix = new Matrix();
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index c1e66de..4e1db90 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -771,6 +771,112 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
}
/**
+ * Translates the given bounds and intersections from child coordinates to
+ * local coordinates. In case any interactive sibling of the calling child
+ * covers the latter, a new intersections is added to the intersection list.
+ * This method is for the exclusive use by the accessibility layer to compute
+ * a point where a sequence of down and up events would click on a view.
+ *
+ * @param child The child making the call.
+ * @param bounds The bounds to translate in child coordinates.
+ * @param intersections The intersections of interactive views covering the child.
+ * @return True if the bounds and intersections were computed, false otherwise.
+ */
+ boolean translateBoundsAndIntersectionsInWindowCoordinates(View child,
+ RectF bounds, List<RectF> intersections) {
+ // Not attached, done.
+ if (mAttachInfo == null) {
+ return false;
+ }
+
+ if (getAlpha() <= 0 || getTransitionAlpha() <= 0 ||
+ getVisibility() != VISIBLE) {
+ // Cannot click on a view with an invisible predecessor.
+ return false;
+ }
+
+ // Compensate for the child transformation.
+ if (!child.hasIdentityMatrix()) {
+ Matrix matrix = child.getMatrix();
+ matrix.mapRect(bounds);
+ final int intersectionCount = intersections.size();
+ for (int i = 0; i < intersectionCount; i++) {
+ RectF intersection = intersections.get(i);
+ matrix.mapRect(intersection);
+ }
+ }
+
+ // Translate the bounds from child to parent coordinates.
+ final int dx = child.mLeft - mScrollX;
+ final int dy = child.mTop - mScrollY;
+ bounds.offset(dx, dy);
+ offsetRects(intersections, dx, dy);
+
+ // If the bounds do not intersect our bounds, done.
+ if (!bounds.intersects(0, 0, getWidth(), getHeight())) {
+ return false;
+ }
+
+ // Check whether any clickable siblings cover the child
+ // view and if so keep track of the intersections. Also
+ // respect Z ordering when iterating over children.
+ ArrayList<View> orderedList = buildOrderedChildList();
+ final boolean useCustomOrder = orderedList == null
+ && isChildrenDrawingOrderEnabled();
+
+ final int childCount = mChildrenCount;
+ for (int i = childCount - 1; i >= 0; i--) {
+ final int childIndex = useCustomOrder
+ ? getChildDrawingOrder(childCount, i) : i;
+ final View sibling = (orderedList == null)
+ ? mChildren[childIndex] : orderedList.get(childIndex);
+
+ // We care only about siblings over the child.
+ if (sibling == child) {
+ break;
+ }
+
+ // If sibling is not interactive we do not care.
+ if (!sibling.isClickable() && !sibling.isLongClickable()) {
+ continue;
+ }
+
+ // Compute the sibling bounds in its coordinates.
+ RectF siblingBounds = mAttachInfo.mTmpTransformRect1;
+ siblingBounds.set(0, 0, sibling.getWidth(), sibling.getHeight());
+
+ // Take into account the sibling transformation matrix.
+ if (!sibling.hasIdentityMatrix()) {
+ sibling.getMatrix().mapRect(siblingBounds);
+ }
+
+ // Offset the sibling to our coordinates.
+ final int siblingDx = sibling.mLeft - mScrollX;
+ final int siblingDy = sibling.mTop - mScrollY;
+ siblingBounds.offset(siblingDx, siblingDy);
+
+ // Compute the intersection between the child and the sibling.
+ if (siblingBounds.intersect(bounds)) {
+ // If an interactive sibling completely covers the child, done.
+ if (siblingBounds.equals(bounds)) {
+ return false;
+ }
+ // Keep track of the intersection rectangle.
+ RectF intersection = new RectF(siblingBounds);
+ intersections.add(intersection);
+ }
+ }
+
+ if (mParent instanceof ViewGroup) {
+ ViewGroup parentGroup = (ViewGroup) mParent;
+ return parentGroup.translateBoundsAndIntersectionsInWindowCoordinates(
+ this, bounds, intersections);
+ }
+
+ return true;
+ }
+
+ /**
* Called when a child view has changed whether or not it is tracking transient state.
*/
public void childHasTransientStateChanged(View child, boolean childHasTransientState) {
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 4299e2e..43ab4ef 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -121,7 +121,7 @@ public final class ViewRootImpl implements ViewParent,
private static final String PROPERTY_MEDIA_DISABLED = "config.disable_media";
// property used by emulator to determine display shape
- private static final String PROPERTY_EMULATOR_CIRCULAR = "ro.emulator.circular";
+ public static final String PROPERTY_EMULATOR_CIRCULAR = "ro.emulator.circular";
/**
* Maximum time we allow the user to roll the trackball enough to generate
@@ -6679,12 +6679,12 @@ public final class ViewRootImpl implements ViewParent,
public void performAccessibilityAction(long accessibilityNodeId, int action,
Bundle arguments, int interactionId,
IAccessibilityInteractionConnectionCallback callback, int flags,
- int interogatingPid, long interrogatingTid) {
+ int interrogatingPid, long interrogatingTid) {
ViewRootImpl viewRootImpl = mViewRootImpl.get();
if (viewRootImpl != null && viewRootImpl.mView != null) {
viewRootImpl.getAccessibilityInteractionController()
.performAccessibilityActionClientThread(accessibilityNodeId, action, arguments,
- interactionId, callback, flags, interogatingPid, interrogatingTid);
+ interactionId, callback, flags, interrogatingPid, interrogatingTid);
} else {
// We cannot make the call and notify the caller so it does not wait.
try {
@@ -6696,6 +6696,26 @@ public final class ViewRootImpl implements ViewParent,
}
@Override
+ public void computeClickPointInScreen(long accessibilityNodeId, Region interactiveRegion,
+ int interactionId, IAccessibilityInteractionConnectionCallback callback,
+ int interrogatingPid, long interrogatingTid, MagnificationSpec spec) {
+ ViewRootImpl viewRootImpl = mViewRootImpl.get();
+ if (viewRootImpl != null && viewRootImpl.mView != null) {
+ viewRootImpl.getAccessibilityInteractionController()
+ .computeClickPointInScreenClientThread(accessibilityNodeId,
+ interactiveRegion, interactionId, callback, interrogatingPid,
+ interrogatingTid, spec);
+ } else {
+ // We cannot make the call and notify the caller so it does not wait.
+ try {
+ callback.setComputeClickPointInScreenActionResult(null, interactionId);
+ } catch (RemoteException re) {
+ /* best effort - ignore */
+ }
+ }
+ }
+
+ @Override
public void findAccessibilityNodeInfosByViewId(long accessibilityNodeId,
String viewId, Region interactiveRegion, int interactionId,
IAccessibilityInteractionConnectionCallback callback, int flags,
diff --git a/core/java/android/view/WindowInsets.java b/core/java/android/view/WindowInsets.java
index 571a8f0..24c3c1a 100644
--- a/core/java/android/view/WindowInsets.java
+++ b/core/java/android/view/WindowInsets.java
@@ -378,35 +378,75 @@ public final class WindowInsets {
}
/**
- * @hide
+ * Returns the top stable inset in pixels.
+ *
+ * <p>The stable inset represents the area of a full-screen window that <b>may</b> be
+ * partially or fully obscured by the system UI elements. This value does not change
+ * based on the visibility state of those elements; for example, if the status bar is
+ * normally shown, but temporarily hidden, the stable inset will still provide the inset
+ * associated with the status bar being shown.</p>
+ *
+ * @return The top stable inset
*/
public int getStableInsetTop() {
return mStableInsets.top;
}
/**
- * @hide
+ * Returns the left stable inset in pixels.
+ *
+ * <p>The stable inset represents the area of a full-screen window that <b>may</b> be
+ * partially or fully obscured by the system UI elements. This value does not change
+ * based on the visibility state of those elements; for example, if the status bar is
+ * normally shown, but temporarily hidden, the stable inset will still provide the inset
+ * associated with the status bar being shown.</p>
+ *
+ * @return The left stable inset
*/
public int getStableInsetLeft() {
return mStableInsets.left;
}
/**
- * @hide
+ * Returns the right stable inset in pixels.
+ *
+ * <p>The stable inset represents the area of a full-screen window that <b>may</b> be
+ * partially or fully obscured by the system UI elements. This value does not change
+ * based on the visibility state of those elements; for example, if the status bar is
+ * normally shown, but temporarily hidden, the stable inset will still provide the inset
+ * associated with the status bar being shown.</p>
+ *
+ * @return The right stable inset
*/
public int getStableInsetRight() {
return mStableInsets.right;
}
/**
- * @hide
+ * Returns the bottom stable inset in pixels.
+ *
+ * <p>The stable inset represents the area of a full-screen window that <b>may</b> be
+ * partially or fully obscured by the system UI elements. This value does not change
+ * based on the visibility state of those elements; for example, if the status bar is
+ * normally shown, but temporarily hidden, the stable inset will still provide the inset
+ * associated with the status bar being shown.</p>
+ *
+ * @return The bottom stable inset
*/
public int getStableInsetBottom() {
return mStableInsets.bottom;
}
/**
- * @hide
+ * Returns true if this WindowInsets has nonzero stable insets.
+ *
+ * <p>The stable inset represents the area of a full-screen window that <b>may</b> be
+ * partially or fully obscured by the system UI elements. This value does not change
+ * based on the visibility state of those elements; for example, if the status bar is
+ * normally shown, but temporarily hidden, the stable inset will still provide the inset
+ * associated with the status bar being shown.</p>
+ *
+ * @return true if any of the stable inset values are nonzero
*/
public boolean hasStableInsets() {
return mStableInsets.top != 0 || mStableInsets.left != 0 || mStableInsets.right != 0
@@ -414,7 +454,9 @@ public final class WindowInsets {
}
/**
- * @hide
+ * Returns a copy of this WindowInsets with the stable insets fully consumed.
+ *
+ * @return A modified copy of this WindowInsets
*/
public WindowInsets consumeStableInsets() {
final WindowInsets result = new WindowInsets(this);
diff --git a/core/java/android/view/accessibility/AccessibilityInteractionClient.java b/core/java/android/view/accessibility/AccessibilityInteractionClient.java
index db78ec5..374f7e0 100644
--- a/core/java/android/view/accessibility/AccessibilityInteractionClient.java
+++ b/core/java/android/view/accessibility/AccessibilityInteractionClient.java
@@ -17,6 +17,7 @@
package android.view.accessibility;
import android.accessibilityservice.IAccessibilityServiceConnection;
+import android.graphics.Point;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
@@ -98,6 +99,8 @@ public final class AccessibilityInteractionClient
private boolean mPerformAccessibilityActionResult;
+ private Point mComputeClickPointResult;
+
private Message mSameThreadMessage;
private static final SparseArray<IAccessibilityServiceConnection> sConnectionCache =
@@ -519,6 +522,43 @@ public final class AccessibilityInteractionClient
return false;
}
+ /**
+ * Computes a point in screen coordinates where sending a down/up events would
+ * perform a click on an {@link AccessibilityNodeInfo}.
+ *
+ * @param connectionId The id of a connection for interacting with the system.
+ * @param accessibilityWindowId A unique window id. Use
+ * {@link android.view.accessibility.AccessibilityNodeInfo#ACTIVE_WINDOW_ID}
+ * to query the currently active window.
+ * @param accessibilityNodeId A unique view id or virtual descendant id from
+ * where to start the search. Use
+ * {@link android.view.accessibility.AccessibilityNodeInfo#ROOT_NODE_ID}
+ * to start from the root.
+ * @return Point the click point of null if no such point.
+ */
+ public Point computeClickPointInScreen(int connectionId, int accessibilityWindowId,
+ long accessibilityNodeId) {
+ try {
+ IAccessibilityServiceConnection connection = getConnection(connectionId);
+ if (connection != null) {
+ final int interactionId = mInteractionIdCounter.getAndIncrement();
+ final boolean success = connection.computeClickPointInScreen(
+ accessibilityWindowId, accessibilityNodeId,
+ interactionId, this, Thread.currentThread().getId());
+ if (success) {
+ return getComputeClickPointInScreenResultAndClear(interactionId);
+ }
+ } else {
+ if (DEBUG) {
+ Log.w(LOG_TAG, "No connection for connection id: " + connectionId);
+ }
+ }
+ } catch (RemoteException re) {
+ Log.w(LOG_TAG, "Error while calling remote computeClickPointInScreen", re);
+ }
+ return null;
+ }
+
public void clearCache() {
sAccessibilityCache.clear();
}
@@ -634,6 +674,34 @@ public final class AccessibilityInteractionClient
}
/**
+ * Gets the result of a request to compute a point in screen for clicking on a node.
+ *
+ * @param interactionId The interaction id to match the result with the request.
+ * @return The point or null if no such point.
+ */
+ private Point getComputeClickPointInScreenResultAndClear(int interactionId) {
+ synchronized (mInstanceLock) {
+ final boolean success = waitForResultTimedLocked(interactionId);
+ Point result = success ? mComputeClickPointResult : null;
+ clearResultLocked();
+ return result;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setComputeClickPointInScreenActionResult(Point point, int interactionId) {
+ synchronized (mInstanceLock) {
+ if (interactionId > mInteractionId) {
+ mComputeClickPointResult = point;
+ mInteractionId = interactionId;
+ }
+ mInstanceLock.notifyAll();
+ }
+ }
+
+ /**
* Clears the result state.
*/
private void clearResultLocked() {
@@ -641,6 +709,7 @@ public final class AccessibilityInteractionClient
mFindAccessibilityNodeInfoResult = null;
mFindAccessibilityNodeInfosResult = null;
mPerformAccessibilityActionResult = false;
+ mComputeClickPointResult = null;
}
/**
diff --git a/core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl b/core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl
index faf7789..66a3f46 100644
--- a/core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl
+++ b/core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl
@@ -17,6 +17,7 @@
package android.view.accessibility;
import android.graphics.Region;
+import android.graphics.Point;
import android.os.Bundle;
import android.view.MagnificationSpec;
import android.view.accessibility.AccessibilityNodeInfo;
@@ -53,4 +54,8 @@ oneway interface IAccessibilityInteractionConnection {
void performAccessibilityAction(long accessibilityNodeId, int action, in Bundle arguments,
int interactionId, IAccessibilityInteractionConnectionCallback callback, int flags,
int interrogatingPid, long interrogatingTid);
+
+ void computeClickPointInScreen(long accessibilityNodeId, in Region bounds, int interactionId,
+ IAccessibilityInteractionConnectionCallback callback, int interrogatingPid,
+ long interrogatingTid, in MagnificationSpec spec);
}
diff --git a/core/java/android/view/accessibility/IAccessibilityInteractionConnectionCallback.aidl b/core/java/android/view/accessibility/IAccessibilityInteractionConnectionCallback.aidl
index c1a3ab7..f480216 100644
--- a/core/java/android/view/accessibility/IAccessibilityInteractionConnectionCallback.aidl
+++ b/core/java/android/view/accessibility/IAccessibilityInteractionConnectionCallback.aidl
@@ -16,6 +16,7 @@
package android.view.accessibility;
+import android.graphics.Point;
import android.view.accessibility.AccessibilityNodeInfo;
import java.util.List;
@@ -51,4 +52,12 @@ oneway interface IAccessibilityInteractionConnectionCallback {
* @param interactionId The interaction id to match the result with the request.
*/
void setPerformAccessibilityActionResult(boolean succeeded, int interactionId);
+
+ /**
+ * Sets the result of a request to compute a point for clicking in a view.
+ *
+ * @param point The point of null if no such point.
+ * @param interactionId The interaction id to match the result with the request.
+ */
+ void setComputeClickPointInScreenActionResult(in Point point, int interactionId);
}
diff --git a/core/java/android/view/inputmethod/InputMethodSubtype.java b/core/java/android/view/inputmethod/InputMethodSubtype.java
index e7ada27..1671faa 100644
--- a/core/java/android/view/inputmethod/InputMethodSubtype.java
+++ b/core/java/android/view/inputmethod/InputMethodSubtype.java
@@ -211,18 +211,6 @@ public final class InputMethodSubtype implements Parcelable {
}
/**
- * Constructor with no subtype ID specified, overridesImplicitlyEnabledSubtype not specified.
- * Arguments for this constructor have the same meanings as
- * {@link InputMethodSubtype#InputMethodSubtype(int, int, String, String, String, boolean,
- * boolean, int)} except "id" and "overridesImplicitlyEnabledSubtype".
- * @hide
- */
- public InputMethodSubtype(int nameId, int iconId, String locale, String mode, String extraValue,
- boolean isAuxiliary) {
- this(nameId, iconId, locale, mode, extraValue, isAuxiliary, false);
- }
-
- /**
* Constructor with no subtype ID specified.
* @deprecated use {@link InputMethodSubtypeBuilder} instead.
* Arguments for this constructor have the same meanings as
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index eef8554..94d52d5 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -3325,8 +3325,8 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
}
if (dispatchNestedPreScroll(0, -rawDeltaY, mScrollConsumed, mScrollOffset)) {
rawDeltaY += mScrollConsumed[1];
- scrollOffsetCorrection -= mScrollOffset[1];
- scrollConsumedCorrection -= mScrollConsumed[1];
+ scrollOffsetCorrection = -mScrollOffset[1];
+ scrollConsumedCorrection = mScrollConsumed[1];
if (vtev != null) {
vtev.offsetLocation(0, mScrollOffset[1]);
}
@@ -3437,7 +3437,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
}
}
}
- mMotionY = y + scrollOffsetCorrection;
+ mMotionY = y + lastYCorrection + scrollOffsetCorrection;
}
mLastY = y + lastYCorrection + scrollOffsetCorrection;
}
@@ -3505,10 +3505,10 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
mMotionCorrection = 0;
View motionView = getChildAt(motionPosition - mFirstPosition);
mMotionViewOriginalTop = motionView != null ? motionView.getTop() : 0;
- mMotionY = y;
+ mMotionY = y + scrollOffsetCorrection;
mMotionPosition = motionPosition;
}
- mLastY = y;
+ mLastY = y + lastYCorrection + scrollOffsetCorrection;
mDirection = newDirection;
}
}
@@ -3876,7 +3876,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
if (mPositionScroller != null) {
mPositionScroller.stop();
}
- if (flingVelocity) {
+ if (flingVelocity && !dispatchNestedPreFling(0, -initialVelocity)) {
dispatchNestedFling(0, -initialVelocity, false);
}
}
@@ -4001,14 +4001,15 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
* <p>Applications can use this method to manually initiate a fling as if the user
* initiated it via touch interaction.</p>
*
- * @param velocityY Vertical velocity in pixels per second
+ * @param velocityY Vertical velocity in pixels per second. Note that this is velocity of
+ * content, not velocity of a touch that initiated the fling.
*/
public void fling(int velocityY) {
if (mFlingRunnable == null) {
mFlingRunnable = new FlingRunnable();
}
reportScrollStateChange(OnScrollListener.SCROLL_STATE_FLING);
- mFlingRunnable.start(-velocityY);
+ mFlingRunnable.start(velocityY);
}
@Override
diff --git a/core/java/android/widget/ActionMenuView.java b/core/java/android/widget/ActionMenuView.java
index 6ca4a9e..7198e52 100644
--- a/core/java/android/widget/ActionMenuView.java
+++ b/core/java/android/widget/ActionMenuView.java
@@ -611,6 +611,7 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo
mMenu = new MenuBuilder(context);
mMenu.setCallback(new MenuBuilderCallback());
mPresenter = new ActionMenuPresenter(context);
+ mPresenter.setReserveOverflow(true);
mPresenter.setCallback(mActionMenuPresenterCallback != null
? mActionMenuPresenterCallback : new ActionMenuPresenterCallback());
mMenu.addMenuPresenter(mPresenter, mPopupContext);
diff --git a/core/java/android/widget/GridView.java b/core/java/android/widget/GridView.java
index d263625..efd6fc0 100644
--- a/core/java/android/widget/GridView.java
+++ b/core/java/android/widget/GridView.java
@@ -2356,7 +2356,7 @@ public class GridView extends AbsListView {
final int rowsCount = getCount() / columnsCount;
final int selectionMode = getSelectionModeForAccessibility();
final CollectionInfo collectionInfo = CollectionInfo.obtain(
- columnsCount, rowsCount, false, selectionMode);
+ rowsCount, columnsCount, false, selectionMode);
info.setCollectionInfo(collectionInfo);
}
@@ -2385,7 +2385,7 @@ public class GridView extends AbsListView {
final boolean isHeading = lp != null && lp.viewType != ITEM_VIEW_TYPE_HEADER_OR_FOOTER;
final boolean isSelected = isItemChecked(position);
final CollectionItemInfo itemInfo = CollectionItemInfo.obtain(
- column, 1, row, 1, isHeading, isSelected);
+ row, 1, column, 1, isHeading, isSelected);
info.setCollectionItemInfo(itemInfo);
}
}
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index 1368cd3..2e9858c 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -3882,9 +3882,10 @@ public class ListView extends AbsListView {
super.onInitializeAccessibilityNodeInfo(info);
info.setClassName(ListView.class.getName());
- final int count = getCount();
+ final int rowsCount = getCount();
final int selectionMode = getSelectionModeForAccessibility();
- final CollectionInfo collectionInfo = CollectionInfo.obtain(1, count, false, selectionMode);
+ final CollectionInfo collectionInfo = CollectionInfo.obtain(
+ rowsCount, 1, false, selectionMode);
info.setCollectionInfo(collectionInfo);
}
@@ -3897,7 +3898,7 @@ public class ListView extends AbsListView {
final boolean isHeading = lp != null && lp.viewType != ITEM_VIEW_TYPE_HEADER_OR_FOOTER;
final boolean isSelected = isItemChecked(position);
final CollectionItemInfo itemInfo = CollectionItemInfo.obtain(
- 0, 1, position, 1, isHeading, isSelected);
+ position, 1, 0, 1, isHeading, isSelected);
info.setCollectionItemInfo(itemInfo);
}
}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 3e1b674..80ea6ea 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -8423,6 +8423,33 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
@Override
public boolean performAccessibilityAction(int action, Bundle arguments) {
switch (action) {
+ case AccessibilityNodeInfo.ACTION_CLICK: {
+ boolean handled = false;
+
+ // Simulate View.onTouchEvent for an ACTION_UP event.
+ if (isClickable() || isLongClickable()) {
+ if (isFocusable() && !isFocused()) {
+ requestFocus();
+ }
+
+ performClick();
+ handled = true;
+ }
+
+ // Simulate TextView.onTouchEvent for an ACTION_UP event.
+ if ((mMovement != null || onCheckIsTextEditor()) && isEnabled()
+ && mText instanceof Spannable && mLayout != null
+ && (isTextEditable() || isTextSelectable()) && isFocused()) {
+ // Show the IME, except when selecting in read-only text.
+ final InputMethodManager imm = InputMethodManager.peekInstance();
+ viewClicked(imm);
+ if (!isTextSelectable() && mEditor.mShowSoftInputOnFocus && imm != null) {
+ handled |= imm.showSoftInput(this, 0);
+ }
+ }
+
+ return handled;
+ }
case AccessibilityNodeInfo.ACTION_COPY: {
if (isFocused() && canCopy()) {
if (onTextContextMenuItem(ID_COPY)) {
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index b6e7353..107e8c6 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -90,7 +90,7 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
private boolean mSafeForwardingMode;
private boolean mAlwaysUseOption;
private boolean mShowExtended;
- private GridView mGridView;
+ private ListView mListView;
private Button mAlwaysButton;
private Button mOnceButton;
private int mIconDpi;
@@ -228,10 +228,13 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
mLaunchedFromUid, alwaysUseOption);
final int layoutId;
+ final boolean useHeader;
if (mAdapter.hasFilteredItem()) {
layoutId = R.layout.resolver_list_with_default;
alwaysUseOption = false;
+ useHeader = true;
} else {
+ useHeader = false;
layoutId = R.layout.resolver_list;
}
mAlwaysUseOption = alwaysUseOption;
@@ -243,16 +246,19 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
return;
} else if (count > 1) {
setContentView(layoutId);
- mGridView = (GridView) findViewById(R.id.resolver_list);
- mGridView.setAdapter(mAdapter);
- mGridView.setOnItemClickListener(this);
- mGridView.setOnItemLongClickListener(new ItemLongClickListener());
+ mListView = (ListView) findViewById(R.id.resolver_list);
+ mListView.setAdapter(mAdapter);
+ mListView.setOnItemClickListener(this);
+ mListView.setOnItemLongClickListener(new ItemLongClickListener());
if (alwaysUseOption) {
- mGridView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
+ mListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
}
- resizeGrid();
+ if (useHeader) {
+ mListView.addHeaderView(LayoutInflater.from(this).inflate(
+ R.layout.resolver_different_item_header, mListView, false));
+ }
} else if (count == 1) {
safelyStartActivity(mAdapter.intentForPosition(0, false));
mPackageMonitor.unregister();
@@ -265,8 +271,8 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
final TextView empty = (TextView) findViewById(R.id.empty);
empty.setVisibility(View.VISIBLE);
- mGridView = (GridView) findViewById(R.id.resolver_list);
- mGridView.setVisibility(View.GONE);
+ mListView = (ListView) findViewById(R.id.resolver_list);
+ mListView.setVisibility(View.GONE);
}
final ResolverDrawerLayout rdl = (ResolverDrawerLayout) findViewById(R.id.contentPanel);
@@ -340,11 +346,6 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
}
}
- void resizeGrid() {
- final int itemCount = mAdapter.getCount();
- mGridView.setNumColumns(Math.min(itemCount, mMaxColumns));
- }
-
void dismiss() {
if (!isFinishing()) {
finish();
@@ -419,19 +420,24 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
if (mAlwaysUseOption) {
- final int checkedPos = mGridView.getCheckedItemPosition();
+ final int checkedPos = mListView.getCheckedItemPosition();
final boolean hasValidSelection = checkedPos != ListView.INVALID_POSITION;
mLastSelected = checkedPos;
setAlwaysButtonEnabled(hasValidSelection, checkedPos, true);
mOnceButton.setEnabled(hasValidSelection);
if (hasValidSelection) {
- mGridView.setSelection(checkedPos);
+ mListView.setSelection(checkedPos);
}
}
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+ position -= mListView.getHeaderViewsCount();
+ if (position < 0) {
+ // Header views don't count.
+ return;
+ }
ResolveInfo resolveInfo = mAdapter.resolveInfoForPosition(position, true);
if (mResolvingHome && hasManagedProfile()
&& !supportsManagedProfiles(resolveInfo)) {
@@ -441,13 +447,13 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
Toast.LENGTH_LONG).show();
return;
}
- final int checkedPos = mGridView.getCheckedItemPosition();
+ final int checkedPos = mListView.getCheckedItemPosition();
final boolean hasValidSelection = checkedPos != ListView.INVALID_POSITION;
if (mAlwaysUseOption && (!hasValidSelection || mLastSelected != checkedPos)) {
setAlwaysButtonEnabled(hasValidSelection, checkedPos, true);
mOnceButton.setEnabled(hasValidSelection);
if (hasValidSelection) {
- mGridView.smoothScrollToPosition(checkedPos);
+ mListView.smoothScrollToPosition(checkedPos);
}
mLastSelected = checkedPos;
} else {
@@ -504,7 +510,7 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
public void onButtonClick(View v) {
final int id = v.getId();
startSelected(mAlwaysUseOption ?
- mGridView.getCheckedItemPosition() : mAdapter.getFilteredPosition(),
+ mListView.getCheckedItemPosition() : mAdapter.getFilteredPosition(),
id == R.id.button_always,
mAlwaysUseOption);
dismiss();
@@ -714,8 +720,6 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
if (newItemCount == 0) {
// We no longer have any items... just finish the activity.
finish();
- } else if (newItemCount != oldItemCount) {
- resizeGrid();
}
}
@@ -957,19 +961,13 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
}
public View getView(int position, View convertView, ViewGroup parent) {
- View view;
- if (convertView == null) {
+ View view = convertView;
+ if (view == null) {
view = mInflater.inflate(
com.android.internal.R.layout.resolve_list_item, parent, false);
final ViewHolder holder = new ViewHolder(view);
view.setTag(holder);
-
- // Fix the icon size even if we have different sized resources
- ViewGroup.LayoutParams lp = holder.icon.getLayoutParams();
- lp.width = lp.height = mIconSize;
- } else {
- view = convertView;
}
bindView(view, getItem(position));
return view;
@@ -1007,6 +1005,11 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
+ position -= mListView.getHeaderViewsCount();
+ if (position < 0) {
+ // Header views don't count.
+ return false;
+ }
ResolveInfo ri = mAdapter.resolveInfoForPosition(position, true);
showAppDetails(ri);
return true;
diff --git a/core/java/com/android/internal/content/PackageHelper.java b/core/java/com/android/internal/content/PackageHelper.java
index c17f4ee..7bdb4be 100644
--- a/core/java/com/android/internal/content/PackageHelper.java
+++ b/core/java/com/android/internal/content/PackageHelper.java
@@ -390,7 +390,10 @@ public class PackageHelper {
if (!emulated && (checkBoth || prefer == RECOMMEND_INSTALL_EXTERNAL)) {
final File target = new UserEnvironment(UserHandle.USER_OWNER)
.getExternalStorageDirectory();
- fitsOnExternal = (sizeBytes <= storage.getStorageBytesUntilLow(target));
+ // External is only an option when size is known
+ if (sizeBytes > 0) {
+ fitsOnExternal = (sizeBytes <= storage.getStorageBytesUntilLow(target));
+ }
}
if (prefer == RECOMMEND_INSTALL_INTERNAL) {
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index c5211bb..c579a15 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -78,17 +78,20 @@ public final class Zygote {
* file descriptor numbers that are to be closed by the child
* (and replaced by /dev/null) after forking. An integer value
* of -1 in any entry in the array means "ignore this one".
+ * @param instructionSet null-ok the instruction set to use.
*
* @return 0 if this is the child, pid of the child
* if this is the parent, or -1 on error.
*/
public static int forkAndSpecialize(int uid, int gid, int[] gids, int debugFlags,
- int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose) {
+ int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
+ String instructionSet) {
long startTime = SystemClock.elapsedRealtime();
VM_HOOKS.preFork();
checkTime(startTime, "Zygote.preFork");
int pid = nativeForkAndSpecialize(
- uid, gid, gids, debugFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose);
+ uid, gid, gids, debugFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
+ instructionSet);
checkTime(startTime, "Zygote.nativeForkAndSpecialize");
VM_HOOKS.postForkCommon();
checkTime(startTime, "Zygote.postForkCommon");
@@ -96,7 +99,8 @@ public final class Zygote {
}
native private static int nativeForkAndSpecialize(int uid, int gid, int[] gids,int debugFlags,
- int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose);
+ int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
+ String instructionSet);
/**
* Temporary hack: check time since start time and log if over a fixed threshold.
@@ -145,9 +149,9 @@ public final class Zygote {
native private static int nativeForkSystemServer(int uid, int gid, int[] gids, int debugFlags,
int[][] rlimits, long permittedCapabilities, long effectiveCapabilities);
- private static void callPostForkChildHooks(int debugFlags) {
+ private static void callPostForkChildHooks(int debugFlags, String instructionSet) {
long startTime = SystemClock.elapsedRealtime();
- VM_HOOKS.postForkChild(debugFlags);
+ VM_HOOKS.postForkChild(debugFlags, instructionSet);
checkTime(startTime, "Zygote.callPostForkChildHooks");
}
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index b4c4da6..fb50b25 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -245,7 +245,7 @@ class ZygoteConnection {
checkTime(startTime, "zygoteConnection.runOnce: preForkAndSpecialize");
pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
- parsedArgs.niceName, fdsToClose);
+ parsedArgs.niceName, fdsToClose, parsedArgs.instructionSet);
checkTime(startTime, "zygoteConnection.runOnce: postForkAndSpecialize");
} catch (IOException ex) {
logAndPrintError(newStderr, "Exception creating pipe", ex);
@@ -335,6 +335,7 @@ class ZygoteConnection {
* [--] &lt;args for RuntimeInit &gt;
* <li> If <code>--runtime-init</code> is absent:
* [--] &lt;classname&gt; [args...]
+ * <li> --instruction-set=<i>instruction-set-string</i> which instruction set to use/emulate.
* </ul>
*/
static class Arguments {
@@ -398,6 +399,11 @@ class ZygoteConnection {
boolean abiListQuery;
/**
+ * The instruction set to use, or null when not important.
+ */
+ String instructionSet;
+
+ /**
* Constructs instance and parses args
* @param args zygote command-line args
* @throws IllegalArgumentException
@@ -552,6 +558,8 @@ class ZygoteConnection {
mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
} else if (arg.equals("--query-abi-list")) {
abiListQuery = true;
+ } else if (arg.startsWith("--instruction-set=")) {
+ instructionSet = arg.substring(arg.indexOf('=') + 1);
} else {
break;
}
diff --git a/core/java/com/android/internal/util/ParcelableString.java b/core/java/com/android/internal/util/ParcelableString.java
new file mode 100644
index 0000000..6bd856f
--- /dev/null
+++ b/core/java/com/android/internal/util/ParcelableString.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2014, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.util;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Helper class to adapt a simple String to cases where a Parcelable is expected.
+ * @hide
+ */
+public class ParcelableString implements Parcelable {
+ public String string;
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(string);
+ }
+
+ public static final Parcelable.Creator<ParcelableString> CREATOR =
+ new Parcelable.Creator<ParcelableString>() {
+ @Override
+ public ParcelableString createFromParcel(Parcel in) {
+ ParcelableString ret = new ParcelableString();
+ ret.string = in.readString();
+ return ret;
+ }
+ @Override
+ public ParcelableString[] newArray(int size) {
+ return new ParcelableString[size];
+ }
+ };
+} \ No newline at end of file
diff --git a/core/java/com/android/internal/util/XmlUtils.java b/core/java/com/android/internal/util/XmlUtils.java
index 7db70ba..45d790b 100644
--- a/core/java/com/android/internal/util/XmlUtils.java
+++ b/core/java/com/android/internal/util/XmlUtils.java
@@ -1440,6 +1440,16 @@ public class XmlUtils {
return Boolean.parseBoolean(value);
}
+ public static boolean readBooleanAttribute(XmlPullParser in, String name,
+ boolean defaultValue) {
+ final String value = in.getAttributeValue(null, name);
+ if (value == null) {
+ return defaultValue;
+ } else {
+ return Boolean.parseBoolean(value);
+ }
+ }
+
public static void writeBooleanAttribute(XmlSerializer out, String name, boolean value)
throws IOException {
out.attribute(null, name, Boolean.toString(value));
diff --git a/core/java/com/android/internal/widget/ResolverDrawerLayout.java b/core/java/com/android/internal/widget/ResolverDrawerLayout.java
index e53f9dd..375822f 100644
--- a/core/java/com/android/internal/widget/ResolverDrawerLayout.java
+++ b/core/java/com/android/internal/widget/ResolverDrawerLayout.java
@@ -20,15 +20,15 @@ package com.android.internal.widget;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Rect;
+import android.os.Parcel;
+import android.os.Parcelable;
import android.util.AttributeSet;
import android.util.Log;
-import android.view.Gravity;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
-
import android.view.ViewParent;
import android.view.ViewTreeObserver;
import android.view.animation.AnimationUtils;
@@ -68,6 +68,7 @@ public class ResolverDrawerLayout extends ViewGroup {
private boolean mIsDragging;
private boolean mOpenOnClick;
+ private boolean mOpenOnLayout;
private final int mTouchSlop;
private final float mMinFlingVelocity;
private final OverScroller mScroller;
@@ -202,6 +203,8 @@ public class ResolverDrawerLayout extends ViewGroup {
public boolean onTouchEvent(MotionEvent ev) {
final int action = ev.getActionMasked();
+ mVelocityTracker.addMovement(ev);
+
boolean handled = false;
switch (action) {
case MotionEvent.ACTION_DOWN: {
@@ -288,6 +291,10 @@ public class ResolverDrawerLayout extends ViewGroup {
break;
case MotionEvent.ACTION_CANCEL: {
+ if (mIsDragging) {
+ smoothScrollTo(
+ mCollapseOffset < mCollapsibleHeight / 2 ? 0 : mCollapsibleHeight, 0);
+ }
resetTouch();
return true;
}
@@ -498,28 +505,39 @@ public class ResolverDrawerLayout extends ViewGroup {
@Override
public void onStopNestedScroll(View child) {
super.onStopNestedScroll(child);
- smoothScrollTo(mCollapseOffset < mCollapsibleHeight / 2 ? 0 : mCollapsibleHeight, 0);
+ if (mScroller.isFinished()) {
+ smoothScrollTo(mCollapseOffset < mCollapsibleHeight / 2 ? 0 : mCollapsibleHeight, 0);
+ }
}
@Override
public void onNestedScroll(View target, int dxConsumed, int dyConsumed,
int dxUnconsumed, int dyUnconsumed) {
- if (dyUnconsumed > 0) {
+ if (dyUnconsumed < 0) {
performDrag(-dyUnconsumed);
}
}
@Override
public void onNestedPreScroll(View target, int dx, int dy, int[] consumed) {
- if (dy < 0) {
- consumed[1] = (int) performDrag(-dy);
+ if (dy > 0) {
+ consumed[1] = (int) -performDrag(-dy);
}
}
@Override
+ public boolean onNestedPreFling(View target, float velocityX, float velocityY) {
+ if (velocityY > mMinFlingVelocity && mCollapseOffset != 0) {
+ smoothScrollTo(0, velocityY);
+ return true;
+ }
+ return false;
+ }
+
+ @Override
public boolean onNestedFling(View target, float velocityX, float velocityY, boolean consumed) {
if (!consumed && Math.abs(velocityY) > mMinFlingVelocity) {
- smoothScrollTo(velocityY < 0 ? 0 : mCollapsibleHeight, velocityY);
+ smoothScrollTo(velocityY > 0 ? 0 : mCollapsibleHeight, velocityY);
return true;
}
return false;
@@ -571,8 +589,8 @@ public class ResolverDrawerLayout extends ViewGroup {
if (isLaidOut()) {
mCollapseOffset = Math.min(mCollapseOffset, mCollapsibleHeight);
} else {
- // Start out collapsed at first
- mCollapseOffset = mCollapsibleHeight;
+ // Start out collapsed at first unless we restored state for otherwise
+ mCollapseOffset = mOpenOnLayout ? 0 : mCollapsibleHeight;
}
mTopOffset = Math.max(0, heightSize - heightUsed) + (int) mCollapseOffset;
@@ -634,6 +652,20 @@ public class ResolverDrawerLayout extends ViewGroup {
return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
}
+ @Override
+ protected Parcelable onSaveInstanceState() {
+ final SavedState ss = new SavedState(super.onSaveInstanceState());
+ ss.open = mCollapsibleHeight > 0 && mCollapseOffset == 0;
+ return ss;
+ }
+
+ @Override
+ protected void onRestoreInstanceState(Parcelable state) {
+ final SavedState ss = (SavedState) state;
+ super.onRestoreInstanceState(ss.getSuperState());
+ mOpenOnLayout = ss.open;
+ }
+
public static class LayoutParams extends MarginLayoutParams {
public boolean alwaysShow;
public boolean ignoreOffset;
@@ -670,4 +702,36 @@ public class ResolverDrawerLayout extends ViewGroup {
super(source);
}
}
+
+ static class SavedState extends BaseSavedState {
+ boolean open;
+
+ SavedState(Parcelable superState) {
+ super(superState);
+ }
+
+ private SavedState(Parcel in) {
+ super(in);
+ open = in.readInt() != 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ super.writeToParcel(out, flags);
+ out.writeInt(open ? 1 : 0);
+ }
+
+ public static final Parcelable.Creator<SavedState> CREATOR =
+ new Parcelable.Creator<SavedState>() {
+ @Override
+ public SavedState createFromParcel(Parcel in) {
+ return new SavedState(in);
+ }
+
+ @Override
+ public SavedState[] newArray(int size) {
+ return new SavedState[size];
+ }
+ };
+ }
}
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index 2106d38..dbaa4b8 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -129,6 +129,7 @@ LOCAL_SRC_FILES:= \
android/graphics/Xfermode.cpp \
android/graphics/YuvToJpegEncoder.cpp \
android/graphics/pdf/PdfDocument.cpp \
+ android/graphics/pdf/PdfEditor.cpp \
android/graphics/pdf/PdfRenderer.cpp \
android_media_AudioRecord.cpp \
android_media_AudioSystem.cpp \
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 62d8036..a63258c 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -126,6 +126,7 @@ extern int register_android_graphics_Region(JNIEnv* env);
extern int register_android_graphics_SurfaceTexture(JNIEnv* env);
extern int register_android_graphics_Xfermode(JNIEnv* env);
extern int register_android_graphics_pdf_PdfDocument(JNIEnv* env);
+extern int register_android_graphics_pdf_PdfEditor(JNIEnv* env);
extern int register_android_graphics_pdf_PdfRenderer(JNIEnv* env);
extern int register_android_view_DisplayEventReceiver(JNIEnv* env);
extern int register_android_view_RenderNode(JNIEnv* env);
@@ -1305,6 +1306,7 @@ static const RegJNIRec gRegJNI[] = {
REG_JNI(register_android_graphics_Xfermode),
REG_JNI(register_android_graphics_YuvImage),
REG_JNI(register_android_graphics_pdf_PdfDocument),
+ REG_JNI(register_android_graphics_pdf_PdfEditor),
REG_JNI(register_android_graphics_pdf_PdfRenderer),
REG_JNI(register_android_database_CursorWindow),
diff --git a/core/jni/android/graphics/pdf/PdfEditor.cpp b/core/jni/android/graphics/pdf/PdfEditor.cpp
new file mode 100644
index 0000000..5f60c9e
--- /dev/null
+++ b/core/jni/android/graphics/pdf/PdfEditor.cpp
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "jni.h"
+#include "JNIHelp.h"
+#include "fpdfview.h"
+#include "fpdfedit.h"
+#include "fpdfsave.h"
+
+#include <android_runtime/AndroidRuntime.h>
+#include <vector>
+#include <utils/Log.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+namespace android {
+
+static Mutex sLock;
+
+static int sUnmatchedInitRequestCount = 0;
+
+static void initializeLibraryIfNeeded() {
+ Mutex::Autolock _l(sLock);
+ if (sUnmatchedInitRequestCount == 0) {
+ FPDF_InitLibrary(NULL);
+ }
+ sUnmatchedInitRequestCount++;
+}
+
+static void destroyLibraryIfNeeded() {
+ Mutex::Autolock _l(sLock);
+ sUnmatchedInitRequestCount--;
+ if (sUnmatchedInitRequestCount == 0) {
+ FPDF_DestroyLibrary();
+ }
+}
+
+static int getBlock(void* param, unsigned long position, unsigned char* outBuffer,
+ unsigned long size) {
+ const int fd = reinterpret_cast<intptr_t>(param);
+ const int readCount = pread(fd, outBuffer, size, position);
+ if (readCount < 0) {
+ ALOGE("Cannot read from file descriptor. Error:%d", errno);
+ return 0;
+ }
+ return 1;
+}
+
+static jlong nativeOpen(JNIEnv* env, jclass thiz, jint fd, jlong size) {
+ initializeLibraryIfNeeded();
+
+ FPDF_FILEACCESS loader;
+ loader.m_FileLen = size;
+ loader.m_Param = reinterpret_cast<void*>(intptr_t(fd));
+ loader.m_GetBlock = &getBlock;
+
+ FPDF_DOCUMENT document = FPDF_LoadCustomDocument(&loader, NULL);
+
+ if (!document) {
+ const long error = FPDF_GetLastError();
+ jniThrowException(env, "java/io/IOException",
+ "cannot create document. Error:" + error);
+ destroyLibraryIfNeeded();
+ return -1;
+ }
+
+ return reinterpret_cast<jlong>(document);
+}
+
+static void nativeClose(JNIEnv* env, jclass thiz, jlong documentPtr) {
+ FPDF_DOCUMENT document = reinterpret_cast<FPDF_DOCUMENT>(documentPtr);
+ FPDF_CloseDocument(document);
+ destroyLibraryIfNeeded();
+}
+
+static jint nativeGetPageCount(JNIEnv* env, jclass thiz, jlong documentPtr) {
+ FPDF_DOCUMENT document = reinterpret_cast<FPDF_DOCUMENT>(documentPtr);
+ return FPDF_GetPageCount(document);
+}
+
+static jint nativeRemovePage(JNIEnv* env, jclass thiz, jlong documentPtr, jint pageIndex) {
+ FPDF_DOCUMENT document = reinterpret_cast<FPDF_DOCUMENT>(documentPtr);
+ FPDFPage_Delete(document, pageIndex);
+ return FPDF_GetPageCount(document);
+}
+
+struct PdfToFdWriter : FPDF_FILEWRITE {
+ int dstFd;
+};
+
+static bool writeAllBytes(const int fd, const void* buffer, const size_t byteCount) {
+ char* writeBuffer = static_cast<char*>(const_cast<void*>(buffer));
+ size_t remainingBytes = byteCount;
+ while (remainingBytes > 0) {
+ ssize_t writtenByteCount = write(fd, writeBuffer, remainingBytes);
+ if (writtenByteCount == -1) {
+ if (errno == EINTR) {
+ continue;
+ }
+ __android_log_print(ANDROID_LOG_ERROR, LOG_TAG,
+ "Error writing to buffer: %d", errno);
+ return false;
+ }
+ remainingBytes -= writtenByteCount;
+ writeBuffer += writtenByteCount;
+ }
+ return true;
+}
+
+static int writeBlock(FPDF_FILEWRITE* owner, const void* buffer, unsigned long size) {
+ const PdfToFdWriter* writer = reinterpret_cast<PdfToFdWriter*>(owner);
+ const bool success = writeAllBytes(writer->dstFd, buffer, size);
+ if (success < 0) {
+ ALOGE("Cannot write to file descriptor. Error:%d", errno);
+ return 0;
+ }
+ return 1;
+}
+
+static void nativeWrite(JNIEnv* env, jclass thiz, jlong documentPtr, jint fd) {
+ FPDF_DOCUMENT document = reinterpret_cast<FPDF_DOCUMENT>(documentPtr);
+ PdfToFdWriter writer;
+ writer.dstFd = fd;
+ writer.WriteBlock = &writeBlock;
+ const bool success = FPDF_SaveAsCopy(document, &writer, FPDF_NO_INCREMENTAL);
+ if (!success) {
+ jniThrowException(env, "java/io/IOException",
+ "cannot write to fd. Error:" + errno);
+ destroyLibraryIfNeeded();
+ }
+}
+
+static JNINativeMethod gPdfEditor_Methods[] = {
+ {"nativeOpen", "(IJ)J", (void*) nativeOpen},
+ {"nativeClose", "(J)V", (void*) nativeClose},
+ {"nativeGetPageCount", "(J)I", (void*) nativeGetPageCount},
+ {"nativeRemovePage", "(JI)I", (void*) nativeRemovePage},
+ {"nativeWrite", "(JI)V", (void*) nativeWrite}
+};
+
+int register_android_graphics_pdf_PdfEditor(JNIEnv* env) {
+ return android::AndroidRuntime::registerNativeMethods(
+ env, "android/graphics/pdf/PdfEditor", gPdfEditor_Methods,
+ NELEM(gPdfEditor_Methods));
+};
+
+};
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 8f30f5d..06c22ae 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -117,7 +117,8 @@ static void nativeDestroy(JNIEnv* env, jclass clazz, jlong nativeObject) {
static jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz,
jobject displayTokenObj, jobject sourceCropObj, jint width, jint height,
- jint minLayer, jint maxLayer, bool allLayers, bool useIdentityTransform) {
+ jint minLayer, jint maxLayer, bool allLayers, bool useIdentityTransform,
+ int rotation) {
sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj);
if (displayToken == NULL) {
return NULL;
@@ -131,17 +132,13 @@ static jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz,
SkAutoTDelete<ScreenshotClient> screenshot(new ScreenshotClient());
status_t res;
- if (width > 0 && height > 0) {
- if (allLayers) {
- res = screenshot->update(displayToken, sourceCrop, width, height,
- useIdentityTransform);
- } else {
- res = screenshot->update(displayToken, sourceCrop, width, height,
- minLayer, maxLayer, useIdentityTransform);
- }
- } else {
- res = screenshot->update(displayToken, sourceCrop, useIdentityTransform);
+ if (allLayers) {
+ minLayer = 0;
+ maxLayer = -1UL;
}
+
+ res = screenshot->update(displayToken, sourceCrop, width, height,
+ minLayer, maxLayer, useIdentityTransform, static_cast<uint32_t>(rotation));
if (res != NO_ERROR) {
return NULL;
}
@@ -588,7 +585,7 @@ static JNINativeMethod sSurfaceControlMethods[] = {
(void*)nativeRelease },
{"nativeDestroy", "(J)V",
(void*)nativeDestroy },
- {"nativeScreenshot", "(Landroid/os/IBinder;Landroid/graphics/Rect;IIIIZZ)Landroid/graphics/Bitmap;",
+ {"nativeScreenshot", "(Landroid/os/IBinder;Landroid/graphics/Rect;IIIIZZI)Landroid/graphics/Bitmap;",
(void*)nativeScreenshotBitmap },
{"nativeScreenshot", "(Landroid/os/IBinder;Landroid/view/Surface;Landroid/graphics/Rect;IIIIZZ)V",
(void*)nativeScreenshot },
diff --git a/core/jni/com_android_internal_net_NetworkStatsFactory.cpp b/core/jni/com_android_internal_net_NetworkStatsFactory.cpp
index c84a466..2e2d0c7 100644
--- a/core/jni/com_android_internal_net_NetworkStatsFactory.cpp
+++ b/core/jni/com_android_internal_net_NetworkStatsFactory.cpp
@@ -175,17 +175,23 @@ static int readNetworkStatsDetail(JNIEnv* env, jclass clazz, jobject stats,
continue;
}
}
- // Skip whitespace.
- while (*pos == ' ') {
- pos++;
- }
- // Next field is tag.
- rawTag = strtoll(pos, &endPos, 16);
- //ALOGI("Index #%d: %s", idx, buffer);
- if (pos == endPos) {
- ALOGE("bad tag: %s", pos);
- fclose(fp);
- return -1;
+
+ // Ignore whitespace
+ while (*pos == ' ') pos++;
+
+ // Find end of tag field
+ endPos = pos;
+ while (*endPos != ' ') endPos++;
+
+ // Three digit field is always 0x0, otherwise parse
+ if (endPos - pos == 3) {
+ rawTag = 0;
+ } else {
+ if (sscanf(pos, "%llx", &rawTag) != 1) {
+ ALOGE("bad tag: %s", pos);
+ fclose(fp);
+ return -1;
+ }
}
s.tag = rawTag >> 32;
if (limitTag != -1 && s.tag != limitTag) {
@@ -193,10 +199,10 @@ static int readNetworkStatsDetail(JNIEnv* env, jclass clazz, jobject stats,
continue;
}
pos = endPos;
- // Skip whitespace.
- while (*pos == ' ') {
- pos++;
- }
+
+ // Ignore whitespace
+ while (*pos == ' ') pos++;
+
// Parse remaining fields.
if (sscanf(pos, "%u %u %llu %llu %llu %llu",
&s.uid, &s.set, &s.rxBytes, &s.rxPackets,
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 3d2d471..451d97a 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -421,7 +421,8 @@ static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArra
jlong permittedCapabilities, jlong effectiveCapabilities,
jint mount_external,
jstring java_se_info, jstring java_se_name,
- bool is_system_server, jintArray fdsToClose) {
+ bool is_system_server, jintArray fdsToClose,
+ jstring instructionSet) {
uint64_t start = MsTime();
SetSigChldHandler();
ckTime(start, "ForkAndSpecializeCommon:SetSigChldHandler");
@@ -542,7 +543,8 @@ static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArra
ckTime(start, "ForkAndSpecializeCommon:child process setup");
- env->CallStaticVoidMethod(gZygoteClass, gCallPostForkChildHooks, debug_flags);
+ env->CallStaticVoidMethod(gZygoteClass, gCallPostForkChildHooks, debug_flags,
+ is_system_server ? NULL : instructionSet);
ckTime(start, "ForkAndSpecializeCommon:PostForkChildHooks returns");
if (env->ExceptionCheck()) {
ALOGE("Error calling post fork hooks.");
@@ -561,7 +563,7 @@ static jint com_android_internal_os_Zygote_nativeForkAndSpecialize(
JNIEnv* env, jclass, jint uid, jint gid, jintArray gids,
jint debug_flags, jobjectArray rlimits,
jint mount_external, jstring se_info, jstring se_name,
- jintArray fdsToClose) {
+ jintArray fdsToClose, jstring instructionSet) {
// Grant CAP_WAKE_ALARM to the Bluetooth process.
jlong capabilities = 0;
if (uid == AID_BLUETOOTH) {
@@ -570,7 +572,7 @@ static jint com_android_internal_os_Zygote_nativeForkAndSpecialize(
return ForkAndSpecializeCommon(env, uid, gid, gids, debug_flags,
rlimits, capabilities, capabilities, mount_external, se_info,
- se_name, false, fdsToClose);
+ se_name, false, fdsToClose, instructionSet);
}
static jint com_android_internal_os_Zygote_nativeForkSystemServer(
@@ -580,7 +582,7 @@ static jint com_android_internal_os_Zygote_nativeForkSystemServer(
pid_t pid = ForkAndSpecializeCommon(env, uid, gid, gids,
debug_flags, rlimits,
permittedCapabilities, effectiveCapabilities,
- MOUNT_EXTERNAL_NONE, NULL, NULL, true, NULL);
+ MOUNT_EXTERNAL_NONE, NULL, NULL, true, NULL, NULL);
if (pid > 0) {
// The zygote process checks whether the child process has died or not.
ALOGI("System server process %d has been created", pid);
@@ -598,7 +600,8 @@ static jint com_android_internal_os_Zygote_nativeForkSystemServer(
}
static JNINativeMethod gMethods[] = {
- { "nativeForkAndSpecialize", "(II[II[[IILjava/lang/String;Ljava/lang/String;[I)I",
+ { "nativeForkAndSpecialize",
+ "(II[II[[IILjava/lang/String;Ljava/lang/String;[ILjava/lang/String;)I",
(void *) com_android_internal_os_Zygote_nativeForkAndSpecialize },
{ "nativeForkSystemServer", "(II[II[[IJJ)I",
(void *) com_android_internal_os_Zygote_nativeForkSystemServer }
@@ -609,7 +612,8 @@ int register_com_android_internal_os_Zygote(JNIEnv* env) {
if (gZygoteClass == NULL) {
RuntimeAbort(env);
}
- gCallPostForkChildHooks = env->GetStaticMethodID(gZygoteClass, "callPostForkChildHooks", "(I)V");
+ gCallPostForkChildHooks = env->GetStaticMethodID(gZygoteClass, "callPostForkChildHooks",
+ "(ILjava/lang/String;)V");
return AndroidRuntime::registerNativeMethods(env, "com/android/internal/os/Zygote",
gMethods, NELEM(gMethods));
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 72dd930..bf2d09b 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2502,7 +2502,7 @@
<permission android:name="android.permission.PACKAGE_USAGE_STATS"
android:label="@string/permlab_pkgUsageStats"
android:description="@string/permdesc_pkgUsageStats"
- android:protectionLevel="signature|system|development|appop" />
+ android:protectionLevel="signature|development|appop" />
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
<!-- @SystemApi Allows an application to collect battery statistics -->
@@ -2773,7 +2773,7 @@
android:description="@string/permdesc_bindNotificationListenerService"
android:protectionLevel="signature" />
- <!-- Must be required by an {@link
+ <!-- @SystemApi Must be required by a {@link
android.service.notification.ConditionProviderService},
to ensure that only the system can bind to it.
@hide -->
diff --git a/core/res/res/drawable/emulator_circular_window_overlay.xml b/core/res/res/drawable/emulator_circular_window_overlay.xml
new file mode 100644
index 0000000..7616b37
--- /dev/null
+++ b/core/res/res/drawable/emulator_circular_window_overlay.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!-- Default to an empty shape drawable -->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle">
+</shape>
diff --git a/core/res/res/layout/alert_dialog_material.xml b/core/res/res/layout/alert_dialog_material.xml
index 5f9066a..be89e41 100644
--- a/core/res/res/layout/alert_dialog_material.xml
+++ b/core/res/res/layout/alert_dialog_material.xml
@@ -33,8 +33,7 @@
android:gravity="center_vertical|start"
android:paddingStart="@dimen/alert_dialog_padding_material"
android:paddingEnd="@dimen/alert_dialog_padding_material"
- android:paddingTop="@dimen/alert_dialog_padding_material"
- android:paddingBottom="8dip">
+ android:paddingTop="@dimen/alert_dialog_padding_top_material">
<ImageView android:id="@+id/icon"
android:layout_width="32dip"
android:layout_height="32dip"
@@ -57,7 +56,8 @@
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical"
- android:minHeight="64dp">
+ android:minHeight="64dp"
+ android:paddingTop="@dimen/alert_dialog_padding_top_material">
<ScrollView android:id="@+id/scrollView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -67,9 +67,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="@dimen/alert_dialog_padding_material"
- android:paddingEnd="@dimen/alert_dialog_padding_material"
- android:paddingTop="@dimen/alert_dialog_padding_material"
- android:paddingBottom="@dimen/alert_dialog_padding_material" />
+ android:paddingEnd="@dimen/alert_dialog_padding_material" />
</ScrollView>
</LinearLayout>
@@ -89,15 +87,14 @@
android:layout_height="wrap_content"
android:layoutDirection="locale"
android:orientation="horizontal"
- android:paddingStart="6dp"
- android:paddingEnd="6dp"
- android:paddingBottom="6dp">
+ android:paddingStart="12dp"
+ android:paddingEnd="12dp"
+ android:paddingTop="8dp"
+ android:paddingBottom="8dp">
<Button android:id="@+id/button3"
style="?attr/buttonBarNeutralButtonStyle"
android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:maxLines="2"
- android:minHeight="@dimen/alert_dialog_button_bar_height" />
+ android:layout_height="wrap_content" />
<Space
android:layout_width="0dp"
android:layout_height="0dp"
@@ -106,14 +103,10 @@
<Button android:id="@+id/button2"
style="?attr/buttonBarNegativeButtonStyle"
android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:maxLines="2"
- android:minHeight="@dimen/alert_dialog_button_bar_height" />
+ android:layout_height="wrap_content" />
<Button android:id="@+id/button1"
style="?attr/buttonBarPositiveButtonStyle"
android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:maxLines="2"
- android:minHeight="@dimen/alert_dialog_button_bar_height" />
+ android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
diff --git a/core/res/res/layout/alert_dialog_progress_material.xml b/core/res/res/layout/alert_dialog_progress_material.xml
index b9d0814..d005a44 100644
--- a/core/res/res/layout/alert_dialog_progress_material.xml
+++ b/core/res/res/layout/alert_dialog_progress_material.xml
@@ -17,32 +17,27 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
- android:layout_height="match_parent">
- <ProgressBar android:id="@+id/progress"
- style="?android:attr/progressBarStyleHorizontal"
+ android:layout_height="match_parent"
+ android:paddingStart="@dimen/alert_dialog_padding_material"
+ android:paddingTop="@dimen/alert_dialog_padding_top_material"
+ android:paddingEnd="@dimen/alert_dialog_padding_material"
+ android:paddingBottom="@dimen/alert_dialog_padding_top_material">
+ <ProgressBar
+ android:id="@+id/progress"
+ style="?attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginTop="16dip"
- android:layout_marginBottom="1dip"
- android:layout_marginStart="16dip"
- android:layout_marginEnd="16dip"
android:layout_centerHorizontal="true" />
<TextView
android:id="@+id/progress_percent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:paddingBottom="16dip"
- android:layout_marginStart="16dip"
- android:layout_marginEnd="16dip"
android:layout_alignParentStart="true"
android:layout_below="@id/progress" />
<TextView
android:id="@+id/progress_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:paddingBottom="16dip"
- android:layout_marginStart="16dip"
- android:layout_marginEnd="16dip"
android:layout_alignParentEnd="true"
android:layout_below="@id/progress" />
</RelativeLayout>
diff --git a/core/res/res/layout/dialog_custom_title_material.xml b/core/res/res/layout/dialog_custom_title_material.xml
index 550b72e..248a05e 100644
--- a/core/res/res/layout/dialog_custom_title_material.xml
+++ b/core/res/res/layout/dialog_custom_title_material.xml
@@ -23,17 +23,17 @@ This is a custom layout for a dialog.
android:fitsSystemWindows="true">
<FrameLayout android:id="@android:id/title_container"
android:layout_width="match_parent"
- android:layout_height="?android:attr/windowTitleSize"
+ android:layout_height="?attr/windowTitleSize"
android:layout_weight="0"
android:gravity="center_vertical|start"
- style="?android:attr/windowTitleBackgroundStyle" />
+ style="?attr/windowTitleBackgroundStyle" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical"
- android:foreground="?android:attr/windowContentOverlay">
- <FrameLayout android:id="@android:id/content"
+ android:foreground="?attr/windowContentOverlay">
+ <FrameLayout android:id="@id/content"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
diff --git a/core/res/res/layout/dialog_title_icons_material.xml b/core/res/res/layout/dialog_title_icons_material.xml
index 28e20d9..21396da 100644
--- a/core/res/res/layout/dialog_title_icons_material.xml
+++ b/core/res/res/layout/dialog_title_icons_material.xml
@@ -28,16 +28,16 @@ enabled.
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical"
- android:paddingStart="16dip"
- android:paddingEnd="16dip"
- android:paddingTop="16dip">
+ android:paddingStart="@dimen/alert_dialog_padding_material"
+ android:paddingEnd="@dimen/alert_dialog_padding_material"
+ android:paddingTop="@dimen/alert_dialog_padding_material">
<ImageView android:id="@+id/left_icon"
android:layout_width="32dip"
android:layout_height="32dip"
android:scaleType="fitCenter"
android:layout_marginEnd="8dip" />
- <TextView android:id="@android:id/title"
- style="?android:attr/windowTitleStyle"
+ <TextView android:id="@id/title"
+ style="?attr/windowTitleStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0" />
@@ -52,8 +52,8 @@ enabled.
android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical"
- android:foreground="?android:attr/windowContentOverlay">
- <FrameLayout android:id="@android:id/content"
+ android:foreground="?attr/windowContentOverlay">
+ <FrameLayout android:id="@id/content"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
diff --git a/core/res/res/layout/dialog_title_material.xml b/core/res/res/layout/dialog_title_material.xml
index 918c8f1..fcf6164 100644
--- a/core/res/res/layout/dialog_title_material.xml
+++ b/core/res/res/layout/dialog_title_material.xml
@@ -29,15 +29,15 @@ enabled.
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAlignment="viewStart"
- android:paddingStart="16dip"
- android:paddingEnd="16dip"
- android:paddingTop="16dip" />
+ android:paddingStart="@dimen/alert_dialog_padding_material"
+ android:paddingEnd="@dimen/alert_dialog_padding_material"
+ android:paddingTop="@dimen/alert_dialog_padding_top_material" />
<FrameLayout
android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical"
- android:foreground="?android:attr/windowContentOverlay">
- <FrameLayout android:id="@android:id/content"
+ android:foreground="?attr/windowContentOverlay">
+ <FrameLayout android:id="@id/content"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
diff --git a/core/res/res/layout/notification_template_material_inbox.xml b/core/res/res/layout/notification_template_material_inbox.xml
index 2382d18..8a66c3f 100644
--- a/core/res/res/layout/notification_template_material_inbox.xml
+++ b/core/res/res/layout/notification_template_material_inbox.xml
@@ -44,6 +44,7 @@
android:layout_width="match_parent"
android:layout_weight="1"
android:layout_height="0dp"
+ android:layout_marginEnd="8dp"
android:orientation="horizontal"
>
<TextView android:id="@+id/inbox_text0"
@@ -60,7 +61,6 @@
android:layout_height="@dimen/notification_badge_size"
android:layout_weight="0"
android:layout_marginStart="4dp"
- android:layout_marginEnd="8dp"
android:scaleType="fitCenter"
android:visibility="gone"
/>
diff --git a/core/res/res/layout/notification_template_part_line2.xml b/core/res/res/layout/notification_template_part_line2.xml
index 7e99c5e..aeef3ab 100644
--- a/core/res/res/layout/notification_template_part_line2.xml
+++ b/core/res/res/layout/notification_template_part_line2.xml
@@ -45,13 +45,13 @@
android:visibility="gone"
/>
</LinearLayout>
- <ProgressBar
+ <ViewStub
android:id="@android:id/progress"
+ android:layout="@layout/notification_template_progressbar"
android:layout_width="match_parent"
android:layout_height="15dp"
android:layout_marginEnd="8dp"
android:visibility="gone"
android:layout_weight="0"
- style="@style/Widget.Material.Light.ProgressBar.Horizontal"
/>
</merge>
diff --git a/core/res/res/layout/notification_template_progressbar.xml b/core/res/res/layout/notification_template_progressbar.xml
new file mode 100644
index 0000000..61480b8
--- /dev/null
+++ b/core/res/res/layout/notification_template_progressbar.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2014 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+
+<ProgressBar xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@android:id/progress"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ style="@style/Widget.Material.Light.ProgressBar.Horizontal"
+ />
diff --git a/core/res/res/layout/progress_dialog_material.xml b/core/res/res/layout/progress_dialog_material.xml
index 84d06b5..54af106 100644
--- a/core/res/res/layout/progress_dialog_material.xml
+++ b/core/res/res/layout/progress_dialog_material.xml
@@ -19,21 +19,27 @@
android:layout_width="match_parent"
android:layout_height="wrap_content">
- <LinearLayout android:id="@+id/body"
+ <LinearLayout
+ android:id="@+id/body"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:baselineAligned="false"
- android:padding="16dip">
+ android:paddingStart="@dimen/alert_dialog_padding_material"
+ android:paddingTop="@dimen/alert_dialog_padding_top_material"
+ android:paddingEnd="@dimen/alert_dialog_padding_material"
+ android:paddingBottom="@dimen/alert_dialog_padding_top_material">
- <ProgressBar android:id="@android:id/progress"
+ <ProgressBar
+ android:id="@id/progress"
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:max="10000"
- android:layout_marginEnd="16dip" />
+ android:layout_marginEnd="@dimen/alert_dialog_padding_material" />
- <TextView android:id="@+id/message"
+ <TextView
+ android:id="@+id/message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical" />
diff --git a/core/res/res/layout/resolve_list_item.xml b/core/res/res/layout/resolve_list_item.xml
index 7aa9a72..37c4270 100644
--- a/core/res/res/layout/resolve_list_item.xml
+++ b/core/res/res/layout/resolve_list_item.xml
@@ -18,9 +18,10 @@
*/
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
+ android:orientation="horizontal"
android:layout_height="wrap_content"
android:layout_width="match_parent"
+ android:minHeight="?attr/listPreferredItemHeightSmall"
android:paddingTop="4dp"
android:paddingBottom="4dp"
android:background="?attr/activatedBackgroundIndicator">
@@ -28,37 +29,40 @@
<!-- Activity icon when presenting dialog
Size will be filled in by ResolverActivity -->
<ImageView android:id="@+id/icon"
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:layout_gravity="center"
- android:layout_margin="4dp"
+ android:layout_width="24dp"
+ android:layout_height="24dp"
+ android:layout_gravity="start|center_vertical"
+ android:layout_marginStart="16dp"
+ android:layout_marginEnd="16dp"
+ android:layout_marginTop="12dp"
+ android:layout_marginBottom="12dp"
android:scaleType="fitCenter" />
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:gravity="center"
+ android:gravity="start|center_vertical"
android:orientation="vertical"
+ android:paddingStart="16dp"
+ android:paddingEnd="16dp"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
- android:layout_gravity="center">
+ android:layout_gravity="start|center_vertical">
<!-- Activity name -->
<TextView android:id="@android:id/text1"
- android:textAppearance="?android:attr/textAppearanceSmall"
- android:fontFamily="sans-serif-condensed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:gravity="center"
- android:minLines="2"
- android:maxLines="2" />
+ android:textAppearance="?attr/textAppearanceMedium"
+ android:textColor="?attr/textColorPrimary"
+ android:minLines="1"
+ android:maxLines="1"
+ android:ellipsize="marquee" />
<!-- Extended activity info to distinguish between duplicate activity names -->
<TextView android:id="@android:id/text2"
android:textAppearance="?android:attr/textAppearanceSmall"
- android:fontFamily="sans-serif-condensed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:gravity="center"
- android:minLines="2"
- android:maxLines="2"
- android:paddingTop="4dip" />
+ android:minLines="1"
+ android:maxLines="1"
+ android:ellipsize="marquee" />
</LinearLayout>
</LinearLayout>
diff --git a/core/res/res/layout/resolver_different_item_header.xml b/core/res/res/layout/resolver_different_item_header.xml
new file mode 100644
index 0000000..5889136
--- /dev/null
+++ b/core/res/res/layout/resolver_different_item_header.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 2014, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<TextView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_alwaysShow="true"
+ android:text="@string/use_a_different_app"
+ android:minHeight="56dp"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:gravity="start|center_vertical"
+ android:paddingStart="16dp"
+ android:paddingEnd="16dp"
+ android:paddingTop="8dp"
+ android:paddingBottom="8dp"
+ android:background="@color/white"
+ android:elevation="8dp"
+ />
diff --git a/core/res/res/layout/resolver_list.xml b/core/res/res/layout/resolver_list.xml
index 8e57543..727f9c6 100644
--- a/core/res/res/layout/resolver_list.xml
+++ b/core/res/res/layout/resolver_list.xml
@@ -21,38 +21,36 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:maxWidth="@dimen/resolver_max_width"
- android:maxCollapsedHeight="260dp"
+ android:maxCollapsedHeight="192dp"
android:maxCollapsedHeightSmall="56dp"
android:id="@id/contentPanel"
>
<TextView android:id="@+id/title"
android:layout_width="match_parent"
- android:layout_height="?android:attr/listPreferredItemHeight"
+ android:layout_height="wrap_content"
android:layout_alwaysShow="true"
+ android:minHeight="56dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:gravity="start|center_vertical"
- android:paddingLeft="32dp"
- android:paddingRight="32dp"
+ android:paddingStart="16dp"
+ android:paddingEnd="16dp"
+ android:paddingTop="8dp"
+ android:paddingBottom="8dp"
android:background="@color/white"
android:elevation="8dp"
/>
- <GridView
+ <ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/resolver_list"
- android:numColumns="4"
- android:columnWidth="128dp"
android:clipToPadding="false"
android:scrollbarStyle="outsideOverlay"
- android:paddingLeft="32dp"
- android:paddingRight="32dp"
- android:paddingTop="16dp"
- android:paddingBottom="16dp"
android:background="@color/white"
android:elevation="8dp"
android:nestedScrollingEnabled="true"
+ android:divider="@null"
/>
<TextView android:id="@+id/empty"
@@ -72,14 +70,15 @@
android:layout_height="wrap_content"
android:layout_ignoreOffset="true"
android:layout_alwaysShow="true"
- android:gravity="end"
+ android:gravity="end|center_vertical"
android:orientation="horizontal"
android:layoutDirection="locale"
android:measureWithLargestChild="true"
android:background="@color/white"
- android:paddingBottom="16dp"
- android:paddingStart="32dp"
- android:paddingEnd="32dp"
+ android:paddingTop="8dp"
+ android:paddingBottom="8dp"
+ android:paddingStart="12dp"
+ android:paddingEnd="12dp"
android:elevation="8dp">
<Button android:id="@+id/button_once"
android:layout_width="wrap_content"
diff --git a/core/res/res/layout/resolver_list_with_default.xml b/core/res/res/layout/resolver_list_with_default.xml
index 0bd0e14..884f41e 100644
--- a/core/res/res/layout/resolver_list_with_default.xml
+++ b/core/res/res/layout/resolver_list_with_default.xml
@@ -21,7 +21,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:maxWidth="@dimen/resolver_max_width"
- android:maxCollapsedHeight="48dp"
+ android:maxCollapsedHeight="144dp"
android:id="@id/contentPanel"
>
@@ -35,26 +35,28 @@
<LinearLayout
android:layout_width="match_parent"
- android:layout_height="80dp"
- android:paddingStart="32dp"
- android:paddingEnd="32dp"
+ android:layout_height="64dp"
android:orientation="horizontal"
>
+ <ImageView android:id="@+id/icon"
+ android:layout_width="24dp"
+ android:layout_height="24dp"
+ android:layout_gravity="start|top"
+ android:layout_marginStart="16dp"
+ android:layout_marginEnd="16dp"
+ android:layout_marginTop="20dp"
+ android:scaleType="fitCenter"
+ />
<TextView android:id="@+id/title"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="?android:attr/listPreferredItemHeight"
+ android:layout_marginStart="16dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:gravity="start|center_vertical"
android:paddingEnd="16dp"
/>
- <ImageView android:id="@+id/icon"
- android:layout_width="56dp"
- android:layout_height="56dp"
- android:layout_gravity="center_vertical"
- android:scaleType="fitCenter"
- />
</LinearLayout>
<LinearLayout
@@ -64,13 +66,14 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alwaysShow="true"
- android:gravity="end"
+ android:gravity="end|center_vertical"
android:orientation="horizontal"
android:layoutDirection="locale"
android:measureWithLargestChild="true"
- android:paddingBottom="16dp"
- android:paddingStart="32dp"
- android:paddingEnd="32dp"
+ android:paddingTop="8dp"
+ android:paddingBottom="8dp"
+ android:paddingStart="12dp"
+ android:paddingEnd="12dp"
android:background="@color/white"
android:elevation="8dp">
<Button android:id="@+id/button_once"
@@ -99,21 +102,16 @@
android:background="?android:attr/dividerVertical" />
</LinearLayout>
- <GridView
+ <ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/resolver_list"
- android:numColumns="4"
- android:columnWidth="128dp"
android:clipToPadding="false"
android:scrollbarStyle="outsideOverlay"
- android:paddingLeft="32dp"
- android:paddingRight="32dp"
- android:paddingTop="16dp"
- android:paddingBottom="16dp"
android:background="@color/white"
android:elevation="8dp"
android:nestedScrollingEnabled="true"
+ android:divider="@null"
/>
</com.android.internal.widget.ResolverDrawerLayout>
diff --git a/core/res/res/values-mcc302-mnc220/config.xml b/core/res/res/values-mcc302-mnc220/config.xml
index 5259152..06b6efe 100644
--- a/core/res/res/values-mcc302-mnc220/config.xml
+++ b/core/res/res/values-mcc302-mnc220/config.xml
@@ -25,4 +25,6 @@
<item>302720</item>
<item>302780</item>
</string-array>
+
+ <integer name="config_mobile_mtu">1410</integer>
</resources>
diff --git a/core/res/res/values-mcc310-mnc004/config.xml b/core/res/res/values-mcc310-mnc004/config.xml
index 2778b6e..423e250 100644
--- a/core/res/res/values-mcc310-mnc004/config.xml
+++ b/core/res/res/values-mcc310-mnc004/config.xml
@@ -34,11 +34,4 @@
</string-array>
<bool name="config_auto_attach_data_on_creation">false</bool>
-
- <!-- Values for GPS configuration (Verizon) -->
- <string-array translatable="false" name="config_gpsParameters">
- <item>CAPABILITIES=0x31</item>
- <item>LPP_PROFILE=3</item>
- <item>GPS_LOCK=3</item>
- </string-array>
</resources>
diff --git a/core/res/res/values-mcc310-mnc120/config.xml b/core/res/res/values-mcc310-mnc120/config.xml
index 3b95db5..62001d9 100644
--- a/core/res/res/values-mcc310-mnc120/config.xml
+++ b/core/res/res/values-mcc310-mnc120/config.xml
@@ -25,10 +25,4 @@
-->
<integer name="config_mobile_mtu">1422</integer>
- <!-- Values for GPS configuration (Sprint) -->
- <string-array translatable="false" name="config_gpsParameters">
- <item>CAPABILITIES=0x31</item>
- <item>GPS_LOCK=3</item>
- <item>LPP_PROFILE=2</item>
- </string-array>
</resources>
diff --git a/core/res/res/values-mcc310-mnc150/config.xml b/core/res/res/values-mcc310-mnc150/config.xml
index 00d2db8..f1936f4 100644
--- a/core/res/res/values-mcc310-mnc150/config.xml
+++ b/core/res/res/values-mcc310-mnc150/config.xml
@@ -33,10 +33,4 @@
<item>315</item>
<item>316</item>
</string-array>
- <!-- Values for GPS configuration (AT&T) -->
- <string-array translatable="false" name="config_gpsParameters">
- <item>CAPABILITIES=0x33</item>
- <item>LPP_PROFILE=3</item>
- <item>GPS_LOCK=1</item>
- </string-array>
</resources>
diff --git a/core/res/res/values-mcc310-mnc260/config.xml b/core/res/res/values-mcc310-mnc260/config.xml
index f8fff3b..28cd695 100644
--- a/core/res/res/values-mcc310-mnc260/config.xml
+++ b/core/res/res/values-mcc310-mnc260/config.xml
@@ -29,11 +29,4 @@
carrier provisioning. If false: hard disabled. If true: then depends on carrier
provisioning, availability etc -->
<bool name="config_carrier_volte_vt_available">true</bool>
-
- <!-- Values for GPS configuration (T-Mobile) -->
- <string-array translatable="false" name="config_gpsParameters">
- <item>CAPABILITEIS=0x33</item>
- <item>GPS_LOCK=1</item>
- <item>LPP_PROFILE=2</item>
- </string-array>
</resources>
diff --git a/core/res/res/values-mcc310-mnc410/config.xml b/core/res/res/values-mcc310-mnc410/config.xml
index edf6d9f..b863aae 100644
--- a/core/res/res/values-mcc310-mnc410/config.xml
+++ b/core/res/res/values-mcc310-mnc410/config.xml
@@ -40,12 +40,6 @@
<item>315</item>
<item>316</item>
</string-array>
- <!-- Values for GPS configuration (AT&T) -->
- <string-array translatable="false" name="config_gpsParameters">
- <item>CAPABILITIES=0x33</item>
- <item>GPS_LOCK=1</item>
- <item>LPP_PROFILE=3</item>
- </string-array>
<!-- Do not translate. Defines the slots is Two Digit Number for dialing normally not USSD -->
<string-array name="config_twoDigitNumberPattern">
<item>"0"</item>
diff --git a/core/res/res/values-mcc311-mnc190/config.xml b/core/res/res/values-mcc311-mnc190/config.xml
index b4e436d..a6c4d1b 100644
--- a/core/res/res/values-mcc311-mnc190/config.xml
+++ b/core/res/res/values-mcc311-mnc190/config.xml
@@ -37,11 +37,4 @@
note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
<string translatable="false" name="config_tether_apndata">Tether,broadband.cellular1.net,,,,,,,,,311,190,,DUN</string>
- <!-- Values for GPS configuration (Sprint) -->
- <string-array translatable="false" name="config_gpsParameters">
- <item>CAPABILITIES=0x31</item>
- <item>GPS_LOCK=3</item>
- <item>LPP_PROFILE=2</item>
- </string-array>
-
</resources>
diff --git a/core/res/res/values-mcc311-mnc480/config.xml b/core/res/res/values-mcc311-mnc480/config.xml
index 57ecd31..cf19235 100644
--- a/core/res/res/values-mcc311-mnc480/config.xml
+++ b/core/res/res/values-mcc311-mnc480/config.xml
@@ -44,11 +44,4 @@
<bool name="config_carrier_volte_vt_available">false</bool>
<bool name="config_auto_attach_data_on_creation">false</bool>
-
- <!-- Values for GPS configuration (Verizon) -->
- <string-array translatable="false" name="config_gpsParameters">
- <item>CAPABILITIES=0x31</item>
- <item>GPS_LOCK=3</item>
- <item>LPP_PROFILE=3</item>
- </string-array>
</resources>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index cf4064f..a00ed5d 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -4483,12 +4483,12 @@
<!-- The row boundary delimiting the top of the group of cells
occupied by this view. -->
<attr name="layout_row" format="integer" />
- <!-- The row span: the difference between the bottom and top
+ <!-- The row span: the difference between the top and bottom
boundaries delimiting the group of cells occupied by this view.
The default is one.
See {@link android.widget.GridLayout.Spec}. -->
<attr name="layout_rowSpan" format="integer" min="1" />
- <!-- The relative proportion of horizontal space that should be allocated to this view
+ <!-- The relative proportion of vertical space that should be allocated to this view
during excess space distribution. -->
<attr name="layout_rowWeight" format="float" />
<!-- The column boundary delimiting the left of the group of cells
@@ -4499,7 +4499,7 @@
The default is one.
See {@link android.widget.GridLayout.Spec}. -->
<attr name="layout_columnSpan" format="integer" min="1" />
- <!-- The relative proportion of vertical space that should be allocated to this view
+ <!-- The relative proportion of horizontal space that should be allocated to this view
during excess space distribution. -->
<attr name="layout_columnWeight" format="float" />
<!-- Gravity specifies how a component should be placed in its group of cells.
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index f3b3077..b36387f 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -351,6 +351,9 @@
point on the move. A value of 0 means no periodic scans will be used in the framework. -->
<integer translatable="false" name="config_wifi_framework_scan_interval">300000</integer>
+ <!-- Integer indicating associated scan interval in milliseconds -->
+ <integer translatable="false" name="config_wifi_framework_associated_scan_interval">10000</integer>
+
<!-- Wifi driver stop delay, in milliseconds.
Default value is 2 minutes. -->
<integer translatable="false" name="config_wifi_driver_stop_delay">120000</integer>
@@ -1611,6 +1614,10 @@
<!-- default window ShowCircularMask property -->
<bool name="config_windowShowCircularMask">false</bool>
+ <!-- default value for whether circular emulators (ro.emulator.circular)
+ should show a display overlay on the screen -->
+ <bool name="config_windowEnableCircularEmulatorDisplayOverlay">false</bool>
+
<!-- Defines the default set of global actions. Actions may still be disabled or hidden based
on the current state of the device.
Each item must be one of the following strings:
@@ -1715,16 +1722,22 @@
<string-array translatable="false" name="config_gpsParameters">
<item>SUPL_HOST=supl.google.com</item>
<item>SUPL_PORT=7275</item>
- <item>XTRA_SERVER_1=http://xtrapath1.izatcloud.net/xtra2.bin</item>
- <item>XTRA_SERVER_2=http://xtrapath2.izatcloud.net/xtra2.bin</item>
- <item>XTRA_SERVER_3=http://xtrapath3.izatcloud.net/xtra2.bin</item>
<item>NTP_SERVER=north-america.pool.ntp.org</item>
<item>SUPL_VER=0x20000</item>
- <item>CAPABILITIES=0x33</item>
- <item>LPP_PROFILE=0</item>
- <item>NMEA_PROVIDER=0</item>
- <item>A_GLONASS_POS_PROTOCOL_SELECT=0</item>
- <item>ERR_ESTIMATE=0</item>
- <item>INTERMEDIATE_POS=0</item>
</string-array>
+
+ <!-- If there is no preload VM number in the sim card, carriers such as
+ Verizon require to load a default vm number from the configurantion.
+ Define config_default_vm_number for this purpose. And there are two
+ optional formats for this configuration as below:
+ (1)<item>voicemail number</item>
+ (2)<item>voicemail number;gid</item>
+ The logic to pick up the correct voicemail number:
+ (1) If the config_default_vm_number array has no gid special item, the last one will be
+ picked
+ (2) If the config_default_vm_number array has gid special item and it matches the current
+ sim's gid, it will be picked.
+ (3) If the config_default_vm_number array has gid special item but it doesn't match the
+ current sim's gid, the last one without gid will be picked -->
+ <string-array translatable="false" name="config_default_vm_number" />
</resources>
diff --git a/core/res/res/values/dimens_material.xml b/core/res/res/values/dimens_material.xml
index 5f7f0ed..275a5ec 100644
--- a/core/res/res/values/dimens_material.xml
+++ b/core/res/res/values/dimens_material.xml
@@ -77,5 +77,6 @@
<!-- Default rounded corner for controls -->
<dimen name="control_corner_material">2dp</dimen>
- <dimen name="alert_dialog_padding_material">18dp</dimen>
+ <dimen name="alert_dialog_padding_material">24dp</dimen>
+ <dimen name="alert_dialog_padding_top_material">18dp</dimen>
</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index f1ec5d2..50da1fa 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -3443,6 +3443,9 @@
<string name="whichHomeApplication">Select a home app</string>
<!-- Option to always use the selected application resolution in the future. See the "Complete action using" dialog title-->
<string name="alwaysUse">Use by default for this action.</string>
+ <!-- Title of the list of alternate options to complete an action shown when the
+ last used option is being displayed separately. -->
+ <string name="use_a_different_app">Use a different app</string>
<!-- Text displayed when the user selects the check box for setting default application. See the "Use by default for this action" check box. -->
<string name="clearDefaultHintMsg">Clear default in System settings &gt; Apps &gt; Downloaded.</string>
<!-- Default title for the activity chooser, when one is not given. Android allows multiple activities to perform an action. for example, there may be many ringtone pickers installed. A dialog is shown to the user allowing him to pick which activity should be used. This is the title. -->
@@ -4874,4 +4877,19 @@
<!-- [CHAR_LIMIT=NONE] Zen mode: Condition summary for built-in downtime condition, if active -->
<string name="downtime_condition_summary">Until your downtime ends at <xliff:g id="formattedTime" example="10.00 PM">%1$s</xliff:g></string>
+
+ <!-- Zen mode condition: time duration in minutes. [CHAR LIMIT=NONE] -->
+ <plurals name="zen_mode_duration_minutes">
+ <item quantity="one">For one minute</item>
+ <item quantity="other">For %d minutes</item>
+ </plurals>
+
+ <!-- Zen mode condition: time duration in hours. [CHAR LIMIT=NONE] -->
+ <plurals name="zen_mode_duration_hours">
+ <item quantity="one">For one hour</item>
+ <item quantity="other">For %d hours</item>
+ </plurals>
+
+ <!-- Zen mode condition: no exit criteria. [CHAR LIMIT=NONE] -->
+ <string name="zen_mode_forever">Indefinitely</string>
</resources>
diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml
index a7335af..26c7d10 100644
--- a/core/res/res/values/styles_material.xml
+++ b/core/res/res/values/styles_material.xml
@@ -474,6 +474,13 @@ please see styles_device_defaults.xml.
<item name="stateListAnimator">@anim/disabled_anim_material</item>
</style>
+ <!-- Alert dialog button bar button -->
+ <style name="Widget.Material.Button.ButtonBar.AlertDialog" parent="Widget.Material.Button.Borderless.Colored">
+ <item name="minWidth">64dp</item>
+ <item name="maxLines">2</item>
+ <item name="minHeight">@dimen/alert_dialog_button_bar_height</item>
+ </style>
+
<!-- Small borderless ink button -->
<style name="Widget.Material.Button.Borderless.Small">
<item name="minHeight">48dip</item>
@@ -496,7 +503,6 @@ please see styles_device_defaults.xml.
<style name="Widget.Material.ButtonBar.AlertDialog">
<item name="background">@null</item>
- <item name="minHeight">@dimen/alert_dialog_button_bar_height</item>
</style>
<style name="Widget.Material.SearchView">
@@ -936,6 +942,7 @@ please see styles_device_defaults.xml.
<style name="Widget.Material.Light.Button.Small" parent="Widget.Material.Button.Small"/>
<style name="Widget.Material.Light.Button.Borderless" parent="Widget.Material.Button.Borderless"/>
<style name="Widget.Material.Light.Button.Borderless.Colored" parent="Widget.Material.Button.Borderless.Colored"/>
+ <style name="Widget.Material.Light.Button.ButtonBar.AlertDialog" parent="Widget.Material.Button.ButtonBar.AlertDialog" />
<style name="Widget.Material.Light.Button.Borderless.Small" parent="Widget.Material.Button.Borderless.Small"/>
<style name="Widget.Material.Light.Button.Inset" parent="Widget.Material.Button.Inset"/>
<style name="Widget.Material.Light.Button.Toggle" parent="Widget.Material.Button.Toggle" />
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 01e6e76..556c07f 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -293,6 +293,7 @@
<java-symbol type="bool" name="config_windowIsRound" />
<java-symbol type="bool" name="config_hasRecents" />
<java-symbol type="bool" name="config_windowShowCircularMask" />
+ <java-symbol type="bool" name="config_windowEnableCircularEmulatorDisplayOverlay" />
<java-symbol type="integer" name="config_bluetooth_max_advertisers" />
<java-symbol type="integer" name="config_bluetooth_max_scan_filters" />
@@ -312,6 +313,7 @@
<java-symbol type="integer" name="config_shortPressOnPowerBehavior" />
<java-symbol type="integer" name="config_toastDefaultGravity" />
<java-symbol type="integer" name="config_wifi_framework_scan_interval" />
+ <java-symbol type="integer" name="config_wifi_framework_associated_scan_interval" />
<java-symbol type="integer" name="config_wifi_supplicant_scan_interval" />
<java-symbol type="integer" name="config_wifi_scan_interval_p2p_connected" />
<java-symbol type="integer" name="db_connection_pool_size" />
@@ -1155,6 +1157,7 @@
<java-symbol type="drawable" name="ic_corp_badge" />
<java-symbol type="drawable" name="ic_corp_icon_badge" />
<java-symbol type="drawable" name="ic_corp_icon" />
+ <java-symbol type="drawable" name="emulator_circular_window_overlay" />
<java-symbol type="drawable" name="sim_light_blue" />
<java-symbol type="drawable" name="sim_light_green" />
@@ -1915,6 +1918,9 @@
<java-symbol type="string" name="timepicker_transition_end_radius_multiplier" />
<java-symbol type="string" name="battery_saver_description" />
<java-symbol type="string" name="downtime_condition_summary" />
+ <java-symbol type="string" name="zen_mode_forever" />
+ <java-symbol type="plurals" name="zen_mode_duration_minutes" />
+ <java-symbol type="plurals" name="zen_mode_duration_hours" />
<java-symbol type="string" name="item_is_selected" />
<java-symbol type="string" name="day_of_week_label_typeface" />
@@ -2004,4 +2010,6 @@
<java-symbol type="bool" name="config_auto_attach_data_on_creation" />
<java-symbol type="id" name="date_picker_month_day_year_layout" />
<java-symbol type="attr" name="closeItemLayout" />
+ <java-symbol type="layout" name="resolver_different_item_header" />
+ <java-symbol type="array" name="config_default_vm_number" />
</resources>
diff --git a/core/res/res/values/themes_material.xml b/core/res/res/values/themes_material.xml
index ab5cd5a..4aca02e 100644
--- a/core/res/res/values/themes_material.xml
+++ b/core/res/res/values/themes_material.xml
@@ -333,7 +333,7 @@ please see themes_device_defaults.xml.
<item name="dividerVertical">?attr/listDivider</item>
<item name="dividerHorizontal">?attr/listDivider</item>
<item name="buttonBarStyle">@style/Widget.Material.ButtonBar</item>
- <item name="buttonBarButtonStyle">@style/Widget.Material.Button.Borderless.Colored</item>
+ <item name="buttonBarButtonStyle">@style/Widget.Material.Button.ButtonBar.AlertDialog</item>
<item name="segmentedButtonStyle">@style/Widget.Material.SegmentedButton</item>
<!-- SearchView attributes -->
@@ -679,7 +679,7 @@ please see themes_device_defaults.xml.
<item name="dividerVertical">?attr/listDivider</item>
<item name="dividerHorizontal">?attr/listDivider</item>
<item name="buttonBarStyle">@style/Widget.Material.Light.ButtonBar</item>
- <item name="buttonBarButtonStyle">@style/Widget.Material.Light.Button.Borderless.Colored</item>
+ <item name="buttonBarButtonStyle">@style/Widget.Material.Light.Button.ButtonBar.AlertDialog</item>
<item name="segmentedButtonStyle">@style/Widget.Material.Light.SegmentedButton</item>
<!-- SearchView attributes -->
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestBase.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestBase.java
index 77e1c53..80d5668 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestBase.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestBase.java
@@ -322,8 +322,13 @@ public class ConnectivityManagerTestBase extends InstrumentationTestCase {
* If the device is already associated with a WiFi, disconnect and forget it,
* We don't verify whether the connection is successful or not, leave this to the test
*/
- protected boolean connectToWifi(String knownSSID) {
- WifiConfiguration config = WifiConfigurationHelper.createOpenConfig(knownSSID);
+ protected boolean connectToWifi(String ssid, String password) {
+ WifiConfiguration config;
+ if (password == null) {
+ config = WifiConfigurationHelper.createOpenConfig(ssid);
+ } else {
+ config = WifiConfigurationHelper.createPskConfig(ssid, password);
+ }
return connectToWifiWithConfiguration(config);
}
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestRunner.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestRunner.java
index b94306a..b6eb674 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestRunner.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestRunner.java
@@ -35,8 +35,9 @@ import junit.framework.TestSuite;
*/
public class ConnectivityManagerTestRunner extends InstrumentationTestRunner {
- public boolean mWifiOnlyFlag = false;
- public String mTestSsid = null;
+ public boolean mWifiOnly = false;
+ public String mSsid = null;
+ public String mPassword = null;
@Override
public TestSuite getAllTests() {
@@ -54,13 +55,29 @@ public class ConnectivityManagerTestRunner extends InstrumentationTestRunner {
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
- String testSSID = (String) icicle.get("ssid");
- if (testSSID != null) {
- mTestSsid = testSSID;
+ String ssid = icicle.getString("ssid");
+ if (ssid != null) {
+ mSsid = ssid;
+ }
+ String password = (String) icicle.get("password");
+ if (password != null) {
+ mPassword = password;
}
String wifiOnlyFlag = (String) icicle.get("wifi-only");
if (wifiOnlyFlag != null) {
- mWifiOnlyFlag = true;
+ mWifiOnly = true;
}
}
+
+ public String getWifiSsid() {
+ return mSsid;
+ }
+
+ public String getWifiPassword() {
+ return mPassword;
+ }
+
+ public boolean isWifiOnly() {
+ return mWifiOnly;
+ }
}
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java
index b280106..d5051df 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java
@@ -33,7 +33,8 @@ public class ConnectivityManagerMobileTest extends ConnectivityManagerTestBase
super(ConnectivityManagerMobileTest.class.getSimpleName());
}
- private String mTestAccessPoint;
+ private String mSsid;
+ private String mPassword;
private boolean mWifiOnlyFlag;
@Override
@@ -41,8 +42,9 @@ public class ConnectivityManagerMobileTest extends ConnectivityManagerTestBase
super.setUp();
ConnectivityManagerTestRunner mRunner =
(ConnectivityManagerTestRunner)getInstrumentation();
- mTestAccessPoint = mRunner.mTestSsid;
- mWifiOnlyFlag = mRunner.mWifiOnlyFlag;
+ mSsid = mRunner.getWifiSsid();
+ mPassword = mRunner.getWifiPassword();
+ mWifiOnlyFlag = mRunner.isWifiOnly();
// Each test case will start with cellular connection
if (Settings.Global.getInt(getInstrumentation().getContext().getContentResolver(),
@@ -120,11 +122,10 @@ public class ConnectivityManagerMobileTest extends ConnectivityManagerTestBase
// Test case 2: test connection to a given AP
@LargeTest
public void testConnectToWifi() {
- assertNotNull("SSID is null", mTestAccessPoint);
+ assertNotNull("SSID is null", mSsid);
// assert that we are able to connect to the ap
- assertTrue("failed to connect to " + mTestAccessPoint,
- connectToWifi(mTestAccessPoint));
+ assertTrue("failed to connect to " + mSsid, connectToWifi(mSsid, mPassword));
// assert that WifiManager reports correct state
assertTrue("wifi not enabled", waitForWifiState(
WifiManager.WIFI_STATE_ENABLED, LONG_TIMEOUT));
@@ -144,14 +145,14 @@ public class ConnectivityManagerMobileTest extends ConnectivityManagerTestBase
// Test case 3: connect & reconnect to Wifi with known AP
@LargeTest
public void testConnectToWifWithKnownAP() {
- assertNotNull("SSID is null", mTestAccessPoint);
+ assertNotNull("SSID is null", mSsid);
// enable WiFi
assertTrue("failed to enable wifi", enableWifi());
// wait for wifi enable
assertTrue("wifi not enabled", waitForWifiState(
WifiManager.WIFI_STATE_ENABLED, LONG_TIMEOUT));
// Connect to AP
- assertTrue("failed to connect to " + mTestAccessPoint, connectToWifi(mTestAccessPoint));
+ assertTrue("failed to connect to " + mSsid, connectToWifi(mSsid, mPassword));
// verify wifi connected as reported by ConnectivityManager
assertTrue("wifi not connected", waitForNetworkState(
ConnectivityManager.TYPE_WIFI, State.CONNECTED, WIFI_CONNECTION_TIMEOUT));
@@ -191,7 +192,7 @@ public class ConnectivityManagerMobileTest extends ConnectivityManagerTestBase
// Test case 4: test disconnect and clear wifi settings
@LargeTest
public void testDisconnectWifi() {
- assertNotNull("SSID is null", mTestAccessPoint);
+ assertNotNull("SSID is null", mSsid);
// enable WiFi
assertTrue("failed to enable wifi", enableWifi());
@@ -199,8 +200,7 @@ public class ConnectivityManagerMobileTest extends ConnectivityManagerTestBase
assertTrue("wifi not enabled", waitForWifiState(
WifiManager.WIFI_STATE_ENABLED, LONG_TIMEOUT));
// connect to Wifi
- assertTrue("failed to connect to " + mTestAccessPoint,
- connectToWifi(mTestAccessPoint));
+ assertTrue("failed to connect to " + mSsid, connectToWifi(mSsid, mPassword));
assertTrue("wifi not connected", waitForNetworkState(
ConnectivityManager.TYPE_WIFI, State.CONNECTED, WIFI_CONNECTION_TIMEOUT));
@@ -257,7 +257,7 @@ public class ConnectivityManagerMobileTest extends ConnectivityManagerTestBase
// Test case 6: test connectivity with airplane mode on but wifi enabled
@LargeTest
public void testDataConnectionOverAMWithWifi() {
- assertNotNull("SSID is null", mTestAccessPoint);
+ assertNotNull("SSID is null", mSsid);
// enable airplane mode
mCm.setAirplaneMode(true);
// assert there is active network connection after airplane mode disabled
@@ -265,8 +265,7 @@ public class ConnectivityManagerMobileTest extends ConnectivityManagerTestBase
waitUntilNoActiveNetworkConnection(LONG_TIMEOUT));
// connect to Wifi
- assertTrue("failed to connect to " + mTestAccessPoint,
- connectToWifi(mTestAccessPoint));
+ assertTrue("failed to connect to " + mSsid, connectToWifi(mSsid, mPassword));
assertTrue("wifi not connected", waitForNetworkState(
ConnectivityManager.TYPE_WIFI, State.CONNECTED, WIFI_CONNECTION_TIMEOUT));
// verify that connection actually works
@@ -280,15 +279,14 @@ public class ConnectivityManagerMobileTest extends ConnectivityManagerTestBase
@LargeTest
public void testDataConnectionWithWifiToAMToWifi () {
// connect to mTestAccessPoint
- assertNotNull("SSID is null", mTestAccessPoint);
+ assertNotNull("SSID is null", mSsid);
// enable WiFi
assertTrue("failed to enable wifi", enableWifi());
// wait for wifi enable
assertTrue("wifi not enabled", waitForWifiState(
WifiManager.WIFI_STATE_ENABLED, LONG_TIMEOUT));
// connect to Wifi
- assertTrue("failed to connect to " + mTestAccessPoint,
- connectToWifi(mTestAccessPoint));
+ assertTrue("failed to connect to " + mSsid, connectToWifi(mSsid, mPassword));
assertTrue("wifi not connected", waitForNetworkState(
ConnectivityManager.TYPE_WIFI, State.CONNECTED, WIFI_CONNECTION_TIMEOUT));
@@ -313,15 +311,14 @@ public class ConnectivityManagerMobileTest extends ConnectivityManagerTestBase
// Test case 8: test wifi state change while connecting/disconnecting to/from an AP
@LargeTest
public void testWifiStateChange () {
- assertNotNull("SSID is null", mTestAccessPoint);
+ assertNotNull("SSID is null", mSsid);
// enable WiFi
assertTrue("failed to enable wifi", enableWifi());
// wait for wifi enable
assertTrue("wifi not enabled", waitForWifiState(
WifiManager.WIFI_STATE_ENABLED, LONG_TIMEOUT));
// connect to Wifi
- assertTrue("failed to connect to " + mTestAccessPoint,
- connectToWifi(mTestAccessPoint));
+ assertTrue("failed to connect to " + mSsid, connectToWifi(mSsid, mPassword));
assertTrue("wifi not connected", waitForNetworkState(
ConnectivityManager.TYPE_WIFI, State.CONNECTED, WIFI_CONNECTION_TIMEOUT));
assertNotNull("not associated with any AP", mWifiManager.getConnectionInfo().getBSSID());
diff --git a/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/downloadmanagertests/DownloadManagerTestApp.java b/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/downloadmanagertests/DownloadManagerTestApp.java
index bcf2e45..db547e2 100644
--- a/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/downloadmanagertests/DownloadManagerTestApp.java
+++ b/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/downloadmanagertests/DownloadManagerTestApp.java
@@ -60,10 +60,10 @@ public class DownloadManagerTestApp extends DownloadManagerBaseTest {
super.setUp();
DownloadManagerTestRunner mRunner = (DownloadManagerTestRunner)getInstrumentation();
externalDownloadUriValue = normalizeUri(mRunner.externalDownloadUriValue);
- assertNotNull(externalDownloadUriValue);
+ assertNotNull("download url is null", externalDownloadUriValue);
externalLargeDownloadUriValue = normalizeUri(mRunner.externalDownloadUriValue);
- assertNotNull(externalLargeDownloadUriValue);
+ assertNotNull("large download url is null", externalLargeDownloadUriValue);
}
/**
@@ -140,7 +140,7 @@ public class DownloadManagerTestApp extends DownloadManagerBaseTest {
dlRequest = mDownloadManager.enqueue(request);
waitForDownloadToStart(dlRequest);
- assertTrue(dlRequest != -1);
+ assertTrue("request id is -1 from download manager", dlRequest != -1);
// Store ID of download for later retrieval
outputFile = new DataOutputStream(fileOutput);
@@ -183,7 +183,7 @@ public class DownloadManagerTestApp extends DownloadManagerBaseTest {
mContext.deleteFile(DOWNLOAD_STARTED_FLAG);
}
- assertTrue(dlRequest != -1);
+ assertTrue("request id is -1 from download manager", dlRequest != -1);
Cursor cursor = getCursor(dlRequest);
ParcelFileDescriptor pfd = null;
try {
@@ -193,7 +193,7 @@ public class DownloadManagerTestApp extends DownloadManagerBaseTest {
int status = cursor.getInt(columnIndex);
int currentWaitTime = 0;
- assertTrue(waitForDownload(dlRequest, 15 * 60 * 1000));
+ assertTrue("download not finished", waitForDownload(dlRequest, 15 * 60 * 1000));
Log.i(LOG_TAG, "Verifying download information...");
// Verify specific info about the file (size, name, etc)...
@@ -233,7 +233,7 @@ public class DownloadManagerTestApp extends DownloadManagerBaseTest {
dlRequest = mDownloadManager.enqueue(request);
// Rather large file, so wait up to 15 mins...
- assertTrue(waitForDownload(dlRequest, 15 * 60 * 1000));
+ assertTrue("download not finished", waitForDownload(dlRequest, 15 * 60 * 1000));
Cursor cursor = getCursor(dlRequest);
ParcelFileDescriptor pfd = null;
@@ -317,7 +317,7 @@ public class DownloadManagerTestApp extends DownloadManagerBaseTest {
Log.i(LOG_TAG, "Turning on WiFi...");
setWiFiStateOn(true);
Log.i(LOG_TAG, "Waiting up to 10 minutes for download to complete...");
- assertTrue(waitForDownload(dlRequest, 10 * 60 * 1000));
+ assertTrue("download not finished", waitForDownload(dlRequest, 10 * 60 * 1000));
ParcelFileDescriptor pfd = mDownloadManager.openDownloadedFile(dlRequest);
verifyFileSize(pfd, filesize);
} finally {
@@ -385,7 +385,7 @@ public class DownloadManagerTestApp extends DownloadManagerBaseTest {
setWiFiStateOn(true);
Log.i(LOG_TAG, "Waiting up to 10 minutes for download to complete...");
- assertTrue(waitForDownload(dlRequest, 10 * 60 * 1000));
+ assertTrue("download not finished", waitForDownload(dlRequest, 10 * 60 * 1000));
ParcelFileDescriptor pfd = mDownloadManager.openDownloadedFile(dlRequest);
verifyFileSize(pfd, filesize);
} finally {
@@ -456,7 +456,7 @@ public class DownloadManagerTestApp extends DownloadManagerBaseTest {
setAirplaneModeOn(false);
Log.i(LOG_TAG, "Waiting up to 10 minutes for donwload to complete...");
- assertTrue(waitForDownload(dlRequest, 10 * 60 * 1000)); // wait up to 10 mins
+ assertTrue("download not finished", waitForDownload(dlRequest, 10 * 60 * 1000)); // wait up to 10 mins
ParcelFileDescriptor pfd = mDownloadManager.openDownloadedFile(dlRequest);
verifyFileSize(pfd, filesize);
} finally {
@@ -489,11 +489,11 @@ public class DownloadManagerTestApp extends DownloadManagerBaseTest {
Request request = new Request(remoteUri);
request.setTitle(filename);
dlRequest = mDownloadManager.enqueue(request);
- assertTrue(dlRequest != -1);
+ assertTrue("request id is -1 from download manager", dlRequest != -1);
downloadIds.add(dlRequest);
}
- assertTrue(waitForMultipleDownloads(downloadIds, 15 * 60 * 2000)); // wait 15 mins max
+ assertTrue("download not finished", waitForMultipleDownloads(downloadIds, 15 * 60 * 2000)); // wait 15 mins max
} finally {
removeAllCurrentDownloads();
}
diff --git a/core/tests/inputmethodtests/src/android/os/CursorAnchorInfoTest.java b/core/tests/inputmethodtests/src/android/os/CursorAnchorInfoTest.java
index b6a03d9..d4244ba 100644
--- a/core/tests/inputmethodtests/src/android/os/CursorAnchorInfoTest.java
+++ b/core/tests/inputmethodtests/src/android/os/CursorAnchorInfoTest.java
@@ -116,16 +116,16 @@ public class CursorAnchorInfoTest extends InstrumentationTestCase {
assertEquals(TRANSFORM_MATRIX, info.getMatrix());
for (int i = 0; i < MANY_BOUNDS.length; i++) {
final RectF expectedBounds = MANY_BOUNDS[i];
- assertEquals(expectedBounds, info.getCharacterRect(i));
+ assertEquals(expectedBounds, info.getCharacterBounds(i));
}
- assertNull(info.getCharacterRect(-1));
- assertNull(info.getCharacterRect(MANY_BOUNDS.length + 1));
+ assertNull(info.getCharacterBounds(-1));
+ assertNull(info.getCharacterBounds(MANY_BOUNDS.length + 1));
for (int i = 0; i < MANY_FLAGS_ARRAY.length; i++) {
final int expectedFlags = MANY_FLAGS_ARRAY[i];
- assertEquals(expectedFlags, info.getCharacterRectFlags(i));
+ assertEquals(expectedFlags, info.getCharacterBoundsFlags(i));
}
- assertEquals(0, info.getCharacterRectFlags(-1));
- assertEquals(0, info.getCharacterRectFlags(MANY_BOUNDS.length + 1));
+ assertEquals(0, info.getCharacterBoundsFlags(-1));
+ assertEquals(0, info.getCharacterBoundsFlags(MANY_BOUNDS.length + 1));
// Make sure that the builder can reproduce the same object.
final CursorAnchorInfo info2 = builder.build();
@@ -141,16 +141,16 @@ public class CursorAnchorInfoTest extends InstrumentationTestCase {
assertEquals(TRANSFORM_MATRIX, info2.getMatrix());
for (int i = 0; i < MANY_BOUNDS.length; i++) {
final RectF expectedBounds = MANY_BOUNDS[i];
- assertEquals(expectedBounds, info2.getCharacterRect(i));
+ assertEquals(expectedBounds, info2.getCharacterBounds(i));
}
- assertNull(info2.getCharacterRect(-1));
- assertNull(info2.getCharacterRect(MANY_BOUNDS.length + 1));
+ assertNull(info2.getCharacterBounds(-1));
+ assertNull(info2.getCharacterBounds(MANY_BOUNDS.length + 1));
for (int i = 0; i < MANY_FLAGS_ARRAY.length; i++) {
final int expectedFlags = MANY_FLAGS_ARRAY[i];
- assertEquals(expectedFlags, info2.getCharacterRectFlags(i));
+ assertEquals(expectedFlags, info2.getCharacterBoundsFlags(i));
}
- assertEquals(0, info2.getCharacterRectFlags(-1));
- assertEquals(0, info2.getCharacterRectFlags(MANY_BOUNDS.length + 1));
+ assertEquals(0, info2.getCharacterBoundsFlags(-1));
+ assertEquals(0, info2.getCharacterBoundsFlags(MANY_BOUNDS.length + 1));
assertEquals(info, info2);
assertEquals(info.hashCode(), info2.hashCode());
@@ -168,16 +168,16 @@ public class CursorAnchorInfoTest extends InstrumentationTestCase {
assertEquals(TRANSFORM_MATRIX, info3.getMatrix());
for (int i = 0; i < MANY_BOUNDS.length; i++) {
final RectF expectedBounds = MANY_BOUNDS[i];
- assertEquals(expectedBounds, info3.getCharacterRect(i));
+ assertEquals(expectedBounds, info3.getCharacterBounds(i));
}
- assertNull(info3.getCharacterRect(-1));
- assertNull(info3.getCharacterRect(MANY_BOUNDS.length + 1));
+ assertNull(info3.getCharacterBounds(-1));
+ assertNull(info3.getCharacterBounds(MANY_BOUNDS.length + 1));
for (int i = 0; i < MANY_FLAGS_ARRAY.length; i++) {
final int expectedFlags = MANY_FLAGS_ARRAY[i];
- assertEquals(expectedFlags, info3.getCharacterRectFlags(i));
+ assertEquals(expectedFlags, info3.getCharacterBoundsFlags(i));
}
- assertEquals(0, info3.getCharacterRectFlags(-1));
- assertEquals(0, info3.getCharacterRectFlags(MANY_BOUNDS.length + 1));
+ assertEquals(0, info3.getCharacterBoundsFlags(-1));
+ assertEquals(0, info3.getCharacterBoundsFlags(MANY_BOUNDS.length + 1));
assertEquals(info.hashCode(), info3.hashCode());
builder.reset();
diff --git a/core/tests/inputmethodtests/src/android/os/InputMethodTest.java b/core/tests/inputmethodtests/src/android/os/InputMethodTest.java
index fa1bd8f..5958c3a 100644
--- a/core/tests/inputmethodtests/src/android/os/InputMethodTest.java
+++ b/core/tests/inputmethodtests/src/android/os/InputMethodTest.java
@@ -26,6 +26,7 @@ import android.test.InstrumentationTestCase;
import android.test.suitebuilder.annotation.SmallTest;
import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodSubtype;
+import android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder;
import java.util.ArrayList;
import java.util.List;
@@ -159,8 +160,15 @@ public class InputMethodTest extends InstrumentationTestCase {
private static InputMethodSubtype createDummyInputMethodSubtype(String locale, String mode,
boolean isAuxiliary, boolean overridesImplicitlyEnabledSubtype) {
- return new InputMethodSubtype(0, 0, locale, mode, "", isAuxiliary,
- overridesImplicitlyEnabledSubtype);
+ return new InputMethodSubtypeBuilder()
+ .setSubtypeNameResId(0)
+ .setSubtypeIconResId(0)
+ .setSubtypeLocale(locale)
+ .setSubtypeMode(mode)
+ .setSubtypeExtraValue("")
+ .setIsAuxiliary(isAuxiliary)
+ .setOverridesImplicitlyEnabledSubtype(overridesImplicitlyEnabledSubtype)
+ .build();
}
private static InputMethodInfo createDefaultAutoDummyVoiceIme() {