Merge "System to track touch and sensor events before unlocking the phone"
diff --git a/Android.mk b/Android.mk
index 769a555..40da134 100644
--- a/Android.mk
+++ b/Android.mk
@@ -90,6 +90,7 @@
core/java/android/app/IWallpaperManager.aidl \
core/java/android/app/IWallpaperManagerCallback.aidl \
core/java/android/app/admin/IDevicePolicyManager.aidl \
+ core/java/android/app/trust/IStrongAuthTracker.aidl \
core/java/android/app/trust/ITrustManager.aidl \
core/java/android/app/trust/ITrustListener.aidl \
core/java/android/app/backup/IBackupManager.aidl \
diff --git a/api/current.txt b/api/current.txt
index 3e1f5a5..b1e80dd 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -8881,6 +8881,7 @@
field public int configChanges;
field public int documentLaunchMode;
field public int flags;
+ field public android.content.pm.ActivityInfo.InitialLayout initialLayout;
field public int launchMode;
field public int maxRecents;
field public java.lang.String parentActivityName;
@@ -8894,6 +8895,15 @@
field public int uiOptions;
}
+ public static final class ActivityInfo.InitialLayout {
+ ctor public ActivityInfo.InitialLayout(int, float, int, float, int);
+ field public final int gravity;
+ field public final int height;
+ field public final float heightFraction;
+ field public final int width;
+ field public final float widthFraction;
+ }
+
public class ApplicationInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable {
ctor public ApplicationInfo();
ctor public ApplicationInfo(android.content.pm.ApplicationInfo);
@@ -18136,7 +18146,7 @@
method public final int getThumbPixWidth();
}
- public class MtpObjectInfo.Builder {
+ public static class MtpObjectInfo.Builder {
ctor public MtpObjectInfo.Builder();
ctor public MtpObjectInfo.Builder(android.mtp.MtpObjectInfo);
method public android.mtp.MtpObjectInfo build();
@@ -32512,7 +32522,7 @@
method public static int getLayoutDirectionFromLocale(java.util.Locale);
method public static int getOffsetAfter(java.lang.CharSequence, int);
method public static int getOffsetBefore(java.lang.CharSequence, int);
- method public static java.lang.CharSequence getReverse(java.lang.CharSequence, int, int);
+ method public static deprecated java.lang.CharSequence getReverse(java.lang.CharSequence, int, int);
method public static int getTrimmedLength(java.lang.CharSequence);
method public static java.lang.String htmlEncode(java.lang.String);
method public static int indexOf(java.lang.CharSequence, char);
@@ -34141,6 +34151,15 @@
field public static final int RTL = 1; // 0x1
}
+ public final class LocaleList {
+ ctor public LocaleList();
+ ctor public LocaleList(java.util.Locale[]);
+ method public java.util.Locale get(int);
+ method public java.util.Locale getPrimary();
+ method public boolean isEmpty();
+ method public int size();
+ }
+
public final class Log {
method public static int d(java.lang.String, java.lang.String);
method public static int d(java.lang.String, java.lang.String, java.lang.Throwable);
diff --git a/api/system-current.txt b/api/system-current.txt
index 984d395..fe7c6da 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -9139,6 +9139,7 @@
field public int configChanges;
field public int documentLaunchMode;
field public int flags;
+ field public android.content.pm.ActivityInfo.InitialLayout initialLayout;
field public int launchMode;
field public int maxRecents;
field public java.lang.String parentActivityName;
@@ -9152,6 +9153,15 @@
field public int uiOptions;
}
+ public static final class ActivityInfo.InitialLayout {
+ ctor public ActivityInfo.InitialLayout(int, float, int, float, int);
+ field public final int gravity;
+ field public final int height;
+ field public final float heightFraction;
+ field public final int width;
+ field public final float widthFraction;
+ }
+
public class ApplicationInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable {
ctor public ApplicationInfo();
ctor public ApplicationInfo(android.content.pm.ApplicationInfo);
@@ -19649,7 +19659,7 @@
method public final int getThumbPixWidth();
}
- public class MtpObjectInfo.Builder {
+ public static class MtpObjectInfo.Builder {
ctor public MtpObjectInfo.Builder();
ctor public MtpObjectInfo.Builder(android.mtp.MtpObjectInfo);
method public android.mtp.MtpObjectInfo build();
@@ -34845,7 +34855,7 @@
method public static int getLayoutDirectionFromLocale(java.util.Locale);
method public static int getOffsetAfter(java.lang.CharSequence, int);
method public static int getOffsetBefore(java.lang.CharSequence, int);
- method public static java.lang.CharSequence getReverse(java.lang.CharSequence, int, int);
+ method public static deprecated java.lang.CharSequence getReverse(java.lang.CharSequence, int, int);
method public static int getTrimmedLength(java.lang.CharSequence);
method public static java.lang.String htmlEncode(java.lang.String);
method public static int indexOf(java.lang.CharSequence, char);
@@ -36474,6 +36484,15 @@
field public static final int RTL = 1; // 0x1
}
+ public final class LocaleList {
+ ctor public LocaleList();
+ ctor public LocaleList(java.util.Locale[]);
+ method public java.util.Locale get(int);
+ method public java.util.Locale getPrimary();
+ method public boolean isEmpty();
+ method public int size();
+ }
+
public final class Log {
method public static int d(java.lang.String, java.lang.String);
method public static int d(java.lang.String, java.lang.String, java.lang.Throwable);
diff --git a/cmds/bootanimation/Android.mk b/cmds/bootanimation/Android.mk
index 2ee586f..7c8842c 100644
--- a/cmds/bootanimation/Android.mk
+++ b/cmds/bootanimation/Android.mk
@@ -27,6 +27,8 @@
LOCAL_MODULE:= bootanimation
+LOCAL_INIT_RC := bootanim.rc
+
ifdef TARGET_32_BIT_SURFACEFLINGER
LOCAL_32_BIT_ONLY := true
endif
diff --git a/cmds/bootanimation/bootanim.rc b/cmds/bootanimation/bootanim.rc
new file mode 100644
index 0000000..ee0d0b8
--- /dev/null
+++ b/cmds/bootanimation/bootanim.rc
@@ -0,0 +1,6 @@
+service bootanim /system/bin/bootanimation
+ class core
+ user graphics
+ group graphics audio
+ disabled
+ oneshot
diff --git a/core/java/android/app/trust/IStrongAuthTracker.aidl b/core/java/android/app/trust/IStrongAuthTracker.aidl
new file mode 100644
index 0000000..36c71bf
--- /dev/null
+++ b/core/java/android/app/trust/IStrongAuthTracker.aidl
@@ -0,0 +1,26 @@
+/*
+**
+** Copyright 2015, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+package android.app.trust;
+
+/**
+ * Private API to be notified about strong auth changes
+ *
+ * {@hide}
+ */
+oneway interface IStrongAuthTracker {
+ void onStrongAuthRequiredChanged(int strongAuthRequired, int userId);
+}
\ No newline at end of file
diff --git a/core/java/android/app/trust/ITrustManager.aidl b/core/java/android/app/trust/ITrustManager.aidl
index 32951d9..2dea545 100644
--- a/core/java/android/app/trust/ITrustManager.aidl
+++ b/core/java/android/app/trust/ITrustManager.aidl
@@ -26,11 +26,9 @@
interface ITrustManager {
void reportUnlockAttempt(boolean successful, int userId);
void reportEnabledTrustAgentsChanged(int userId);
- void reportRequireCredentialEntry(int userId);
void registerTrustListener(in ITrustListener trustListener);
void unregisterTrustListener(in ITrustListener trustListener);
void reportKeyguardShowingChanged();
boolean isDeviceLocked(int userId);
boolean isDeviceSecure(int userId);
- boolean hasUserAuthenticatedSinceBoot(int userId);
}
diff --git a/core/java/android/app/trust/TrustManager.java b/core/java/android/app/trust/TrustManager.java
index 8cab565..aff69f0 100644
--- a/core/java/android/app/trust/TrustManager.java
+++ b/core/java/android/app/trust/TrustManager.java
@@ -16,13 +16,19 @@
package android.app.trust;
+import android.annotation.IntDef;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
+import android.os.UserHandle;
import android.util.ArrayMap;
import android.util.Log;
+import android.util.SparseIntArray;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
/**
* See {@link com.android.server.trust.TrustManagerService}
@@ -73,21 +79,6 @@
}
/**
- * Reports that trust is disabled until credentials have been entered for user {@param userId}.
- *
- * Requires the {@link android.Manifest.permission#ACCESS_KEYGUARD_SECURE_STORAGE} permission.
- *
- * @param userId either an explicit user id or {@link android.os.UserHandle#USER_ALL}
- */
- public void reportRequireCredentialEntry(int userId) {
- try {
- mService.reportRequireCredentialEntry(userId);
- } catch (RemoteException e) {
- onError(e);
- }
- }
-
- /**
* Reports that the visibility of the keyguard has changed.
*
* Requires the {@link android.Manifest.permission#ACCESS_KEYGUARD_SECURE_STORAGE} permission.
@@ -147,23 +138,6 @@
}
}
- /**
- * Checks whether the specified user has been authenticated since the last boot.
- *
- * @param userId the user id of the user to check for
- * @return true if the user has authenticated since boot, false otherwise
- *
- * Requires the {@link android.Manifest.permission#ACCESS_KEYGUARD_SECURE_STORAGE} permission.
- */
- public boolean hasUserAuthenticatedSinceBoot(int userId) {
- try {
- return mService.hasUserAuthenticatedSinceBoot(userId);
- } catch (RemoteException e) {
- onError(e);
- return false;
- }
- }
-
private void onError(Exception e) {
Log.e(TAG, "Error while calling TrustManagerService", e);
}
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 1f3ff51..2d825fa 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -64,9 +64,7 @@
* <p>To get a {@link BluetoothAdapter} representing the local Bluetooth
* adapter, when running on JELLY_BEAN_MR1 and below, call the
* static {@link #getDefaultAdapter} method; when running on JELLY_BEAN_MR2 and
- * higher, retrieve it through
- * {@link android.content.Context#getSystemService} with
- * {@link android.content.Context#BLUETOOTH_SERVICE}.
+ * higher, call {@link BluetoothManager#getAdapter}.
* Fundamentally, this is your starting point for all
* Bluetooth actions. Once you have the local adapter, you can get a set of
* {@link BluetoothDevice} objects representing all paired devices with
diff --git a/core/java/android/content/RestrictionEntry.java b/core/java/android/content/RestrictionEntry.java
index ab049ec..0473475 100644
--- a/core/java/android/content/RestrictionEntry.java
+++ b/core/java/android/content/RestrictionEntry.java
@@ -456,7 +456,7 @@
if (o == this) return true;
if (!(o instanceof RestrictionEntry)) return false;
final RestrictionEntry other = (RestrictionEntry) o;
- if (mType != other.mType || mKey.equals(other.mKey)) {
+ if (mType != other.mType || !mKey.equals(other.mKey)) {
return false;
}
if (mCurrentValues == null && other.mCurrentValues == null
diff --git a/core/java/android/content/RestrictionsManager.java b/core/java/android/content/RestrictionsManager.java
index 1fac06e..a7744e7 100644
--- a/core/java/android/content/RestrictionsManager.java
+++ b/core/java/android/content/RestrictionsManager.java
@@ -677,7 +677,8 @@
* <table>
* <tr><th>RestrictionEntry</th><th>Bundle</th></tr>
* <tr><td>{@link RestrictionEntry#TYPE_BOOLEAN}</td><td>{@link Bundle#putBoolean}</td></tr>
- * <tr><td>{@link RestrictionEntry#TYPE_CHOICE}, {@link RestrictionEntry#TYPE_CHOICE}</td>
+ * <tr><td>{@link RestrictionEntry#TYPE_CHOICE},
+ * {@link RestrictionEntry#TYPE_MULTI_SELECT}</td>
* <td>{@link Bundle#putStringArray}</td></tr>
* <tr><td>{@link RestrictionEntry#TYPE_INTEGER}</td><td>{@link Bundle#putInt}</td></tr>
* <tr><td>{@link RestrictionEntry#TYPE_STRING}</td><td>{@link Bundle#putString}</td></tr>
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index 43cc63b..876fbf5 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -698,6 +698,8 @@
*/
public int lockTaskLaunchMode;
+ public InitialLayout initialLayout;
+
public ActivityInfo() {
}
@@ -763,9 +765,14 @@
}
pw.println(prefix + "resizeable=" + resizeable + " lockTaskLaunchMode="
+ lockTaskLaunchModeToString(lockTaskLaunchMode));
+ if (initialLayout != null) {
+ pw.println(prefix + "initialLayout=" + initialLayout.width + "|"
+ + initialLayout.widthFraction + ", " + initialLayout.height + "|"
+ + initialLayout.heightFraction + ", " + initialLayout.gravity);
+ }
super.dumpBack(pw, prefix);
}
-
+
public String toString() {
return "ActivityInfo{"
+ Integer.toHexString(System.identityHashCode(this))
@@ -793,6 +800,16 @@
dest.writeInt(maxRecents);
dest.writeInt(resizeable ? 1 : 0);
dest.writeInt(lockTaskLaunchMode);
+ if (initialLayout != null) {
+ dest.writeInt(1);
+ dest.writeInt(initialLayout.width);
+ dest.writeFloat(initialLayout.widthFraction);
+ dest.writeInt(initialLayout.height);
+ dest.writeFloat(initialLayout.heightFraction);
+ dest.writeInt(initialLayout.gravity);
+ } else {
+ dest.writeInt(0);
+ }
}
public static final Parcelable.Creator<ActivityInfo> CREATOR
@@ -822,5 +839,33 @@
maxRecents = source.readInt();
resizeable = (source.readInt() == 1);
lockTaskLaunchMode = source.readInt();
+ if (source.readInt() == 1) {
+ initialLayout = new InitialLayout(source);
+ }
+ }
+
+ public static final class InitialLayout {
+ public InitialLayout(int width, float widthFraction, int height, float heightFraction,
+ int gravity) {
+ this.width = width;
+ this.widthFraction = widthFraction;
+ this.height = height;
+ this.heightFraction = heightFraction;
+ this.gravity = gravity;
+ }
+
+ InitialLayout(Parcel source) {
+ width = source.readInt();
+ widthFraction = source.readFloat();
+ height = source.readInt();
+ heightFraction = source.readFloat();
+ gravity = source.readInt();
+ }
+
+ public final int width;
+ public final float widthFraction;
+ public final int height;
+ public final float heightFraction;
+ public final int gravity;
}
}
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 924df1b..6443667 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -50,6 +50,7 @@
import android.util.Pair;
import android.util.Slog;
import android.util.TypedValue;
+import android.view.Gravity;
import com.android.internal.R;
import com.android.internal.util.ArrayUtils;
@@ -3260,10 +3261,12 @@
owner.preferredActivityFilters.add(intent);
}
} else if (parser.getName().equals("meta-data")) {
- if ((a.metaData=parseMetaData(res, parser, attrs, a.metaData,
+ if ((a.metaData = parseMetaData(res, parser, attrs, a.metaData,
outError)) == null) {
return null;
}
+ } else if (!receiver && parser.getName().equals("initial-layout")) {
+ parseInitialLayout(res, attrs, a);
} else {
if (!RIGID_PARSER) {
Slog.w(TAG, "Problem in package " + mArchiveSourcePath + ":");
@@ -3296,6 +3299,43 @@
return a;
}
+ private void parseInitialLayout(Resources res, AttributeSet attrs, Activity a) {
+ TypedArray sw = res.obtainAttributes(attrs,
+ com.android.internal.R.styleable.AndroidManifestInitialLayout);
+ int width = -1;
+ float widthFraction = -1f;
+ int height = -1;
+ float heightFraction = -1f;
+ final int widthType = sw.getType(
+ com.android.internal.R.styleable.AndroidManifestInitialLayout_activity_width);
+ if (widthType == TypedValue.TYPE_FRACTION) {
+ widthFraction = sw.getFraction(
+ com.android.internal.R.styleable.AndroidManifestInitialLayout_activity_width,
+ 1, 1, -1);
+ } else if (widthType == TypedValue.TYPE_DIMENSION) {
+ width = sw.getDimensionPixelSize(
+ com.android.internal.R.styleable.AndroidManifestInitialLayout_activity_width,
+ -1);
+ }
+ final int heightType = sw.getType(
+ com.android.internal.R.styleable.AndroidManifestInitialLayout_activity_height);
+ if (heightType == TypedValue.TYPE_FRACTION) {
+ heightFraction = sw.getFraction(
+ com.android.internal.R.styleable.AndroidManifestInitialLayout_activity_height,
+ 1, 1, -1);
+ } else if (heightType == TypedValue.TYPE_DIMENSION) {
+ height = sw.getDimensionPixelSize(
+ com.android.internal.R.styleable.AndroidManifestInitialLayout_activity_height,
+ -1);
+ }
+ int gravity = sw.getInt(
+ com.android.internal.R.styleable.AndroidManifestInitialLayout_gravity,
+ Gravity.CENTER);
+ sw.recycle();
+ a.info.initialLayout = new ActivityInfo.InitialLayout(width, widthFraction,
+ height, heightFraction, gravity);
+ }
+
private Activity parseActivityAlias(Package owner, Resources res,
XmlPullParser parser, AttributeSet attrs, int flags, String[] outError)
throws XmlPullParserException, IOException {
diff --git a/core/java/android/content/pm/UserInfo.java b/core/java/android/content/pm/UserInfo.java
index cbd2f78..dfd0f7d 100644
--- a/core/java/android/content/pm/UserInfo.java
+++ b/core/java/android/content/pm/UserInfo.java
@@ -145,6 +145,17 @@
return (!hideSystemUser || id != UserHandle.USER_SYSTEM) && supportsSwitchTo();
}
+ /* @hide */
+ public boolean canHaveProfile() {
+ if (isManagedProfile() || isGuest() || isRestricted()) {
+ return false;
+ }
+ if (UserManager.isSplitSystemUser()) {
+ return id != UserHandle.USER_SYSTEM;
+ }
+ return id == UserHandle.USER_OWNER;
+ }
+
public UserInfo() {
}
diff --git a/core/java/android/hardware/camera2/params/OutputConfiguration.java b/core/java/android/hardware/camera2/params/OutputConfiguration.java
index 7aa9787..a04cdce 100644
--- a/core/java/android/hardware/camera2/params/OutputConfiguration.java
+++ b/core/java/android/hardware/camera2/params/OutputConfiguration.java
@@ -19,7 +19,9 @@
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.utils.HashCodeHelpers;
+import android.hardware.camera2.utils.SurfaceUtils;
import android.util.Log;
+import android.util.Size;
import android.view.Surface;
import android.os.Parcel;
import android.os.Parcelable;
@@ -66,9 +68,7 @@
*
*/
public OutputConfiguration(Surface surface) {
- checkNotNull(surface, "Surface must not be null");
- mSurface = surface;
- mRotation = ROTATION_0;
+ this(surface, ROTATION_0);
}
/**
@@ -94,6 +94,9 @@
checkArgumentInRange(rotation, ROTATION_0, ROTATION_270, "Rotation constant");
mSurface = surface;
mRotation = rotation;
+ mConfiguredSize = SurfaceUtils.getSurfaceSize(surface);
+ mConfiguredFormat = SurfaceUtils.getSurfaceFormat(surface);
+ mConfiguredDataspace = SurfaceUtils.getSurfaceDataspace(surface);
}
/**
@@ -106,6 +109,9 @@
checkArgumentInRange(rotation, ROTATION_0, ROTATION_270, "Rotation constant");
mSurface = surface;
mRotation = rotation;
+ mConfiguredSize = SurfaceUtils.getSurfaceSize(mSurface);
+ mConfiguredFormat = SurfaceUtils.getSurfaceFormat(mSurface);
+ mConfiguredDataspace = SurfaceUtils.getSurfaceDataspace(mSurface);
}
/**
@@ -163,8 +169,9 @@
/**
* Check if this {@link OutputConfiguration} is equal to another {@link OutputConfiguration}.
*
- * <p>Two output configurations are only equal if and only if the underlying surface and
- * all other configuration parameters are equal. </p>
+ * <p>Two output configurations are only equal if and only if the underlying surfaces, surface
+ * properties (width, height, format, dataspace) when the output configurations are created,
+ * and all other configuration parameters are equal. </p>
*
* @return {@code true} if the objects were equal, {@code false} otherwise
*/
@@ -176,7 +183,11 @@
return true;
} else if (obj instanceof OutputConfiguration) {
final OutputConfiguration other = (OutputConfiguration) obj;
- return (mSurface == other.mSurface && mRotation == other.mRotation);
+ return mSurface == other.mSurface &&
+ mRotation == other.mRotation &&
+ mConfiguredSize.equals(other.mConfiguredSize) &&
+ mConfiguredFormat == other.mConfiguredFormat &&
+ mConfiguredDataspace == other.mConfiguredDataspace;
}
return false;
}
@@ -192,4 +203,9 @@
private static final String TAG = "OutputConfiguration";
private final Surface mSurface;
private final int mRotation;
+
+ // The size, format, and dataspace of the surface when OutputConfiguration is created.
+ private final Size mConfiguredSize;
+ private final int mConfiguredFormat;
+ private final int mConfiguredDataspace;
}
diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java
index 061fad9..7cff11b 100644
--- a/core/java/android/hardware/fingerprint/FingerprintManager.java
+++ b/core/java/android/hardware/fingerprint/FingerprintManager.java
@@ -395,7 +395,7 @@
* Request authentication of a crypto object. This call warms up the fingerprint hardware
* and starts scanning for a fingerprint. It terminates when
* {@link AuthenticationCallback#onAuthenticationError(int, CharSequence)} or
- * {@link AuthenticationCallback#onAuthenticationSucceeded(AuthenticationResult) is called, at
+ * {@link AuthenticationCallback#onAuthenticationSucceeded(AuthenticationResult)} is called, at
* which point the object is no longer valid. The operation can be canceled by using the
* provided cancel object.
*
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
index a6d477f..3bd12c0 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/core/java/android/net/NetworkCapabilities.java
@@ -351,8 +351,12 @@
public void maybeMarkCapabilitiesRestricted() {
// If all the capabilities are typically provided by restricted networks, conclude that this
// network is restricted.
- if ((mNetworkCapabilities & ~(DEFAULT_CAPABILITIES | RESTRICTED_CAPABILITIES)) == 0)
+ if ((mNetworkCapabilities & ~(DEFAULT_CAPABILITIES | RESTRICTED_CAPABILITIES)) == 0 &&
+ // Must have at least some restricted capabilities, otherwise a request for an
+ // internet-less network will get marked restricted.
+ (mNetworkCapabilities & RESTRICTED_CAPABILITIES) != 0) {
removeCapability(NET_CAPABILITY_NOT_RESTRICTED);
+ }
}
/**
diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl
index 364c0eb..aeb5d45 100644
--- a/core/java/android/os/IUserManager.aidl
+++ b/core/java/android/os/IUserManager.aidl
@@ -43,7 +43,7 @@
UserInfo getPrimaryUser();
List<UserInfo> getUsers(boolean excludeDying);
List<UserInfo> getProfiles(int userHandle, boolean enabledOnly);
- boolean canAddMoreManagedProfiles();
+ boolean canAddMoreManagedProfiles(int userId);
UserInfo getProfileParent(int userHandle);
UserInfo getUserInfo(int userHandle);
long getUserCreationTime(int userHandle);
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index aea5123..849f5de 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -1024,9 +1024,9 @@
* @return true if more managed profiles can be added, false if limit has been reached.
* @hide
*/
- public boolean canAddMoreManagedProfiles() {
+ public boolean canAddMoreManagedProfiles(int userId) {
try {
- return mService.canAddMoreManagedProfiles();
+ return mService.canAddMoreManagedProfiles(userId);
} catch (RemoteException re) {
Log.w(TAG, "Could not check if we can add more managed profiles", re);
return false;
diff --git a/core/java/android/os/storage/VolumeInfo.java b/core/java/android/os/storage/VolumeInfo.java
index ef54d84..6888594 100644
--- a/core/java/android/os/storage/VolumeInfo.java
+++ b/core/java/android/os/storage/VolumeInfo.java
@@ -341,6 +341,7 @@
}
String description = null;
+ String derivedFsUuid = fsUuid;
long mtpReserveSize = 0;
long maxFileSize = 0;
int mtpStorageId = StorageVolume.STORAGE_ID_INVALID;
@@ -351,6 +352,7 @@
final VolumeInfo privateVol = storage.findPrivateForEmulated(this);
if (privateVol != null) {
description = storage.getBestVolumeDescription(privateVol);
+ derivedFsUuid = privateVol.fsUuid;
}
if (isPrimary()) {
@@ -393,7 +395,7 @@
return new StorageVolume(id, mtpStorageId, userPath, description, isPrimary(), removable,
emulated, mtpReserveSize, allowMassStorage, maxFileSize, new UserHandle(userId),
- fsUuid, envState);
+ derivedFsUuid, envState);
}
public static int buildStableMtpStorageId(String fsUuid) {
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java
index db19f7a..6310570 100644
--- a/core/java/android/service/notification/ZenModeConfig.java
+++ b/core/java/android/service/notification/ZenModeConfig.java
@@ -118,7 +118,7 @@
public boolean allowEvents = DEFAULT_ALLOW_EVENTS;
public int allowCallsFrom = DEFAULT_SOURCE;
public int allowMessagesFrom = DEFAULT_SOURCE;
- public int user = UserHandle.USER_OWNER;
+ public int user = UserHandle.USER_SYSTEM;
public ZenRule manualRule;
public ArrayMap<String, ZenRule> automaticRules = new ArrayMap<>();
diff --git a/core/java/android/text/TextUtils.java b/core/java/android/text/TextUtils.java
index 4d8a7d0..49cb8e2 100644
--- a/core/java/android/text/TextUtils.java
+++ b/core/java/android/text/TextUtils.java
@@ -462,7 +462,7 @@
/**
* Returns the length that the specified CharSequence would have if
- * spaces and control characters were trimmed from the start and end,
+ * spaces and ASCII control characters were trimmed from the start and end,
* as by {@link String#trim}.
*/
public static int getTrimmedLength(CharSequence s) {
@@ -505,7 +505,13 @@
return false;
}
- // XXX currently this only reverses chars, not spans
+ /*
+ * @deprecated
+ * Do not use. This function only reverses individual {@code char}s and not their associated
+ * spans. It doesn't support surrogate pairs (that correspond to non-BMP code points),
+ * combining sequences or conjuncts either.
+ */
+ @Deprecated
public static CharSequence getReverse(CharSequence source,
int start, int end) {
return new Reverser(source, start, end);
@@ -1470,8 +1476,9 @@
*/
public static boolean isDigitsOnly(CharSequence str) {
final int len = str.length();
- for (int i = 0; i < len; i++) {
- if (!Character.isDigit(str.charAt(i))) {
+ for (int cp, i = 0; i < len; i += Character.charCount(cp)) {
+ cp = Character.codePointAt(str, i);
+ if (!Character.isDigit(cp)) {
return false;
}
}
diff --git a/core/java/android/text/format/Formatter.java b/core/java/android/text/format/Formatter.java
index a53da09..9f5dfa6 100644
--- a/core/java/android/text/format/Formatter.java
+++ b/core/java/android/text/format/Formatter.java
@@ -98,7 +98,8 @@
/** {@hide} */
public static BytesResult formatBytes(Resources res, long sizeBytes, int flags) {
- float result = sizeBytes;
+ final boolean isNegative = (sizeBytes < 0);
+ float result = isNegative ? -sizeBytes : sizeBytes;
int suffix = com.android.internal.R.string.byteShort;
long mult = 1;
if (result > 900) {
@@ -154,9 +155,13 @@
roundFormat = "%.2f";
}
}
+
+ if (isNegative) {
+ result = -result;
+ }
final String roundedString = String.format(roundFormat, result);
- // Note this might overflow if result >= Long.MAX_VALUE / 100, but that's like 80PB so
+ // Note this might overflow if abs(result) >= Long.MAX_VALUE / 100, but that's like 80PB so
// it's okay (for now)...
final long roundedBytes =
(flags & FLAG_CALCULATE_ROUNDED) == 0 ? 0
diff --git a/core/java/android/util/LocaleList.java b/core/java/android/util/LocaleList.java
new file mode 100644
index 0000000..017735a
--- /dev/null
+++ b/core/java/android/util/LocaleList.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.util;
+
+import android.annotation.Nullable;
+
+import java.util.HashSet;
+import java.util.Locale;
+
+// TODO: We don't except too many LocaleLists to exist at the same time, and
+// we need access to the data at native level, so we should pass the data
+// down to the native level, create a mapt of every list seen there, take a
+// pointer back, and just keep that pointed in the Java-level object, so
+// things could be copied very quickly.
+
+/**
+ * LocaleList is an immutable list of Locales, typically used to keep an
+ * ordered user preferences for locales.
+ */
+public final class LocaleList {
+ private final Locale[] mList;
+ private static final Locale[] sEmptyList = new Locale[0];
+
+ public Locale get(int location) {
+ return location < mList.length ? mList[location] : null;
+ }
+
+ public Locale getPrimary() {
+ return mList.length == 0 ? null : get(0);
+ }
+
+ public boolean isEmpty() {
+ return mList.length == 0;
+ }
+
+ public int size() {
+ return mList.length;
+ }
+
+ public LocaleList() {
+ mList = sEmptyList;
+ }
+
+ /**
+ * @throws NullPointerException if any of the input locales is <code>null</code>.
+ * @throws IllegalArgumentException if any of the input locales repeat.
+ */
+ public LocaleList(@Nullable Locale[] list) {
+ if (list == null || list.length == 0) {
+ mList = sEmptyList;
+ } else {
+ final Locale[] localeList = new Locale[list.length];
+ final HashSet<Locale> seenLocales = new HashSet<Locale>();
+ for (int i = 0; i < list.length; ++i) {
+ final Locale l = list[i];
+ if (l == null) {
+ throw new NullPointerException();
+ } else if (seenLocales.contains(l)) {
+ throw new IllegalArgumentException();
+ } else {
+ seenLocales.add(l);
+ localeList[i] = (Locale) l.clone();
+ }
+ }
+ mList = localeList;
+ }
+ }
+}
diff --git a/core/java/android/view/AppTransitionAnimationSpec.aidl b/core/java/android/view/AppTransitionAnimationSpec.aidl
new file mode 100644
index 0000000..8388347
--- /dev/null
+++ b/core/java/android/view/AppTransitionAnimationSpec.aidl
@@ -0,0 +1,20 @@
+/*
+** Copyright 2015, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.view;
+
+/** @hide */
+parcelable AppTransitionAnimationSpec;
diff --git a/core/java/android/view/AppTransitionAnimationSpec.java b/core/java/android/view/AppTransitionAnimationSpec.java
new file mode 100644
index 0000000..c6e1989
--- /dev/null
+++ b/core/java/android/view/AppTransitionAnimationSpec.java
@@ -0,0 +1,61 @@
+package android.view;
+
+import android.graphics.Bitmap;
+import android.graphics.Rect;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Holds information about how the next app transition animation should be executed.
+ *
+ * This class is intended to be used with IWindowManager.overridePendingAppTransition* methods when
+ * simple arguments are not enough to describe the animation.
+ *
+ * @hide
+ */
+public class AppTransitionAnimationSpec implements Parcelable {
+ public final int taskId;
+ public final Bitmap bitmap;
+ public final Rect rect;
+
+ public AppTransitionAnimationSpec(int taskId, Bitmap bitmap, Rect rect) {
+ this.taskId = taskId;
+ this.bitmap = bitmap;
+ this.rect = rect;
+ }
+
+ public AppTransitionAnimationSpec(Parcel in) {
+ taskId = in.readInt();
+ bitmap = in.readParcelable(null);
+ rect = in.readParcelable(null);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(taskId);
+ dest.writeParcelable(bitmap, 0 /* flags */);
+ dest.writeParcelable(rect, 0 /* flags */);
+
+ }
+
+ public static final Parcelable.Creator<AppTransitionAnimationSpec> CREATOR
+ = new Parcelable.Creator<AppTransitionAnimationSpec>() {
+ public AppTransitionAnimationSpec createFromParcel(Parcel in) {
+ return new AppTransitionAnimationSpec(in);
+ }
+
+ public AppTransitionAnimationSpec[] newArray(int size) {
+ return new AppTransitionAnimationSpec[size];
+ }
+ };
+
+ @Override
+ public String toString() {
+ return "{taskId: " + taskId + ", bitmap: " + bitmap + ", rect: " + rect + "}";
+ }
+}
diff --git a/core/java/android/view/DisplayListCanvas.java b/core/java/android/view/DisplayListCanvas.java
index 948cec7..080ed9a 100644
--- a/core/java/android/view/DisplayListCanvas.java
+++ b/core/java/android/view/DisplayListCanvas.java
@@ -20,12 +20,7 @@
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.CanvasProperty;
-import android.graphics.NinePatch;
import android.graphics.Paint;
-import android.graphics.Path;
-import android.graphics.Picture;
-import android.graphics.Rect;
-import android.graphics.RectF;
import android.util.Pools.SynchronizedPool;
/**
@@ -206,16 +201,12 @@
* Draws the specified layer onto this canvas.
*
* @param layer The layer to composite on this canvas
- * @param x The left coordinate of the layer
- * @param y The top coordinate of the layer
- * @param paint The paint used to draw the layer
*/
- void drawHardwareLayer(HardwareLayer layer, float x, float y, Paint paint) {
- layer.setLayerPaint(paint);
- nDrawLayer(mNativeCanvasWrapper, layer.getLayerHandle(), x, y);
+ void drawHardwareLayer(HardwareLayer layer) {
+ nDrawLayer(mNativeCanvasWrapper, layer.getLayerHandle());
}
- private static native void nDrawLayer(long renderer, long layer, float x, float y);
+ private static native void nDrawLayer(long renderer, long layer);
///////////////////////////////////////////////////////////////////////////
// Drawing
diff --git a/core/java/android/view/HardwareLayer.java b/core/java/android/view/HardwareLayer.java
index 65ae8a6..692ca7b 100644
--- a/core/java/android/view/HardwareLayer.java
+++ b/core/java/android/view/HardwareLayer.java
@@ -150,8 +150,4 @@
private static native void nSetSurfaceTexture(long layerUpdater,
SurfaceTexture surface, boolean isAlreadyAttached);
private static native void nUpdateSurfaceTexture(long layerUpdater);
- private static native void nUpdateRenderLayer(long layerUpdater, long displayList,
- int left, int top, int right, int bottom);
-
- private static native int nGetTexName(long layerUpdater);
}
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 0a4b982..f86adfe 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -39,6 +39,7 @@
import android.view.InputChannel;
import android.view.InputDevice;
import android.view.IInputFilter;
+import android.view.AppTransitionAnimationSpec;
import android.view.WindowContentFrameStats;
/**
@@ -127,6 +128,16 @@
void overridePendingAppTransitionAspectScaledThumb(in Bitmap srcThumb, int startX,
int startY, int targetWidth, int targetHeight, IRemoteCallback startedCallback,
boolean scaleUp);
+ /**
+ * Overrides animation for app transition that exits from an application to a multi-window
+ * environment and allows specifying transition animation parameters for each window.
+ *
+ * @param specs Array of transition animation descriptions for entering windows.
+ *
+ * @hide
+ */
+ void overridePendingAppTransitionMultiThumb(in AppTransitionAnimationSpec[] specs,
+ IRemoteCallback startedCallback, boolean scaleUp);
void overridePendingAppTransitionInPlace(String packageName, int anim);
void executeAppTransition();
void setAppStartingWindow(IBinder token, String pkg, int theme,
diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java
index cdc196e..6b60be9 100644
--- a/core/java/android/view/TextureView.java
+++ b/core/java/android/view/TextureView.java
@@ -23,6 +23,7 @@
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.SurfaceTexture;
+import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
@@ -294,6 +295,22 @@
public void buildLayer() {
}
+ @Override
+ public void setForeground(Drawable foreground) {
+ if (foreground != null) {
+ throw new UnsupportedOperationException(
+ "TextureView doesn't support displaying a foreground drawable");
+ }
+ }
+
+ @Override
+ public void setBackgroundDrawable(Drawable background) {
+ if (background != null) {
+ throw new UnsupportedOperationException(
+ "TextureView doesn't support displaying a background drawable");
+ }
+ }
+
/**
* Subclasses of TextureView cannot do their own rendering
* with the {@link Canvas} object.
@@ -302,11 +319,25 @@
*/
@Override
public final void draw(Canvas canvas) {
- // NOTE: Maintain this carefully (see View.java)
+ // NOTE: Maintain this carefully (see View#draw)
mPrivateFlags = (mPrivateFlags & ~PFLAG_DIRTY_MASK) | PFLAG_DRAWN;
- applyUpdate();
- applyTransformMatrix();
+ /* Simplify drawing to guarantee the layer is the only thing drawn - so e.g. no background,
+ scrolling, or fading edges. This guarantees all drawing is in the layer, so drawing
+ properties (alpha, layer paint) affect all of the content of a TextureView. */
+
+ if (canvas.isHardwareAccelerated()) {
+ DisplayListCanvas displayListCanvas = (DisplayListCanvas) canvas;
+
+ HardwareLayer layer = getHardwareLayer();
+ if (layer != null) {
+ applyUpdate();
+ applyTransformMatrix();
+
+ mLayer.setLayerPaint(mLayerPaint); // ensure layer paint is up to date
+ displayListCanvas.drawHardwareLayer(layer);
+ }
+ }
}
/**
@@ -342,12 +373,7 @@
invalidate(true);
}
- @Override
HardwareLayer getHardwareLayer() {
- // NOTE: Maintain these two lines very carefully (see View.java)
- mPrivateFlags |= PFLAG_DRAWN | PFLAG_DRAWING_CACHE_VALID;
- mPrivateFlags &= ~PFLAG_DIRTY_MASK;
-
if (mLayer == null) {
if (mAttachInfo == null || mAttachInfo.mHardwareRenderer == null) {
return null;
@@ -385,9 +411,6 @@
mSurface.setDefaultBufferSize(getWidth(), getHeight());
}
- applyUpdate();
- applyTransformMatrix();
-
return mLayer;
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index a492518..b17f88f 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -15002,16 +15002,6 @@
}
/**
- * If this View draws with a HardwareLayer, returns it.
- * Otherwise returns null
- *
- * TODO: Only TextureView uses this, can we eliminate it?
- */
- HardwareLayer getHardwareLayer() {
- return null;
- }
-
- /**
* Destroys all hardware rendering resources. This method is invoked
* when the system needs to reclaim resources. Upon execution of this
* method, you should free any OpenGL resources created by the view.
@@ -15161,10 +15151,7 @@
canvas.setHighContrastText(mAttachInfo.mHighContrastText);
try {
- final HardwareLayer layer = getHardwareLayer();
- if (layer != null && layer.isValid()) {
- canvas.drawHardwareLayer(layer, 0, 0, mLayerPaint);
- } else if (layerType == LAYER_TYPE_SOFTWARE) {
+ if (layerType == LAYER_TYPE_SOFTWARE) {
buildDrawingCache(true);
Bitmap cache = getDrawingCache(true);
if (cache != null) {
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index d9faece..5fc8c7a 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -220,7 +220,7 @@
result.putExtras(replExtras);
}
}
- if (aInfo.name.equals(IntentForwarderActivity.FORWARD_INTENT_TO_USER_OWNER)
+ if (aInfo.name.equals(IntentForwarderActivity.FORWARD_INTENT_TO_PARENT)
|| aInfo.name.equals(IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE)) {
result = Intent.createChooser(result,
getIntent().getCharSequenceExtra(Intent.EXTRA_TITLE));
diff --git a/core/java/com/android/internal/app/IntentForwarderActivity.java b/core/java/com/android/internal/app/IntentForwarderActivity.java
index 39b66aa..dbec740 100644
--- a/core/java/com/android/internal/app/IntentForwarderActivity.java
+++ b/core/java/com/android/internal/app/IntentForwarderActivity.java
@@ -45,8 +45,8 @@
public static String TAG = "IntentForwarderActivity";
- public static String FORWARD_INTENT_TO_USER_OWNER
- = "com.android.internal.app.ForwardIntentToUserOwner";
+ public static String FORWARD_INTENT_TO_PARENT
+ = "com.android.internal.app.ForwardIntentToParent";
public static String FORWARD_INTENT_TO_MANAGED_PROFILE
= "com.android.internal.app.ForwardIntentToManagedProfile";
@@ -60,9 +60,9 @@
final int targetUserId;
final int userMessageId;
- if (className.equals(FORWARD_INTENT_TO_USER_OWNER)) {
+ if (className.equals(FORWARD_INTENT_TO_PARENT)) {
userMessageId = com.android.internal.R.string.forward_intent_to_owner;
- targetUserId = UserHandle.USER_OWNER;
+ targetUserId = getProfileParent();
} else if (className.equals(FORWARD_INTENT_TO_MANAGED_PROFILE)) {
userMessageId = com.android.internal.R.string.forward_intent_to_work;
targetUserId = getManagedProfile();
@@ -72,7 +72,7 @@
targetUserId = UserHandle.USER_NULL;
}
if (targetUserId == UserHandle.USER_NULL) {
- // This covers the case where there is no managed profile.
+ // This covers the case where there is no parent / managed profile.
finish();
return;
}
@@ -168,7 +168,7 @@
*/
private int getManagedProfile() {
UserManager userManager = (UserManager) getSystemService(Context.USER_SERVICE);
- List<UserInfo> relatedUsers = userManager.getProfiles(UserHandle.USER_OWNER);
+ List<UserInfo> relatedUsers = userManager.getProfiles(UserHandle.myUserId());
for (UserInfo userInfo : relatedUsers) {
if (userInfo.isManagedProfile()) return userInfo.id;
}
@@ -176,4 +176,19 @@
+ " has been called, but there is no managed profile");
return UserHandle.USER_NULL;
}
+
+ /**
+ * Returns the userId of the profile parent or UserHandle.USER_NULL if there is
+ * no parent.
+ */
+ private int getProfileParent() {
+ UserManager userManager = (UserManager) getSystemService(Context.USER_SERVICE);
+ UserInfo parent = userManager.getProfileParent(UserHandle.myUserId());
+ if (parent == null) {
+ Slog.wtf(TAG, FORWARD_INTENT_TO_PARENT
+ + " has been called, but there is no parent");
+ return UserHandle.USER_NULL;
+ }
+ return parent.id;
+ }
}
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index be26c24..55e23b1 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -20,6 +20,7 @@
import static android.app.ActivityManager.FREEFORM_WORKSPACE_STACK_ID;
import static android.app.ActivityManager.FULLSCREEN_WORKSPACE_STACK_ID;
import static android.app.ActivityManager.HOME_STACK_ID;
+import static android.app.ActivityManager.INVALID_STACK_ID;
import static android.view.View.MeasureSpec.AT_MOST;
import static android.view.View.MeasureSpec.EXACTLY;
import static android.view.View.MeasureSpec.getMode;
@@ -5250,7 +5251,7 @@
* @return Returns the workspace stack id which contains this window.
**/
private int getWorkspaceId() {
- int workspaceId = FULLSCREEN_WORKSPACE_STACK_ID;
+ int workspaceId = INVALID_STACK_ID;
WindowControllerCallback callback = getWindowControllerCallback();
if (callback != null) {
try {
@@ -5259,6 +5260,9 @@
Log.e(TAG, "Failed to get the workspace ID of a PhoneWindow.");
}
}
+ if (workspaceId == INVALID_STACK_ID) {
+ return FULLSCREEN_WORKSPACE_STACK_ID;
+ }
return workspaceId;
}
diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl
index c1645c3..1e41e63 100644
--- a/core/java/com/android/internal/statusbar/IStatusBar.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl
@@ -46,6 +46,8 @@
void cancelPreloadRecentApps();
void showScreenPinningRequest();
+ void showKeyboardShortcutsMenu();
+
/**
* Notifies the status bar that an app transition is pending to delay applying some flags with
* visual impact until {@link #appTransitionReady} is called.
diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
index 7db2cc9..6c957be 100644
--- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
@@ -68,6 +68,8 @@
void preloadRecentApps();
void cancelPreloadRecentApps();
+ void showKeyboardShortcutsMenu();
+
/**
* Notifies the status bar that an app transition is pending to delay applying some flags with
* visual impact until {@link #appTransitionReady} is called.
diff --git a/core/java/com/android/internal/widget/ILockSettings.aidl b/core/java/com/android/internal/widget/ILockSettings.aidl
index dfb7c50..4e4552d 100644
--- a/core/java/com/android/internal/widget/ILockSettings.aidl
+++ b/core/java/com/android/internal/widget/ILockSettings.aidl
@@ -16,6 +16,7 @@
package com.android.internal.widget;
+import android.app.trust.IStrongAuthTracker;
import com.android.internal.widget.VerifyCredentialResponse;
/** {@hide} */
@@ -35,4 +36,7 @@
boolean checkVoldPassword(int userId);
boolean havePattern(int userId);
boolean havePassword(int userId);
+ void registerStrongAuthTracker(in IStrongAuthTracker tracker);
+ void unregisterStrongAuthTracker(in IStrongAuthTracker tracker);
+ void requireStrongAuth(int strongAuthReason, int userId);
}
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index ca184d1..1995694 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -16,19 +16,19 @@
package com.android.internal.widget;
-import android.Manifest;
+import android.annotation.IntDef;
import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
import android.app.admin.DevicePolicyManager;
+import android.app.trust.IStrongAuthTracker;
import android.app.trust.TrustManager;
-import android.bluetooth.BluetoothClass;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
-import android.content.pm.PackageManager;
import android.os.AsyncTask;
+import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
+import android.os.Message;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
@@ -39,9 +39,12 @@
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
+import android.util.SparseIntArray;
import com.google.android.collect.Lists;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
@@ -229,7 +232,7 @@
public void reportFailedPasswordAttempt(int userId) {
getDevicePolicyManager().reportFailedPasswordAttempt(userId);
getTrustManager().reportUnlockAttempt(false /* authenticated */, userId);
- getTrustManager().reportRequireCredentialEntry(userId);
+ requireCredentialEntry(userId);
}
public void reportSuccessfulPasswordAttempt(int userId) {
@@ -1168,10 +1171,32 @@
}
/**
- * @see android.app.trust.TrustManager#reportRequireCredentialEntry(int)
+ * Disable trust until credentials have been entered for user {@param userId}.
+ *
+ * Requires the {@link android.Manifest.permission#ACCESS_KEYGUARD_SECURE_STORAGE} permission.
+ *
+ * @param userId either an explicit user id or {@link android.os.UserHandle#USER_ALL}
*/
public void requireCredentialEntry(int userId) {
- getTrustManager().reportRequireCredentialEntry(userId);
+ requireStrongAuth(StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_USER_REQUEST, userId);
+ }
+
+ /**
+ * Requests strong authentication for user {@param userId}.
+ *
+ * Requires the {@link android.Manifest.permission#ACCESS_KEYGUARD_SECURE_STORAGE} permission.
+ *
+ * @param strongAuthReason a combination of {@link StrongAuthTracker.StrongAuthFlags} indicating
+ * the reason for and the strength of the requested authentication.
+ * @param userId either an explicit user id or {@link android.os.UserHandle#USER_ALL}
+ */
+ public void requireStrongAuth(@StrongAuthTracker.StrongAuthFlags int strongAuthReason,
+ int userId) {
+ try {
+ getLockSettings().requireStrongAuth(strongAuthReason, userId);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error while requesting strong auth: " + e);
+ }
}
private void onAfterChangingPassword(int userHandle) {
@@ -1209,4 +1234,147 @@
throw new IllegalStateException("should not be called from the main thread.");
}
}
+
+ public void registerStrongAuthTracker(final StrongAuthTracker strongAuthTracker) {
+ try {
+ getLockSettings().registerStrongAuthTracker(strongAuthTracker.mStub);
+ } catch (RemoteException e) {
+ throw new RuntimeException("Could not register StrongAuthTracker");
+ }
+ }
+
+ public void unregisterStrongAuthTracker(final StrongAuthTracker strongAuthTracker) {
+ try {
+ getLockSettings().unregisterStrongAuthTracker(strongAuthTracker.mStub);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Could not unregister StrongAuthTracker", e);
+ }
+ }
+
+ /**
+ * Tracks the global strong authentication state.
+ */
+ public static class StrongAuthTracker {
+
+ @IntDef(flag = true,
+ value = { STRONG_AUTH_NOT_REQUIRED,
+ STRONG_AUTH_REQUIRED_AFTER_BOOT,
+ STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW,
+ SOME_AUTH_REQUIRED_AFTER_USER_REQUEST})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface StrongAuthFlags {}
+
+ /**
+ * Strong authentication is not required.
+ */
+ public static final int STRONG_AUTH_NOT_REQUIRED = 0x0;
+
+ /**
+ * Strong authentication is required because the user has not authenticated since boot.
+ */
+ public static final int STRONG_AUTH_REQUIRED_AFTER_BOOT = 0x1;
+
+ /**
+ * Strong authentication is required because a device admin has requested it.
+ */
+ public static final int STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW = 0x2;
+
+ /**
+ * Some authentication is required because the user has temporarily disabled trust.
+ */
+ public static final int SOME_AUTH_REQUIRED_AFTER_USER_REQUEST = 0x4;
+
+ public static final int DEFAULT = STRONG_AUTH_REQUIRED_AFTER_BOOT;
+ private static final int ALLOWING_FINGERPRINT = SOME_AUTH_REQUIRED_AFTER_USER_REQUEST;
+
+ final SparseIntArray mStrongAuthRequiredForUser = new SparseIntArray();
+
+ private final H mHandler;
+
+ public StrongAuthTracker() {
+ this(Looper.myLooper());
+ }
+
+ /**
+ * @param looper the looper on whose thread calls to {@link #onStrongAuthRequiredChanged}
+ * will be scheduled.
+ */
+ public StrongAuthTracker(Looper looper) {
+ mHandler = new H(looper);
+ }
+
+ /**
+ * Returns {@link #STRONG_AUTH_NOT_REQUIRED} if strong authentication is not required,
+ * otherwise returns a combination of {@link StrongAuthFlags} indicating why strong
+ * authentication is required.
+ *
+ * @param userId the user for whom the state is queried.
+ */
+ public @StrongAuthFlags int getStrongAuthForUser(int userId) {
+ return mStrongAuthRequiredForUser.get(userId, DEFAULT);
+ }
+
+ /**
+ * @return true if unlocking with trust alone is allowed for {@param userId} by the current
+ * strong authentication requirements.
+ */
+ public boolean isTrustAllowedForUser(int userId) {
+ return getStrongAuthForUser(userId) == STRONG_AUTH_NOT_REQUIRED;
+ }
+
+ /**
+ * @return true if unlocking with fingerprint alone is allowed for {@param userId} by the
+ * current strong authentication requirements.
+ */
+ public boolean isFingerprintAllowedForUser(int userId) {
+ return (getStrongAuthForUser(userId) & ~ALLOWING_FINGERPRINT) == 0;
+ }
+
+ /**
+ * Called when the strong authentication requirements for {@param userId} changed.
+ */
+ public void onStrongAuthRequiredChanged(int userId) {
+ }
+
+ void handleStrongAuthRequiredChanged(@StrongAuthFlags int strongAuthFlags,
+ int userId) {
+
+ int oldValue = getStrongAuthForUser(userId);
+ if (strongAuthFlags != oldValue) {
+ if (strongAuthFlags == DEFAULT) {
+ mStrongAuthRequiredForUser.delete(userId);
+ } else {
+ mStrongAuthRequiredForUser.put(userId, strongAuthFlags);
+ }
+ onStrongAuthRequiredChanged(userId);
+ }
+ }
+
+
+ final IStrongAuthTracker.Stub mStub = new IStrongAuthTracker.Stub() {
+ @Override
+ public void onStrongAuthRequiredChanged(@StrongAuthFlags int strongAuthFlags,
+ int userId) {
+ mHandler.obtainMessage(H.MSG_ON_STRONG_AUTH_REQUIRED_CHANGED,
+ strongAuthFlags, userId).sendToTarget();
+ }
+ };
+
+ private class H extends Handler {
+ static final int MSG_ON_STRONG_AUTH_REQUIRED_CHANGED = 1;
+
+ public H(Looper looper) {
+ super(looper);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_ON_STRONG_AUTH_REQUIRED_CHANGED:
+ handleStrongAuthRequiredChanged(msg.arg1, msg.arg2);
+ break;
+ }
+ }
+ };
+ }
}
diff --git a/core/java/com/android/internal/widget/NonClientDecorView.java b/core/java/com/android/internal/widget/NonClientDecorView.java
index 05711b5..92812f8 100644
--- a/core/java/com/android/internal/widget/NonClientDecorView.java
+++ b/core/java/com/android/internal/widget/NonClientDecorView.java
@@ -20,6 +20,7 @@
import android.graphics.Rect;
import android.os.RemoteException;
import android.util.AttributeSet;
+import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;
import android.view.ViewGroup;
@@ -63,18 +64,31 @@
private final int DECOR_SHADOW_FOCUSED_HEIGHT_IN_DIP = 20;
// The height of a window which has not in DIP.
private final int DECOR_SHADOW_UNFOCUSED_HEIGHT_IN_DIP = 5;
-
private PhoneWindow mOwner = null;
- boolean mWindowHasShadow = false;
- boolean mShowDecor = false;
+ private boolean mWindowHasShadow = false;
+ private boolean mShowDecor = false;
+
+ // True if the window is being dragged.
+ private boolean mDragging = false;
+
+ // The bounds of the window and the absolute mouse pointer coordinates from before we started to
+ // drag the window. They will be used to determine the next window position.
+ private final Rect mWindowOriginalBounds = new Rect();
+ private float mStartDragX;
+ private float mStartDragY;
+ // True when the left mouse button got released while dragging.
+ private boolean mLeftMouseButtonReleased;
+
+ // Avoiding re-creation of Rect's by keeping a temporary window drag bound.
+ private final Rect mWindowDragBounds = new Rect();
// The current focus state of the window for updating the window elevation.
- boolean mWindowHasFocus = true;
+ private boolean mWindowHasFocus = true;
// Cludge to address b/22668382: Set the shadow size to the maximum so that the layer
// size calculation takes the shadow size into account. We set the elevation currently
// to max until the first layout command has been executed.
- boolean mAllowUpdateElevation = false;
+ private boolean mAllowUpdateElevation = false;
public NonClientDecorView(Context context) {
super(context);
@@ -103,6 +117,62 @@
findViewById(R.id.close_window).setOnClickListener(this);
}
+ @Override
+ public boolean onTouchEvent(MotionEvent e) {
+ // Note: There are no mixed events. When a new device gets used (e.g. 1. Mouse, 2. touch)
+ // the old input device events get cancelled first. So no need to remember the kind of
+ // input device we are listening to.
+ switch (e.getActionMasked()) {
+ case MotionEvent.ACTION_DOWN:
+ // A drag action is started if we aren't dragging already and the starting event is
+ // either a left mouse button or any other input device.
+ if (!mDragging &&
+ (e.getToolType(e.getActionIndex()) != MotionEvent.TOOL_TYPE_MOUSE ||
+ (e.getButtonState() & MotionEvent.BUTTON_PRIMARY) != 0)) {
+ mDragging = true;
+ mWindowOriginalBounds.set(getActivityBounds());
+ mLeftMouseButtonReleased = false;
+ mStartDragX = e.getRawX();
+ mStartDragY = e.getRawY();
+ }
+ break;
+
+ case MotionEvent.ACTION_MOVE:
+ if (mDragging && !mLeftMouseButtonReleased) {
+ if (e.getToolType(e.getActionIndex()) == MotionEvent.TOOL_TYPE_MOUSE &&
+ (e.getButtonState() & MotionEvent.BUTTON_PRIMARY) == 0) {
+ // There is no separate mouse button up call and if the user mixes mouse
+ // button drag actions, we stop dragging once he releases the button.
+ mLeftMouseButtonReleased = true;
+ break;
+ }
+ mWindowDragBounds.set(mWindowOriginalBounds);
+ mWindowDragBounds.offset(Math.round(e.getRawX() - mStartDragX),
+ Math.round(e.getRawY() - mStartDragY));
+ setActivityBounds(mWindowDragBounds);
+ }
+ break;
+
+ case MotionEvent.ACTION_UP:
+ if (mDragging) {
+ // Since the window is already where it should be we don't have to do anything
+ // special at this time.
+ mDragging = false;
+ return true;
+ }
+ break;
+
+ case MotionEvent.ACTION_CANCEL:
+ if (mDragging) {
+ mDragging = false;
+ setActivityBounds(mWindowOriginalBounds);
+ return true;
+ }
+ break;
+ }
+ return mDragging;
+ }
+
/**
* The phone window configuration has changed and the decor needs to be updated.
* @param showDecor True if the decor should be shown.
diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp
index c66cdfe..988d13a 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -112,15 +112,15 @@
}
static jlong init(JNIEnv* env, jobject clazz) {
- SK_COMPILE_ASSERT(1 << 0 == SkPaint::kAntiAlias_Flag, paint_flags_mismatch);
- SK_COMPILE_ASSERT(1 << 2 == SkPaint::kDither_Flag, paint_flags_mismatch);
- SK_COMPILE_ASSERT(1 << 3 == SkPaint::kUnderlineText_Flag, paint_flags_mismatch);
- SK_COMPILE_ASSERT(1 << 4 == SkPaint::kStrikeThruText_Flag, paint_flags_mismatch);
- SK_COMPILE_ASSERT(1 << 5 == SkPaint::kFakeBoldText_Flag, paint_flags_mismatch);
- SK_COMPILE_ASSERT(1 << 6 == SkPaint::kLinearText_Flag, paint_flags_mismatch);
- SK_COMPILE_ASSERT(1 << 7 == SkPaint::kSubpixelText_Flag, paint_flags_mismatch);
- SK_COMPILE_ASSERT(1 << 8 == SkPaint::kDevKernText_Flag, paint_flags_mismatch);
- SK_COMPILE_ASSERT(1 << 10 == SkPaint::kEmbeddedBitmapText_Flag, paint_flags_mismatch);
+ static_assert(1 << 0 == SkPaint::kAntiAlias_Flag, "paint_flags_mismatch");
+ static_assert(1 << 2 == SkPaint::kDither_Flag, "paint_flags_mismatch");
+ static_assert(1 << 3 == SkPaint::kUnderlineText_Flag, "paint_flags_mismatch");
+ static_assert(1 << 4 == SkPaint::kStrikeThruText_Flag, "paint_flags_mismatch");
+ static_assert(1 << 5 == SkPaint::kFakeBoldText_Flag, "paint_flags_mismatch");
+ static_assert(1 << 6 == SkPaint::kLinearText_Flag, "paint_flags_mismatch");
+ static_assert(1 << 7 == SkPaint::kSubpixelText_Flag, "paint_flags_mismatch");
+ static_assert(1 << 8 == SkPaint::kDevKernText_Flag, "paint_flags_mismatch");
+ static_assert(1 << 10 == SkPaint::kEmbeddedBitmapText_Flag, "paint_flags_mismatch");
Paint* obj = new Paint();
defaultSettingsForAndroid(obj);
diff --git a/core/jni/android/graphics/Path.cpp b/core/jni/android/graphics/Path.cpp
index f7b5dc2..dbd7c89 100644
--- a/core/jni/android/graphics/Path.cpp
+++ b/core/jni/android/graphics/Path.cpp
@@ -519,6 +519,9 @@
int register_android_graphics_Path(JNIEnv* env) {
return RegisterMethodsOrDie(env, "android/graphics/Path", methods, NELEM(methods));
+
+ static_assert(0 == SkPath::kCW_Direction, "direction_mismatch");
+ static_assert(1 == SkPath::kCCW_Direction, "direction_mismatch");
}
}
diff --git a/core/jni/android/graphics/PorterDuff.cpp b/core/jni/android/graphics/PorterDuff.cpp
index d65864d..fed90a5 100644
--- a/core/jni/android/graphics/PorterDuff.cpp
+++ b/core/jni/android/graphics/PorterDuff.cpp
@@ -33,29 +33,29 @@
static jlong CreateXfermode(JNIEnv* env, jobject, jint modeHandle) {
// validate that the Java enum values match our expectations
- SK_COMPILE_ASSERT(0 == SkXfermode::kClear_Mode, xfermode_mismatch);
- SK_COMPILE_ASSERT(1 == SkXfermode::kSrc_Mode, xfermode_mismatch);
- SK_COMPILE_ASSERT(2 == SkXfermode::kDst_Mode, xfermode_mismatch);
- SK_COMPILE_ASSERT(3 == SkXfermode::kSrcOver_Mode, xfermode_mismatch);
- SK_COMPILE_ASSERT(4 == SkXfermode::kDstOver_Mode, xfermode_mismatch);
- SK_COMPILE_ASSERT(5 == SkXfermode::kSrcIn_Mode, xfermode_mismatch);
- SK_COMPILE_ASSERT(6 == SkXfermode::kDstIn_Mode, xfermode_mismatch);
- SK_COMPILE_ASSERT(7 == SkXfermode::kSrcOut_Mode, xfermode_mismatch);
- SK_COMPILE_ASSERT(8 == SkXfermode::kDstOut_Mode, xfermode_mismatch);
- SK_COMPILE_ASSERT(9 == SkXfermode::kSrcATop_Mode, xfermode_mismatch);
- SK_COMPILE_ASSERT(10 == SkXfermode::kDstATop_Mode, xfermode_mismatch);
- SK_COMPILE_ASSERT(11 == SkXfermode::kXor_Mode, xfermode_mismatch);
- SK_COMPILE_ASSERT(16 == SkXfermode::kDarken_Mode, xfermode_mismatch);
- SK_COMPILE_ASSERT(17 == SkXfermode::kLighten_Mode, xfermode_mismatch);
- SK_COMPILE_ASSERT(13 == SkXfermode::kModulate_Mode, xfermode_mismatch);
- SK_COMPILE_ASSERT(14 == SkXfermode::kScreen_Mode, xfermode_mismatch);
- SK_COMPILE_ASSERT(12 == SkXfermode::kPlus_Mode, xfermode_mismatch);
- SK_COMPILE_ASSERT(15 == SkXfermode::kOverlay_Mode, xfermode_mismatch);
-
+ static_assert(0 == SkXfermode::kClear_Mode, "xfermode_mismatch");
+ static_assert(1 == SkXfermode::kSrc_Mode, "xfermode_mismatch");
+ static_assert(2 == SkXfermode::kDst_Mode, "xfermode_mismatch");
+ static_assert(3 == SkXfermode::kSrcOver_Mode, "xfermode_mismatch");
+ static_assert(4 == SkXfermode::kDstOver_Mode, "xfermode_mismatch");
+ static_assert(5 == SkXfermode::kSrcIn_Mode, "xfermode_mismatch");
+ static_assert(6 == SkXfermode::kDstIn_Mode, "xfermode_mismatch");
+ static_assert(7 == SkXfermode::kSrcOut_Mode, "xfermode_mismatch");
+ static_assert(8 == SkXfermode::kDstOut_Mode, "xfermode_mismatch");
+ static_assert(9 == SkXfermode::kSrcATop_Mode, "xfermode_mismatch");
+ static_assert(10 == SkXfermode::kDstATop_Mode, "xfermode_mismatch");
+ static_assert(11 == SkXfermode::kXor_Mode, "xfermode_mismatch");
+ static_assert(16 == SkXfermode::kDarken_Mode, "xfermode_mismatch");
+ static_assert(17 == SkXfermode::kLighten_Mode, "xfermode_mismatch");
+ static_assert(13 == SkXfermode::kModulate_Mode, "xfermode_mismatch");
+ static_assert(14 == SkXfermode::kScreen_Mode, "xfermode_mismatch");
+ static_assert(12 == SkXfermode::kPlus_Mode, "xfermode_mismatch");
+ static_assert(15 == SkXfermode::kOverlay_Mode, "xfermode_mismatch");
+
SkXfermode::Mode mode = static_cast<SkXfermode::Mode>(modeHandle);
return reinterpret_cast<jlong>(SkXfermode::Create(mode));
}
-
+
};
static JNINativeMethod methods[] = {
diff --git a/core/jni/android_view_DisplayListCanvas.cpp b/core/jni/android_view_DisplayListCanvas.cpp
index 3833325..460c1a1 100644
--- a/core/jni/android_view_DisplayListCanvas.cpp
+++ b/core/jni/android_view_DisplayListCanvas.cpp
@@ -40,18 +40,14 @@
using namespace uirenderer;
-static struct {
- jmethodID set;
-} gRectClassInfo;
-
// ----------------------------------------------------------------------------
// Setup
// ----------------------------------------------------------------------------
static void android_view_DisplayListCanvas_insertReorderBarrier(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jboolean reorderEnable) {
- DisplayListCanvas* renderer = reinterpret_cast<DisplayListCanvas*>(rendererPtr);
- renderer->insertReorderBarrier(reorderEnable);
+ jlong canvasPtr, jboolean reorderEnable) {
+ DisplayListCanvas* canvas = reinterpret_cast<DisplayListCanvas*>(canvasPtr);
+ canvas->insertReorderBarrier(reorderEnable);
}
// ----------------------------------------------------------------------------
@@ -59,10 +55,10 @@
// ----------------------------------------------------------------------------
static void android_view_DisplayListCanvas_callDrawGLFunction(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jlong functorPtr) {
- DisplayListCanvas* renderer = reinterpret_cast<DisplayListCanvas*>(rendererPtr);
+ jlong canvasPtr, jlong functorPtr) {
+ DisplayListCanvas* canvas = reinterpret_cast<DisplayListCanvas*>(canvasPtr);
Functor* functor = reinterpret_cast<Functor*>(functorPtr);
- renderer->callDrawGLFunction(functor);
+ canvas->callDrawGLFunction(functor);
}
// ----------------------------------------------------------------------------
@@ -82,9 +78,9 @@
// ----------------------------------------------------------------------------
static void android_view_DisplayListCanvas_drawRoundRectProps(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jlong leftPropPtr, jlong topPropPtr, jlong rightPropPtr,
+ jlong canvasPtr, jlong leftPropPtr, jlong topPropPtr, jlong rightPropPtr,
jlong bottomPropPtr, jlong rxPropPtr, jlong ryPropPtr, jlong paintPropPtr) {
- DisplayListCanvas* renderer = reinterpret_cast<DisplayListCanvas*>(rendererPtr);
+ DisplayListCanvas* canvas = reinterpret_cast<DisplayListCanvas*>(canvasPtr);
CanvasPropertyPrimitive* leftProp = reinterpret_cast<CanvasPropertyPrimitive*>(leftPropPtr);
CanvasPropertyPrimitive* topProp = reinterpret_cast<CanvasPropertyPrimitive*>(topPropPtr);
CanvasPropertyPrimitive* rightProp = reinterpret_cast<CanvasPropertyPrimitive*>(rightPropPtr);
@@ -92,17 +88,17 @@
CanvasPropertyPrimitive* rxProp = reinterpret_cast<CanvasPropertyPrimitive*>(rxPropPtr);
CanvasPropertyPrimitive* ryProp = reinterpret_cast<CanvasPropertyPrimitive*>(ryPropPtr);
CanvasPropertyPaint* paintProp = reinterpret_cast<CanvasPropertyPaint*>(paintPropPtr);
- renderer->drawRoundRect(leftProp, topProp, rightProp, bottomProp, rxProp, ryProp, paintProp);
+ canvas->drawRoundRect(leftProp, topProp, rightProp, bottomProp, rxProp, ryProp, paintProp);
}
static void android_view_DisplayListCanvas_drawCircleProps(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jlong xPropPtr, jlong yPropPtr, jlong radiusPropPtr, jlong paintPropPtr) {
- DisplayListCanvas* renderer = reinterpret_cast<DisplayListCanvas*>(rendererPtr);
+ jlong canvasPtr, jlong xPropPtr, jlong yPropPtr, jlong radiusPropPtr, jlong paintPropPtr) {
+ DisplayListCanvas* canvas = reinterpret_cast<DisplayListCanvas*>(canvasPtr);
CanvasPropertyPrimitive* xProp = reinterpret_cast<CanvasPropertyPrimitive*>(xPropPtr);
CanvasPropertyPrimitive* yProp = reinterpret_cast<CanvasPropertyPrimitive*>(yPropPtr);
CanvasPropertyPrimitive* radiusProp = reinterpret_cast<CanvasPropertyPrimitive*>(radiusPropPtr);
CanvasPropertyPaint* paintProp = reinterpret_cast<CanvasPropertyPaint*>(paintPropPtr);
- renderer->drawCircle(xProp, yProp, radiusProp, paintProp);
+ canvas->drawCircle(xProp, yProp, radiusProp, paintProp);
}
// ----------------------------------------------------------------------------
@@ -110,9 +106,9 @@
// ----------------------------------------------------------------------------
static jlong android_view_DisplayListCanvas_finishRecording(JNIEnv* env,
- jobject clazz, jlong rendererPtr) {
- DisplayListCanvas* renderer = reinterpret_cast<DisplayListCanvas*>(rendererPtr);
- return reinterpret_cast<jlong>(renderer->finishRecording());
+ jobject clazz, jlong canvasPtr) {
+ DisplayListCanvas* canvas = reinterpret_cast<DisplayListCanvas*>(canvasPtr);
+ return reinterpret_cast<jlong>(canvas->finishRecording());
}
static jlong android_view_DisplayListCanvas_createDisplayListCanvas(JNIEnv* env, jobject clazz,
@@ -121,17 +117,17 @@
}
static void android_view_DisplayListCanvas_resetDisplayListCanvas(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jint width, jint height) {
- DisplayListCanvas* renderer = reinterpret_cast<DisplayListCanvas*>(rendererPtr);
- renderer->reset(width, height);
+ jlong canvasPtr, jint width, jint height) {
+ DisplayListCanvas* canvas = reinterpret_cast<DisplayListCanvas*>(canvasPtr);
+ canvas->reset(width, height);
}
static void android_view_DisplayListCanvas_drawRenderNode(JNIEnv* env,
- jobject clazz, jlong rendererPtr, jlong renderNodePtr) {
- DisplayListCanvas* renderer = reinterpret_cast<DisplayListCanvas*>(rendererPtr);
+ jobject clazz, jlong canvasPtr, jlong renderNodePtr) {
+ DisplayListCanvas* canvas = reinterpret_cast<DisplayListCanvas*>(canvasPtr);
RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
- renderer->drawRenderNode(renderNode);
+ canvas->drawRenderNode(renderNode);
}
// ----------------------------------------------------------------------------
@@ -139,10 +135,10 @@
// ----------------------------------------------------------------------------
static void android_view_DisplayListCanvas_drawLayer(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jlong layerPtr, jfloat x, jfloat y) {
- DisplayListCanvas* renderer = reinterpret_cast<DisplayListCanvas*>(rendererPtr);
+ jlong canvasPtr, jlong layerPtr) {
+ DisplayListCanvas* canvas = reinterpret_cast<DisplayListCanvas*>(canvasPtr);
DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerPtr);
- renderer->drawLayer(layer, x, y);
+ canvas->drawLayer(layer);
}
// ----------------------------------------------------------------------------
@@ -192,7 +188,7 @@
{ "nCreateDisplayListCanvas", "(II)J", (void*) android_view_DisplayListCanvas_createDisplayListCanvas },
{ "nResetDisplayListCanvas", "(JII)V", (void*) android_view_DisplayListCanvas_resetDisplayListCanvas },
- { "nDrawLayer", "(JJFF)V", (void*) android_view_DisplayListCanvas_drawLayer },
+ { "nDrawLayer", "(JJ)V", (void*) android_view_DisplayListCanvas_drawLayer },
{ "nGetMaximumTextureWidth", "()I", (void*) android_view_DisplayListCanvas_getMaxTextureWidth },
{ "nGetMaximumTextureHeight", "()I", (void*) android_view_DisplayListCanvas_getMaxTextureHeight },
@@ -204,9 +200,6 @@
};
int register_android_view_DisplayListCanvas(JNIEnv* env) {
- jclass clazz = FindClassOrDie(env, "android/graphics/Rect");
- gRectClassInfo.set = GetMethodIDOrDie(env, clazz, "set", "(IIII)V");
-
return RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods));
}
diff --git a/core/jni/android_view_HardwareLayer.cpp b/core/jni/android_view_HardwareLayer.cpp
index 9e49afb..36ba892 100644
--- a/core/jni/android_view_HardwareLayer.cpp
+++ b/core/jni/android_view_HardwareLayer.cpp
@@ -79,12 +79,6 @@
layer->updateTexImage();
}
-static jint android_view_HardwareLayer_getTexName(JNIEnv* env, jobject clazz,
- jlong layerUpdaterPtr) {
- DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerUpdaterPtr);
- return layer->backingLayer()->getTextureId();
-}
-
// ----------------------------------------------------------------------------
// JNI Glue
// ----------------------------------------------------------------------------
@@ -98,8 +92,6 @@
{ "nSetSurfaceTexture", "(JLandroid/graphics/SurfaceTexture;Z)V",
(void*) android_view_HardwareLayer_setSurfaceTexture },
{ "nUpdateSurfaceTexture", "(J)V", (void*) android_view_HardwareLayer_updateSurfaceTexture },
-
- { "nGetTexName", "(J)I", (void*) android_view_HardwareLayer_getTexName },
};
int register_android_view_HardwareLayer(JNIEnv* env) {
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 4c920dc..414cbb4 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -358,8 +358,8 @@
return;
}
jsize count = env->GetArrayLength(fdsToClose);
- jint *ar = env->GetIntArrayElements(fdsToClose, 0);
- if (!ar) {
+ ScopedIntArrayRO ar(env, fdsToClose);
+ if (ar.get() == NULL) {
ALOGE("Bad fd array");
RuntimeAbort(env);
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index d591f8b..fefd5a7 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -786,6 +786,46 @@
android:protectionLevel="normal"
android:permissionFlags="hidden"/>
+ <!-- @hide We need to keep this around for backwards compatibility -->
+ <permission android:name="android.permission.WRITE_SMS"
+ android:protectionLevel="normal"
+ android:permissionFlags="hidden"/>
+
+ <!-- @hide We need to keep this around for backwards compatibility -->
+ <permission android:name="com.android.browser.permission.READ_HISTORY_BOOKMARKS"
+ android:protectionLevel="normal"
+ android:permissionFlags="hidden"/>
+
+ <!-- @hide We need to keep this around for backwards compatibility -->
+ <permission android:name="com.android.browser.permission.WRITE_HISTORY_BOOKMARKS"
+ android:protectionLevel="normal"
+ android:permissionFlags="hidden"/>
+
+ <!-- @hide We need to keep this around for backwards compatibility -->
+ <permission android:name="android.permission.AUTHENTICATE_ACCOUNTS"
+ android:protectionLevel="normal"
+ android:permissionFlags="hidden"/>
+
+ <!-- @hide We need to keep this around for backwards compatibility -->
+ <permission android:name="android.permission.MANAGE_ACCOUNTS"
+ android:protectionLevel="normal"
+ android:permissionFlags="hidden"/>
+
+ <!-- @hide We need to keep this around for backwards compatibility -->
+ <permission android:name="android.permission.USE_CREDENTIALS"
+ android:protectionLevel="normal"
+ android:permissionFlags="hidden"/>
+
+ <!-- @hide We need to keep this around for backwards compatibility -->
+ <permission android:name="android.permission.SUBSCRIBED_FEEDS_READ"
+ android:protectionLevel="normal"
+ android:permissionFlags="hidden"/>
+
+ <!-- @hide We need to keep this around for backwards compatibility -->
+ <permission android:name="android.permission.SUBSCRIBED_FEEDS_WRITE"
+ android:protectionLevel="normal"
+ android:permissionFlags="hidden"/>
+
<!-- ====================================================================== -->
<!-- INSTALL PERMISSIONS -->
<!-- ====================================================================== -->
@@ -2658,7 +2698,7 @@
android:exported="true"
>
</activity>
- <activity-alias android:name="com.android.internal.app.ForwardIntentToUserOwner"
+ <activity-alias android:name="com.android.internal.app.ForwardIntentToParent"
android:targetActivity="com.android.internal.app.IntentForwarderActivity"
android:exported="true"
android:label="@string/user_owner_label">
diff --git a/core/res/res/drawable/scrollbar_handle_material.xml b/core/res/res/drawable/scrollbar_handle_material.xml
index 56fecec..33efbba 100644
--- a/core/res/res/drawable/scrollbar_handle_material.xml
+++ b/core/res/res/drawable/scrollbar_handle_material.xml
@@ -17,6 +17,9 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:tint="?attr/colorControlNormal"
android:shape="rectangle">
- <solid android:color="#84ffffff" />
- <size android:width="4dp" />
+ <solid
+ android:color="#84ffffff" />
+ <size
+ android:width="4dp"
+ android:height="4dp" />
</shape>
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 1a45b3a..74fd1ec 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -2195,4 +2195,18 @@
<attr name="name" />
</declare-styleable>
+ <!-- <code>initial-layout</code> tag allows configuring the initial layout for the activity
+ within multi-window environment. -->
+ <declare-styleable name="AndroidManifestInitialLayout" parent="AndroidManifestActivity">
+ <!-- Initial width of the activity. Can be either a fixed value or fraction, in which case
+ the width will be constructed as a fraction of the total available width. -->
+ <attr name="activity_width" format="dimension|fraction" />
+ <!-- Initial height of the activity. Can be either a fixed value or fraction, in which case
+ the height will be constructed as a fraction of the total available height. -->
+ <attr name="activity_height" format="dimension|fraction" />
+ <!-- Where to initially position the activity inside the available space. Uses constants
+ defined in {@link android.view.Gravity}. -->
+ <attr name="gravity" />
+ </declare-styleable>
+
</resources>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 7acc25d..2c940ae 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -619,6 +619,17 @@
<!-- rotation: 270 (rotate CW) --> <item>-25</item> <item>65</item>
</integer-array>
+ <!-- Indicate the name of the window orientation sensor type if present. A
+ window orientation sensor produces values to be used in lieu of the
+ typical, accelerometer based sensor. It must only produce integral
+ values between 0 and 3, inclusive, with each one corresponding to a
+ given rotation:
+ 0: 0 degrees of rotation (natural)
+ 1: 90 degrees of rotation (rotate CCW)
+ 2: 180 degrees of rotation (reverse)
+ 3: 270 degrees of rotation (rotate CW) -->
+ <string name="config_orientationSensorType" translatable="false">@null</string>
+
<!-- Lid switch behavior -->
<!-- The number of degrees to rotate the display when the keyboard is open.
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 004407f..a55258c 100755
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1545,6 +1545,7 @@
<java-symbol type="string" name="bugreport_title" />
<java-symbol type="string" name="bugreport_message" />
<java-symbol type="string" name="bugreport_status" />
+ <java-symbol type="string" name="config_orientationSensorType" />
<java-symbol type="string" name="faceunlock_multiple_failures" />
<java-symbol type="string" name="global_action_power_off" />
<java-symbol type="string" name="global_actions_airplane_mode_off_status" />
diff --git a/core/tests/coretests/src/android/animation/ValueAnimatorTests.java b/core/tests/coretests/src/android/animation/ValueAnimatorTests.java
new file mode 100644
index 0000000..03ae9dc
--- /dev/null
+++ b/core/tests/coretests/src/android/animation/ValueAnimatorTests.java
@@ -0,0 +1,494 @@
+/*
+* Copyright (C) 2015 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package android.animation;
+
+import android.os.SystemClock;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import static android.test.MoreAsserts.assertNotEqual;
+
+public class ValueAnimatorTests extends ActivityInstrumentationTestCase2<BasicAnimatorActivity> {
+ private ValueAnimator a1;
+ private ValueAnimator a2;
+
+ // Tolerance of error in calculations related to duration, frame time, etc. due to frame delay.
+ private final static long TOLERANCE = 100; // ms
+ private final static long POLL_INTERVAL = 100; // ms
+
+ private final static float A1_START_VALUE = 0f;
+ private final static float A1_END_VALUE = 1f;
+ private final static int A2_START_VALUE = 100;
+ private final static int A2_END_VALUE = 200;
+
+ public ValueAnimatorTests() {
+ super(BasicAnimatorActivity.class);
+ }
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ a1 = ValueAnimator.ofFloat(A1_START_VALUE, A1_END_VALUE).setDuration(300);
+ a2 = ValueAnimator.ofInt(A2_START_VALUE, A2_END_VALUE).setDuration(500);
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ super.tearDown();
+ a1 = null;
+ a2 = null;
+ }
+
+ @SmallTest
+ public void testStartDelay() throws Throwable {
+ final ValueAnimator a = ValueAnimator.ofFloat(5f, 20f);
+ assertEquals(a.getStartDelay(), 0);
+ final long delay = 200;
+ a.setStartDelay(delay);
+ assertEquals(a.getStartDelay(), delay);
+
+ final MyUpdateListener listener = new MyUpdateListener();
+ a.addUpdateListener(listener);
+ final long[] startTime = new long[1];
+
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ // Test the time between isRunning() and isStarted()
+ assertFalse(a.isStarted());
+ assertFalse(a.isRunning());
+ a.start();
+ startTime[0] = SystemClock.uptimeMillis();
+ assertTrue(a.isStarted());
+ assertFalse(a.isRunning());
+ }
+ });
+
+ Thread.sleep(a.getTotalDuration());
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ assertTrue(listener.wasRunning);
+ assertTrue(listener.firstRunningFrameTime - startTime[0] >= delay);
+ }
+ });
+
+ Thread.sleep(a.getTotalDuration());
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ assertFalse(a.isStarted());
+ }
+ });
+ }
+
+ @SmallTest
+ public void testListenerCallbacks() throws Throwable {
+ final MyListener l1 = new MyListener();
+ final MyListener l2 = new MyListener();
+ a1.addListener(l1);
+ a2.addListener(l2);
+ a2.setStartDelay(400);
+
+ assertFalse(l1.startCalled);
+ assertFalse(l1.cancelCalled);
+ assertFalse(l1.endCalled);
+ assertFalse(l2.startCalled);
+ assertFalse(l2.cancelCalled);
+ assertFalse(l2.endCalled);
+
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ a1.start();
+ a2.start();
+ }
+ });
+
+ long wait = 0;
+ Thread.sleep(POLL_INTERVAL);
+ wait += POLL_INTERVAL;
+
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ assertFalse(l1.cancelCalled);
+ a1.cancel();
+ assertTrue(l1.cancelCalled);
+ assertTrue(l1.endCalled);
+ }
+ });
+
+ while (wait < a2.getStartDelay()) {
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ // Make sure a2's start listener isn't called during start delay.
+ assertTrue(l1.startCalled);
+ assertFalse(l2.startCalled);
+ }
+ });
+ Thread.sleep(POLL_INTERVAL);
+ wait += POLL_INTERVAL;
+ }
+
+ long delay = Math.max(a1.getTotalDuration(), a2.getTotalDuration()) + TOLERANCE;
+ Thread.sleep(delay);
+
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ // a1 is canceled.
+ assertTrue(l1.startCalled);
+ assertTrue(l1.cancelCalled);
+ assertTrue(l1.endCalled);
+
+ // a2 is supposed to finish normally
+ assertTrue(l2.startCalled);
+ assertFalse(l2.cancelCalled);
+ assertTrue(l2.endCalled);
+ }
+ });
+ }
+
+ @SmallTest
+ public void testIsStarted() throws Throwable {
+ assertFalse(a1.isStarted());
+ assertFalse(a2.isStarted());
+ assertFalse(a1.isRunning());
+ assertFalse(a2.isRunning());
+ final long startDelay = 150;
+ a1.setStartDelay(startDelay);
+ final long[] startTime = new long[1];
+
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ a1.start();
+ a2.start();
+ startTime[0] = SystemClock.uptimeMillis();
+ assertTrue(a1.isStarted());
+ assertTrue(a2.isStarted());
+ }
+ });
+ long delayMs = 0;
+ while (delayMs < startDelay) {
+ Thread.sleep(POLL_INTERVAL);
+ delayMs += POLL_INTERVAL;
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ if (SystemClock.uptimeMillis() - startTime[0] < startDelay) {
+ assertFalse(a1.isRunning());
+ }
+ }
+ });
+ }
+
+ Thread.sleep(startDelay);
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ assertTrue(a1.isRunning());
+ assertTrue(a2.isRunning());
+ }
+ });
+
+ long delay = Math.max(a1.getTotalDuration(), a2.getTotalDuration()) * 2;
+ Thread.sleep(delay);
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ assertFalse(a1.isStarted());
+ assertFalse(a1.isRunning());
+ assertFalse(a2.isStarted());
+ assertFalse(a2.isRunning());
+ }
+ });
+ }
+
+ @SmallTest
+ public void testPause() throws Throwable {
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ assertFalse(a1.isPaused());
+ assertFalse(a2.isPaused());
+
+ a1.start();
+ a2.start();
+
+ assertFalse(a1.isPaused());
+ assertFalse(a2.isPaused());
+ assertTrue(a1.isStarted());
+ assertTrue(a2.isStarted());
+ }
+ });
+
+ Thread.sleep(POLL_INTERVAL);
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ assertTrue(a1.isRunning());
+ assertTrue(a2.isRunning());
+ a1.pause();
+ assertTrue(a1.isPaused());
+ assertFalse(a2.isPaused());
+ assertTrue(a1.isRunning());
+ }
+ });
+
+ Thread.sleep(a2.getTotalDuration());
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ // By this time, a2 should have finished, and a1 is still paused
+ assertFalse(a2.isStarted());
+ assertFalse(a2.isRunning());
+ assertTrue(a1.isStarted());
+ assertTrue(a1.isRunning());
+ assertTrue(a1.isPaused());
+
+ a1.resume();
+ }
+ });
+
+ Thread.sleep(POLL_INTERVAL);
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ assertTrue(a1.isRunning());
+ assertTrue(a1.isStarted());
+ assertFalse(a1.isPaused());
+ }
+ });
+
+ Thread.sleep(a1.getTotalDuration());
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ // a1 should finish by now.
+ assertFalse(a1.isRunning());
+ assertFalse(a1.isStarted());
+ assertFalse(a1.isPaused());
+ }
+ });
+
+ }
+
+ @SmallTest
+ public void testPauseListener() throws Throwable {
+ MyPauseListener l1 = new MyPauseListener();
+ MyPauseListener l2 = new MyPauseListener();
+ a1.addPauseListener(l1);
+ a2.addPauseListener(l2);
+
+ assertFalse(l1.pauseCalled);
+ assertFalse(l1.resumeCalled);
+ assertFalse(l2.pauseCalled);
+ assertFalse(l2.resumeCalled);
+
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ a1.start();
+ a2.start();
+ }
+ });
+
+ Thread.sleep(a1.getTotalDuration() / 2);
+ a1.pause();
+
+ Thread.sleep(a2.getTotalDuration());
+
+ // Only a1's pause listener should be called.
+ assertTrue(l1.pauseCalled);
+ assertFalse(l1.resumeCalled);
+ a1.resume();
+
+ Thread.sleep(a1.getTotalDuration());
+
+ assertTrue(l1.pauseCalled);
+ assertTrue(l1.resumeCalled);
+ assertFalse(l2.pauseCalled);
+ assertFalse(l2.resumeCalled);
+ }
+
+ @SmallTest
+ public void testResume() throws Throwable {
+ final MyUpdateListener l1 = new MyUpdateListener();
+ final long totalDuration = a1.getTotalDuration();
+ a1.addUpdateListener(l1);
+ // Set a longer duration on a1 for this test
+ a1.setDuration(1000);
+ assertTrue(l1.firstRunningFrameTime < 0);
+ assertTrue(l1.lastUpdateTime < 0);
+
+ final long[] lastUpdate = new long[1];
+
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ a1.start();
+ }
+ });
+
+ Thread.sleep(totalDuration / 2);
+
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ assertTrue(l1.firstRunningFrameTime > 0);
+ assertTrue(l1.lastUpdateTime > l1.firstRunningFrameTime);
+ lastUpdate[0] = l1.lastUpdateTime;
+ a1.pause();
+ }
+ });
+
+ Thread.sleep(totalDuration);
+
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ // There should be no update after pause()
+ assertEquals(lastUpdate[0], l1.lastUpdateTime);
+ a1.resume();
+ }
+ });
+
+ do {
+ Thread.sleep(POLL_INTERVAL);
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ assertTrue(l1.lastUpdateTime > lastUpdate[0]);
+ lastUpdate[0] = l1.lastUpdateTime;
+ }
+ });
+ } while (!a1.isStarted());
+
+ // Time between pause and resume: totalDuration
+ long entireSpan = totalDuration * 2;
+ long frameDelta = l1.lastUpdateTime - l1.firstRunningFrameTime;
+ assertTrue(Math.abs(entireSpan - frameDelta) < TOLERANCE);
+ }
+
+ @SmallTest
+ public void testEndValue() throws Throwable {
+ final MyListener l1 = new MyListener();
+ a1.addListener(l1);
+
+ final MyListener l2 = new MyListener();
+ a2.addListener(l2);
+
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ a1.start();
+ a2.start();
+ }
+ });
+
+ Thread.sleep(POLL_INTERVAL);
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ // Animation has started but not finished, check animated values against end values
+ assertFalse(l1.endCalled);
+ assertFalse(l2.endCalled);
+ assertNotEqual(A1_END_VALUE, a1.getAnimatedValue());
+ assertNotEqual(A1_END_VALUE, a2.getAnimatedValue());
+
+ // Force a2 to end.
+ a2.end();
+ }
+ });
+
+ Thread.sleep(a1.getTotalDuration());
+
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ assertFalse(l1.cancelCalled);
+ assertTrue(l1.endCalled);
+ assertFalse(l2.cancelCalled);
+ assertTrue(l2.endCalled);
+
+ // By now a1 should have finished normally and a2 has skipped to the end, check
+ // their end values.
+ assertEquals(A1_END_VALUE, ((Float) (a1.getAnimatedValue())).floatValue());
+ assertEquals(A2_END_VALUE, ((Integer) (a2.getAnimatedValue())).intValue());
+ }
+ });
+ }
+
+ class MyUpdateListener implements ValueAnimator.AnimatorUpdateListener {
+ boolean wasRunning = false;
+ long firstRunningFrameTime = -1;
+ long lastUpdateTime = -1;
+
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ lastUpdateTime = SystemClock.uptimeMillis();
+ if (animation.isRunning() && !wasRunning) {
+ // Delay has passed
+ firstRunningFrameTime = lastUpdateTime;
+ wasRunning = animation.isRunning();
+ }
+ }
+ }
+
+ class MyListener implements Animator.AnimatorListener {
+ boolean startCalled = false;
+ boolean cancelCalled = false;
+ boolean endCalled = false;
+
+ @Override
+ public void onAnimationStart(Animator animation) {
+ startCalled = true;
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ endCalled = true;
+ }
+
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ cancelCalled = true;
+ }
+
+ @Override
+ public void onAnimationRepeat(Animator animation) {
+
+ }
+ }
+
+ class MyPauseListener implements Animator.AnimatorPauseListener {
+ boolean pauseCalled = false;
+ boolean resumeCalled = false;
+
+ @Override
+ public void onAnimationPause(Animator animation) {
+ pauseCalled = true;
+ }
+
+ @Override
+ public void onAnimationResume(Animator animation) {
+ resumeCalled = true;
+ }
+ }
+}
diff --git a/core/tests/coretests/src/android/text/format/FormatterTest.java b/core/tests/coretests/src/android/text/format/FormatterTest.java
index d2e2131..be6e7ea 100644
--- a/core/tests/coretests/src/android/text/format/FormatterTest.java
+++ b/core/tests/coretests/src/android/text/format/FormatterTest.java
@@ -56,14 +56,14 @@
public void testFormatBytes() {
setLocale(Locale.ENGLISH);
- checkFormatBytes(0, true, "0.00", 0);
- checkFormatBytes(0, false, "0.00", 0);
+ checkFormatBytes(0, true, "0", 0);
+ checkFormatBytes(0, false, "0", 0);
- checkFormatBytes(1, true, "1.0", 1);
- checkFormatBytes(1, false, "1.00", 1);
+ checkFormatBytes(1, true, "1", 1);
+ checkFormatBytes(1, false, "1", 1);
checkFormatBytes(12, true, "12", 12);
- checkFormatBytes(12, false, "12.00", 12);
+ checkFormatBytes(12, false, "12", 12);
checkFormatBytes(123, true, "123", 123);
checkFormatBytes(123, false, "123", 123);
@@ -80,13 +80,15 @@
checkFormatBytes(9123000, true, "8.7", 9122611);
checkFormatBytes(9123000, false, "8.70", 9122611);
- // The method doesn't really support negative values, but apparently people pass -1...
- checkFormatBytes(-1, true, "-1.00", -1);
- checkFormatBytes(-1, false, "-1.00", -1);
+ checkFormatBytes(-1, true, "-1", -1);
+ checkFormatBytes(-1, false, "-1", -1);
+
+ checkFormatBytes(-912, true, "-0.89", -911);
+ checkFormatBytes(-912, false, "-0.89", -911);
// Missing FLAG_CALCULATE_ROUNDED case.
BytesResult r = Formatter.formatBytes(getContext().getResources(), 1, 0);
- assertEquals("1.00", r.value);
+ assertEquals("1", r.value);
assertEquals(0, r.roundedBytes); // Didn't pass FLAG_CALCULATE_ROUNDED
// Make sure it works on different locales.
diff --git a/core/tests/coretests/src/android/widget/TextViewTest.java b/core/tests/coretests/src/android/widget/TextViewTest.java
index 0b94f8b..49d9115 100644
--- a/core/tests/coretests/src/android/widget/TextViewTest.java
+++ b/core/tests/coretests/src/android/widget/TextViewTest.java
@@ -18,7 +18,7 @@
import android.app.Activity;
import android.content.Intent;
-import android.test.AndroidTestCase;
+import android.test.ActivityInstrumentationTestCase2;
import android.test.suitebuilder.annotation.SmallTest;
import android.text.GetChars;
import android.text.Selection;
@@ -27,11 +27,15 @@
/**
* TextViewTest tests {@link TextView}.
*/
-public class TextViewTest extends AndroidTestCase {
+public class TextViewTest extends ActivityInstrumentationTestCase2<TextViewActivity> {
+
+ public TextViewTest() {
+ super(TextViewActivity.class);
+ }
@SmallTest
public void testArray() throws Exception {
- TextView tv = new TextView(mContext);
+ TextView tv = new TextView(getActivity());
char[] c = new char[] { 'H', 'e', 'l', 'l', 'o', ' ',
'W', 'o', 'r', 'l', 'd', '!' };
@@ -59,25 +63,34 @@
assertEquals('\0', c2[5]);
}
+ @SmallTest
public void testProcessTextActivityResultNonEditable() {
- TextView tv = new TextView(mContext);
+ final TextView tv = new TextView(getActivity());
CharSequence originalText = "This is some text.";
tv.setText(originalText, TextView.BufferType.SPANNABLE);
assertEquals(originalText, tv.getText().toString());
tv.setTextIsSelectable(true);
Selection.setSelection((Spannable) tv.getText(), 0, tv.getText().length());
- CharSequence newText = "Text is replaced.";
- Intent data = new Intent();
- data.putExtra(Intent.EXTRA_PROCESS_TEXT, newText);
- tv.onActivityResult(TextView.PROCESS_TEXT_REQUEST_CODE, Activity.RESULT_OK, data);
+ // We need to run this in the UI thread, as it will create a Toast.
+ getActivity().runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ CharSequence newText = "Text is replaced.";
+ Intent data = new Intent();
+ data.putExtra(Intent.EXTRA_PROCESS_TEXT, newText);
+ tv.onActivityResult(TextView.PROCESS_TEXT_REQUEST_CODE, Activity.RESULT_OK, data);
+ }
+ });
+ getInstrumentation().waitForIdleSync();
// This is a TextView, which can't be modified. Hence no change should have been made.
assertEquals(originalText, tv.getText().toString());
}
+ @SmallTest
public void testProcessTextActivityResultEditable() {
- EditText tv = new EditText(mContext);
+ EditText tv = new EditText(getActivity());
CharSequence originalText = "This is some text.";
tv.setText(originalText, TextView.BufferType.SPANNABLE);
assertEquals(originalText, tv.getText().toString());
@@ -92,8 +105,9 @@
assertEquals(newText, tv.getText().toString());
}
+ @SmallTest
public void testProcessTextActivityResultCancel() {
- EditText tv = new EditText(mContext);
+ EditText tv = new EditText(getActivity());
CharSequence originalText = "This is some text.";
tv.setText(originalText, TextView.BufferType.SPANNABLE);
assertEquals(originalText, tv.getText().toString());
@@ -108,8 +122,9 @@
assertEquals(originalText, tv.getText().toString());
}
+ @SmallTest
public void testProcessTextActivityNoData() {
- EditText tv = new EditText(mContext);
+ EditText tv = new EditText(getActivity());
CharSequence originalText = "This is some text.";
tv.setText(originalText, TextView.BufferType.SPANNABLE);
assertEquals(originalText, tv.getText().toString());
diff --git a/docs/html/design/media/wear/1-tap-launch.png b/docs/html/design/media/wear/1-tap-launch.png
new file mode 100644
index 0000000..c0c9aca
--- /dev/null
+++ b/docs/html/design/media/wear/1-tap-launch.png
Binary files differ
diff --git a/docs/html/design/media/wear/2-tap-launch.png b/docs/html/design/media/wear/2-tap-launch.png
new file mode 100644
index 0000000..395a3ce
--- /dev/null
+++ b/docs/html/design/media/wear/2-tap-launch.png
Binary files differ
diff --git a/docs/html/design/media/wear/aesthetic.png b/docs/html/design/media/wear/aesthetic.png
new file mode 100644
index 0000000..f6e5f3e
--- /dev/null
+++ b/docs/html/design/media/wear/aesthetic.png
Binary files differ
diff --git a/docs/html/design/media/wear/available_gestures.png b/docs/html/design/media/wear/available_gestures.png
new file mode 100644
index 0000000..677076b
--- /dev/null
+++ b/docs/html/design/media/wear/available_gestures.png
Binary files differ
diff --git a/docs/html/design/media/wear/available_gestures_2x.png b/docs/html/design/media/wear/available_gestures_2x.png
new file mode 100644
index 0000000..eced0c7
--- /dev/null
+++ b/docs/html/design/media/wear/available_gestures_2x.png
Binary files differ
diff --git a/docs/html/design/media/wear/changing-target.png b/docs/html/design/media/wear/changing-target.png
new file mode 100644
index 0000000..427531f
--- /dev/null
+++ b/docs/html/design/media/wear/changing-target.png
Binary files differ
diff --git a/docs/html/design/media/wear/revealing-info.png b/docs/html/design/media/wear/revealing-info.png
new file mode 100644
index 0000000..e419e9f
--- /dev/null
+++ b/docs/html/design/media/wear/revealing-info.png
Binary files differ
diff --git a/docs/html/design/media/wear/toggling-states.png b/docs/html/design/media/wear/toggling-states.png
new file mode 100644
index 0000000..93398e6
--- /dev/null
+++ b/docs/html/design/media/wear/toggling-states.png
Binary files differ
diff --git a/docs/html/design/media/wear/visual_feedback.gif b/docs/html/design/media/wear/visual_feedback.gif
new file mode 100644
index 0000000..e07000a
--- /dev/null
+++ b/docs/html/design/media/wear/visual_feedback.gif
Binary files differ
diff --git a/docs/html/design/wear/watchfaces.jd b/docs/html/design/wear/watchfaces.jd
index e018523..c8c6d5a 100644
--- a/docs/html/design/wear/watchfaces.jd
+++ b/docs/html/design/wear/watchfaces.jd
@@ -288,6 +288,107 @@
with an actual watch screen before you start coding.</p>
+<h2 id="interactive">Design Interactive Watch Faces</h2>
+
+<p>Your watch face can respond to a single-tap gesture from the user, as long as
+there’s not another UI element that also responds to that gesture. Some possible use cases for
+interacting with the watch face include:</p>
+
+<ul>
+ <li><strong>Causing an aesthetic change</strong> on the watch face, for example inverting
+ the color scheme.</li>
+ <li><strong>Showing more information</strong> inline on the watch face, for example displaying a
+ detailed step count.</li>
+ <li><strong>Completing an action</strong> inline or in the background, for example starting a
+ timer.</li>
+ <li><strong>Launching a specific activity,</strong> for example a starting a conversation in a
+ messaging application.</li>
+</ul>
+
+<h3 id="ag">Available gestures</h3>
+<p>Only single taps are available. This restriction is important for maintaining clear and
+consistent system interactions, and for making watch face interactions as simple as
+possible: Neither you nor the user should think of watch faces as full-fledged apps. Figure 1
+summarizes the categories of gestures, and their uses.</p>
+
+<img src="{@docRoot}design/media/wear/available_gestures.png"
+srcset="{@docRoot}design/media/wear/available_gestures.png 1x,
+{@docRoot}design/media/wear/available_gestures_2x.png 2x"
+alt="Single tap is the only available gesture." width="740" height="" id="available-gestures" />
+<p class="img-caption">
+ <strong>Figure 1.</strong> Available, reserved, and blocked gestures.
+</p>
+
+As a rule, watch-face interaction should be lightweight, with the user completing their desired
+action within one or two touches.
+
+<h3>Tap targets</h3>
+
+<p>If you want to cause a simple state change on the watch face, such as a purely aesthetic
+change, you can use the entire canvas of the watch face as the tap target.</p>
+
+<p>For a more significant change or action, such as launching an activity or sending a message to a
+friend, it’s important to keep targets smaller, between 48-90 dpi, to avoid false-positive taps.
+There should be a gap between targets of at least 8-16 dpi. For an optimized tappable experience,
+display a maximum of 7 to 9 targets at once.</p>
+
+<h3 id=”areas”>Tap regions</h3>
+
+<p>You can also use different regions of the screen to trigger different changes to the watch face.
+For example, tapping on the entire canvas could toggle states for the entire face. Tapping a specific target
+could produce an inline display of information related to the target. Last, tapping outside the
+target could restore the watch face to its default state.</p>
+
+<div style="float:right;margin-bottom:20px;margin-left:20px">
+ <img src="/design/media/wear/visual_feedback.gif" width="200"
+ height="196" alt="The watch face should show where the user’s finger has made contact." style="margin-top:-10px;margin-left:13px">
+</div>
+
+
+<h3>Visual feedback</h3>
+
+<p>Provide visual feedback when the user’s finger touches down on the watch face. The tap
+event does not trigger until the user lifts their finger, but visual feedback on touchdown helps
+indicate that the system has received the touch, and also helps the user know where the touch
+landed.</p>
+
+<p class=”warning”><strong>Warning:</strong> Do not immediately launch a UI on touchdown. A UI that
+you launch on touchdown conflicts with gestures for interacting with system UI elements including
+the watch face picker, notification stream, settings shade, and app launcher.</p>
+
+<h3>Design examples</h3>
+
+Here are some examples of approaches for interactive watch faces:
+
+<h4>Applying an aesthetic change</h4>
+
+<img src="{@docRoot}design/media/wear/aesthetic.png"
+alt="" width="686" height="" id="descriptive-id" />
+
+<h4>Toggling states</h4>
+
+<img src="{@docRoot}design/media/wear/toggling-states.png"
+alt="" width="686" height="" id="descriptive-id" />
+
+<h4>Changing a targeted UI element</h4>
+
+<img src="{@docRoot}design/media/wear/changing-target.png"
+alt="" width="686" height="" id="descriptive-id" />
+
+<h4>Revealing information inline</h4>
+
+<img src="{@docRoot}design/media/wear/revealing-info.png"
+alt="" width="686" height="" id="descriptive-id" />
+
+<h4>Launching an activity with a single tap</h4>
+
+<img src="{@docRoot}design/media/wear/1-tap-launch.png"
+alt="" width="751" height="" id="descriptive-id" />
+
+<h4>Launching an activity with two taps</h4>
+
+<img src="{@docRoot}design/media/wear/2-tap-launch.png"
+alt="" width="751" height="" id="descriptive-id" />
<h2 id="CompanionApp">Support the Android Wear Companion App</h2>
diff --git a/docs/html/reference/android/support/wearable/R.anim.html b/docs/html/reference/android/support/wearable/R.anim.html
index 11d766d..8976afe 100644
--- a/docs/html/reference/android/support/wearable/R.anim.html
+++ b/docs/html/reference/android/support/wearable/R.anim.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -473,6 +473,7 @@
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.html">R</a></li>
<li class="selected api apilevel-"><a href="../../../../reference/android/support/wearable/R.anim.html">R.anim</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.animator.html">R.animator</a></li>
+ <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.array.html">R.array</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.attr.html">R.attr</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.color.html">R.color</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.dimen.html">R.dimen</a></li>
@@ -614,7 +615,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -1322,6 +1323,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/R.animator.html b/docs/html/reference/android/support/wearable/R.animator.html
index 9fa6445..7ab63f2 100644
--- a/docs/html/reference/android/support/wearable/R.animator.html
+++ b/docs/html/reference/android/support/wearable/R.animator.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -473,6 +473,7 @@
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.html">R</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.anim.html">R.anim</a></li>
<li class="selected api apilevel-"><a href="../../../../reference/android/support/wearable/R.animator.html">R.animator</a></li>
+ <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.array.html">R.array</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.attr.html">R.attr</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.color.html">R.color</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.dimen.html">R.dimen</a></li>
@@ -614,7 +615,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -1134,6 +1135,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/R.attr.html b/docs/html/reference/android/support/wearable/R.attr.html
index 1f043a2..099c981 100644
--- a/docs/html/reference/android/support/wearable/R.attr.html
+++ b/docs/html/reference/android/support/wearable/R.attr.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -473,6 +473,7 @@
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.html">R</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.anim.html">R.anim</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.animator.html">R.animator</a></li>
+ <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.array.html">R.array</a></li>
<li class="selected api apilevel-"><a href="../../../../reference/android/support/wearable/R.attr.html">R.attr</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.color.html">R.color</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.dimen.html">R.dimen</a></li>
@@ -614,7 +615,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -697,6 +698,23 @@
static
int</nobr></td>
+ <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.attr.html#buttonRippleColor">buttonRippleColor</a></td>
+ <td class="jd-descrcol" width="100%">
+ <p>May be a reference to another resource, in the form "<code>@[+][<i>package</i>:]<i>type</i>:<i>name</i></code>"
+or to a theme attribute in the form "<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>".
+
+
+
+ </td>
+ </tr>
+
+
+ <tr class=" api apilevel-" >
+ <td class="jd-typecol"><nobr>
+ public
+ static
+
+ int</nobr></td>
<td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.attr.html#circle_border_color">circle_border_color</a></td>
<td class="jd-descrcol" width="100%">
<p>Must be a color value, in the form of "<code>#<i>rgb</i></code>", "<code>#<i>argb</i></code>",
@@ -708,7 +726,7 @@
</tr>
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -724,7 +742,7 @@
</tr>
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -741,7 +759,7 @@
</tr>
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -757,7 +775,7 @@
</tr>
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -773,7 +791,7 @@
</tr>
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -789,7 +807,7 @@
</tr>
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -805,7 +823,7 @@
</tr>
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -821,6 +839,23 @@
</tr>
+ <tr class=" api apilevel-" >
+ <td class="jd-typecol"><nobr>
+ public
+ static
+
+ int</nobr></td>
+ <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.attr.html#color_sequence">color_sequence</a></td>
+ <td class="jd-descrcol" width="100%">
+ <p>May be a reference to another resource, in the form "<code>@[+][<i>package</i>:]<i>type</i>:<i>name</i></code>"
+or to a theme attribute in the form "<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>".
+
+
+
+ </td>
+ </tr>
+
+
<tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
public
@@ -1054,6 +1089,55 @@
static
int</nobr></td>
+ <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.attr.html#image_circle_percentage">image_circle_percentage</a></td>
+ <td class="jd-descrcol" width="100%">
+ <p>Must be a dimension value, which is a floating point number appended with a unit such as "<code>14.5sp</code>".
+
+
+
+ </td>
+ </tr>
+
+
+ <tr class=" api apilevel-" >
+ <td class="jd-typecol"><nobr>
+ public
+ static
+
+ int</nobr></td>
+ <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.attr.html#image_horizontal_offcenter_percentage">image_horizontal_offcenter_percentage</a></td>
+ <td class="jd-descrcol" width="100%">
+ <p>Must be a dimension value, which is a floating point number appended with a unit such as "<code>14.5sp</code>".
+
+
+
+ </td>
+ </tr>
+
+
+ <tr class="alt-color api apilevel-" >
+ <td class="jd-typecol"><nobr>
+ public
+ static
+
+ int</nobr></td>
+ <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.attr.html#image_tint">image_tint</a></td>
+ <td class="jd-descrcol" width="100%">
+ <p>Must be a color value, in the form of "<code>#<i>rgb</i></code>", "<code>#<i>argb</i></code>",
+"<code>#<i>rrggbb</i></code>", or "<code>#<i>aarrggbb</i></code>".
+
+
+
+ </td>
+ </tr>
+
+
+ <tr class=" api apilevel-" >
+ <td class="jd-typecol"><nobr>
+ public
+ static
+
+ int</nobr></td>
<td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.attr.html#layout_box">layout_box</a></td>
<td class="jd-descrcol" width="100%">
<p>Must be one or more (separated by '|') of the following constant values.
@@ -1064,7 +1148,7 @@
</tr>
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -1080,7 +1164,7 @@
</tr>
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -1096,7 +1180,7 @@
</tr>
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -1112,7 +1196,7 @@
</tr>
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -1128,7 +1212,7 @@
</tr>
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -1144,7 +1228,7 @@
</tr>
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -1160,7 +1244,7 @@
</tr>
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -1176,7 +1260,7 @@
</tr>
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -1192,7 +1276,7 @@
</tr>
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -1208,7 +1292,7 @@
</tr>
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -1224,13 +1308,13 @@
</tr>
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
int</nobr></td>
- <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.attr.html#pressedTranslationZ">pressedTranslationZ</a></td>
+ <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.attr.html#pressedButtonTranslationZ">pressedButtonTranslationZ</a></td>
<td class="jd-descrcol" width="100%">
<p>Must be a dimension value, which is a floating point number appended with a unit such as "<code>14.5sp</code>".
@@ -1240,7 +1324,7 @@
</tr>
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -1257,23 +1341,6 @@
</tr>
- <tr class=" api apilevel-" >
- <td class="jd-typecol"><nobr>
- public
- static
-
- int</nobr></td>
- <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.attr.html#rippleColor">rippleColor</a></td>
- <td class="jd-descrcol" width="100%">
- <p>May be a reference to another resource, in the form "<code>@[+][<i>package</i>:]<i>type</i>:<i>name</i></code>"
-or to a theme attribute in the form "<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>".
-
-
-
- </td>
- </tr>
-
-
<tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
public
@@ -1605,6 +1672,41 @@
+<A NAME="buttonRippleColor"></A>
+
+<div class="jd-details api apilevel-">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ public
+ static
+
+ int
+ </span>
+ buttonRippleColor
+ </h4>
+ <div class="api-level">
+
+
+
+
+ </div>
+ <div class="jd-details-descr">
+
+
+
+
+ <div class="jd-tagdata jd-tagdescr"><p><p>May be a reference to another resource, in the form "<code>@[+][<i>package</i>:]<i>type</i>:<i>name</i></code>"
+or to a theme attribute in the form "<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>".
+<p>May be a color value, in the form of "<code>#<i>rgb</i></code>", "<code>#<i>argb</i></code>",
+"<code>#<i>rrggbb</i></code>", or "<code>#<i>aarrggbb</i></code>".
+</p></div>
+
+
+ </div>
+</div>
+
+
+
<A NAME="circle_border_color"></A>
<div class="jd-details api apilevel-">
@@ -1921,6 +2023,41 @@
+<A NAME="color_sequence"></A>
+
+<div class="jd-details api apilevel-">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ public
+ static
+
+ int
+ </span>
+ color_sequence
+ </h4>
+ <div class="api-level">
+
+
+
+
+ </div>
+ <div class="jd-details-descr">
+
+
+
+
+ <div class="jd-tagdata jd-tagdescr"><p><p>May be a reference to another resource, in the form "<code>@[+][<i>package</i>:]<i>type</i>:<i>name</i></code>"
+or to a theme attribute in the form "<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>".
+<p>May be a color value, in the form of "<code>#<i>rgb</i></code>", "<code>#<i>argb</i></code>",
+"<code>#<i>rrggbb</i></code>", or "<code>#<i>aarrggbb</i></code>".
+</p></div>
+
+
+ </div>
+</div>
+
+
+
<A NAME="dotColor"></A>
<div class="jd-details api apilevel-">
@@ -2457,6 +2594,122 @@
+<A NAME="image_circle_percentage"></A>
+
+<div class="jd-details api apilevel-">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ public
+ static
+
+ int
+ </span>
+ image_circle_percentage
+ </h4>
+ <div class="api-level">
+
+
+
+
+ </div>
+ <div class="jd-details-descr">
+
+
+
+
+ <div class="jd-tagdata jd-tagdescr"><p><p>Must be a dimension value, which is a floating point number appended with a unit such as "<code>14.5sp</code>".
+Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size),
+in (inches), mm (millimeters).
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+</p></div>
+
+
+ </div>
+</div>
+
+
+
+<A NAME="image_horizontal_offcenter_percentage"></A>
+
+<div class="jd-details api apilevel-">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ public
+ static
+
+ int
+ </span>
+ image_horizontal_offcenter_percentage
+ </h4>
+ <div class="api-level">
+
+
+
+
+ </div>
+ <div class="jd-details-descr">
+
+
+
+
+ <div class="jd-tagdata jd-tagdescr"><p><p>Must be a dimension value, which is a floating point number appended with a unit such as "<code>14.5sp</code>".
+Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size),
+in (inches), mm (millimeters).
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+</p></div>
+
+
+ </div>
+</div>
+
+
+
+<A NAME="image_tint"></A>
+
+<div class="jd-details api apilevel-">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ public
+ static
+
+ int
+ </span>
+ image_tint
+ </h4>
+ <div class="api-level">
+
+
+
+
+ </div>
+ <div class="jd-details-descr">
+
+
+
+
+ <div class="jd-tagdata jd-tagdescr"><p><p>Must be a color value, in the form of "<code>#<i>rgb</i></code>", "<code>#<i>argb</i></code>",
+"<code>#<i>rrggbb</i></code>", or "<code>#<i>aarrggbb</i></code>".
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+</p></div>
+
+
+ </div>
+</div>
+
+
+
<A NAME="layout_box"></A>
<div class="jd-details api apilevel-">
@@ -2903,7 +3156,7 @@
-<A NAME="pressedTranslationZ"></A>
+<A NAME="pressedButtonTranslationZ"></A>
<div class="jd-details api apilevel-">
<h4 class="jd-details-title">
@@ -2913,7 +3166,7 @@
int
</span>
- pressedTranslationZ
+ pressedButtonTranslationZ
</h4>
<div class="api-level">
@@ -2975,41 +3228,6 @@
-<A NAME="rippleColor"></A>
-
-<div class="jd-details api apilevel-">
- <h4 class="jd-details-title">
- <span class="normal">
- public
- static
-
- int
- </span>
- rippleColor
- </h4>
- <div class="api-level">
-
-
-
-
- </div>
- <div class="jd-details-descr">
-
-
-
-
- <div class="jd-tagdata jd-tagdescr"><p><p>May be a reference to another resource, in the form "<code>@[+][<i>package</i>:]<i>type</i>:<i>name</i></code>"
-or to a theme attribute in the form "<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>".
-<p>May be a color value, in the form of "<code>#<i>rgb</i></code>", "<code>#<i>argb</i></code>",
-"<code>#<i>rrggbb</i></code>", or "<code>#<i>aarrggbb</i></code>".
-</p></div>
-
-
- </div>
-</div>
-
-
-
<A NAME="roundLayout"></A>
<div class="jd-details api apilevel-">
@@ -3233,6 +3451,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/R.color.html b/docs/html/reference/android/support/wearable/R.color.html
index cdfd0a8..07b5e0c 100644
--- a/docs/html/reference/android/support/wearable/R.color.html
+++ b/docs/html/reference/android/support/wearable/R.color.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -473,6 +473,7 @@
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.html">R</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.anim.html">R.anim</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.animator.html">R.animator</a></li>
+ <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.array.html">R.array</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.attr.html">R.attr</a></li>
<li class="selected api apilevel-"><a href="../../../../reference/android/support/wearable/R.color.html">R.color</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.dimen.html">R.dimen</a></li>
@@ -614,7 +615,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -2450,6 +2451,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/R.dimen.html b/docs/html/reference/android/support/wearable/R.dimen.html
index c24ef8d..215b2b3 100644
--- a/docs/html/reference/android/support/wearable/R.dimen.html
+++ b/docs/html/reference/android/support/wearable/R.dimen.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -473,6 +473,7 @@
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.html">R</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.anim.html">R.anim</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.animator.html">R.animator</a></li>
+ <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.array.html">R.array</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.attr.html">R.attr</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.color.html">R.color</a></li>
<li class="selected api apilevel-"><a href="../../../../reference/android/support/wearable/R.dimen.html">R.dimen</a></li>
@@ -614,7 +615,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -1839,6 +1840,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/R.drawable.html b/docs/html/reference/android/support/wearable/R.drawable.html
index 167c8ab..c83cd2e 100644
--- a/docs/html/reference/android/support/wearable/R.drawable.html
+++ b/docs/html/reference/android/support/wearable/R.drawable.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -473,6 +473,7 @@
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.html">R</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.anim.html">R.anim</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.animator.html">R.animator</a></li>
+ <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.array.html">R.array</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.attr.html">R.attr</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.color.html">R.color</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.dimen.html">R.dimen</a></li>
@@ -614,7 +615,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -1557,6 +1558,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/R.html b/docs/html/reference/android/support/wearable/R.html
index fd87f79..714f287 100644
--- a/docs/html/reference/android/support/wearable/R.html
+++ b/docs/html/reference/android/support/wearable/R.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -473,6 +473,7 @@
<li class="selected api apilevel-"><a href="../../../../reference/android/support/wearable/R.html">R</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.anim.html">R.anim</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.animator.html">R.animator</a></li>
+ <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.array.html">R.array</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.attr.html">R.attr</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.color.html">R.color</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.dimen.html">R.dimen</a></li>
@@ -614,7 +615,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -717,7 +718,7 @@
class</nobr></td>
- <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.attr.html">R.attr</a></td>
+ <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.array.html">R.array</a></td>
<td class="jd-descrcol" width="100%">
@@ -734,6 +735,23 @@
class</nobr></td>
+ <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.attr.html">R.attr</a></td>
+ <td class="jd-descrcol" width="100%">
+
+
+
+
+ </td>
+ </tr>
+
+
+ <tr class="alt-color api apilevel-" >
+ <td class="jd-typecol"><nobr>
+
+
+
+
+ class</nobr></td>
<td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.color.html">R.color</a></td>
<td class="jd-descrcol" width="100%">
@@ -744,7 +762,7 @@
</tr>
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -761,7 +779,7 @@
</tr>
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -778,7 +796,7 @@
</tr>
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -795,7 +813,7 @@
</tr>
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -812,7 +830,7 @@
</tr>
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -829,7 +847,7 @@
</tr>
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -846,7 +864,7 @@
</tr>
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -863,7 +881,7 @@
</tr>
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1283,6 +1301,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/R.id.html b/docs/html/reference/android/support/wearable/R.id.html
index 2b3db85..c6bad3b 100644
--- a/docs/html/reference/android/support/wearable/R.id.html
+++ b/docs/html/reference/android/support/wearable/R.id.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -473,6 +473,7 @@
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.html">R</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.anim.html">R.anim</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.animator.html">R.animator</a></li>
+ <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.array.html">R.array</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.attr.html">R.attr</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.color.html">R.color</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.dimen.html">R.dimen</a></li>
@@ -614,7 +615,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -2262,6 +2263,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/R.interpolator.html b/docs/html/reference/android/support/wearable/R.interpolator.html
index ae6cac1..01391a8 100644
--- a/docs/html/reference/android/support/wearable/R.interpolator.html
+++ b/docs/html/reference/android/support/wearable/R.interpolator.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -473,6 +473,7 @@
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.html">R</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.anim.html">R.anim</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.animator.html">R.animator</a></li>
+ <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.array.html">R.array</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.attr.html">R.attr</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.color.html">R.color</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.dimen.html">R.dimen</a></li>
@@ -614,7 +615,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -1369,6 +1370,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/R.layout.html b/docs/html/reference/android/support/wearable/R.layout.html
index 7a87cf2..4987ba7 100644
--- a/docs/html/reference/android/support/wearable/R.layout.html
+++ b/docs/html/reference/android/support/wearable/R.layout.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -473,6 +473,7 @@
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.html">R</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.anim.html">R.anim</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.animator.html">R.animator</a></li>
+ <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.array.html">R.array</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.attr.html">R.attr</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.color.html">R.color</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.dimen.html">R.dimen</a></li>
@@ -614,7 +615,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -1275,6 +1276,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/R.string.html b/docs/html/reference/android/support/wearable/R.string.html
index 3d13614..c8707ef 100644
--- a/docs/html/reference/android/support/wearable/R.string.html
+++ b/docs/html/reference/android/support/wearable/R.string.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -473,6 +473,7 @@
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.html">R</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.anim.html">R.anim</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.animator.html">R.animator</a></li>
+ <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.array.html">R.array</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.attr.html">R.attr</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.color.html">R.color</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.dimen.html">R.dimen</a></li>
@@ -614,7 +615,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -1134,6 +1135,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/R.style.html b/docs/html/reference/android/support/wearable/R.style.html
index 48837d0..38ce308 100644
--- a/docs/html/reference/android/support/wearable/R.style.html
+++ b/docs/html/reference/android/support/wearable/R.style.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -473,6 +473,7 @@
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.html">R</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.anim.html">R.anim</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.animator.html">R.animator</a></li>
+ <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.array.html">R.array</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.attr.html">R.attr</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.color.html">R.color</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.dimen.html">R.dimen</a></li>
@@ -614,7 +615,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -2262,6 +2263,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/R.styleable.html b/docs/html/reference/android/support/wearable/R.styleable.html
index d1e4ca3..e43e070 100644
--- a/docs/html/reference/android/support/wearable/R.styleable.html
+++ b/docs/html/reference/android/support/wearable/R.styleable.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -473,6 +473,7 @@
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.html">R</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.anim.html">R.anim</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.animator.html">R.animator</a></li>
+ <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.array.html">R.array</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.attr.html">R.attr</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.color.html">R.color</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.dimen.html">R.dimen</a></li>
@@ -614,7 +615,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -1137,6 +1138,23 @@
static
int</nobr></td>
+ <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_buttonRippleColor">ActionPage_buttonRippleColor</a></td>
+ <td class="jd-descrcol" width="100%">
+ <p>This symbol is the offset where the <code><a href="../../../../reference/android/support/wearable/R.attr.html#buttonRippleColor">buttonRippleColor</a></code>
+ attribute's value can be found in the <code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage">ActionPage</a></code> array.
+
+
+
+ </td>
+ </tr>
+
+
+ <tr class=" api apilevel-" >
+ <td class="jd-typecol"><nobr>
+ public
+ static
+
+ int</nobr></td>
<td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_imageScaleMode">ActionPage_imageScaleMode</a></td>
<td class="jd-descrcol" width="100%">
<p>This symbol is the offset where the <code><a href="../../../../reference/android/support/wearable/R.attr.html#imageScaleMode">imageScaleMode</a></code>
@@ -1148,7 +1166,7 @@
</tr>
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -1165,7 +1183,7 @@
</tr>
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -1182,32 +1200,15 @@
</tr>
- <tr class=" api apilevel-" >
- <td class="jd-typecol"><nobr>
- public
- static
-
- int</nobr></td>
- <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_pressedTranslationZ">ActionPage_pressedTranslationZ</a></td>
- <td class="jd-descrcol" width="100%">
- <p>This symbol is the offset where the <code><a href="../../../../reference/android/support/wearable/R.attr.html#pressedTranslationZ">pressedTranslationZ</a></code>
- attribute's value can be found in the <code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage">ActionPage</a></code> array.
-
-
-
- </td>
- </tr>
-
-
<tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
int</nobr></td>
- <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_rippleColor">ActionPage_rippleColor</a></td>
+ <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_pressedButtonTranslationZ">ActionPage_pressedButtonTranslationZ</a></td>
<td class="jd-descrcol" width="100%">
- <p>This symbol is the offset where the <code><a href="../../../../reference/android/support/wearable/R.attr.html#rippleColor">rippleColor</a></code>
+ <p>This symbol is the offset where the <code><a href="../../../../reference/android/support/wearable/R.attr.html#pressedButtonTranslationZ">pressedButtonTranslationZ</a></code>
attribute's value can be found in the <code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage">ActionPage</a></code> array.
@@ -1390,6 +1391,57 @@
static
int</nobr></td>
+ <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_image_circle_percentage">CircledImageView_image_circle_percentage</a></td>
+ <td class="jd-descrcol" width="100%">
+ <p>This symbol is the offset where the <code><a href="../../../../reference/android/support/wearable/R.attr.html#image_circle_percentage">image_circle_percentage</a></code>
+ attribute's value can be found in the <code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView">CircledImageView</a></code> array.
+
+
+
+ </td>
+ </tr>
+
+
+ <tr class="alt-color api apilevel-" >
+ <td class="jd-typecol"><nobr>
+ public
+ static
+
+ int</nobr></td>
+ <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_image_horizontal_offcenter_percentage">CircledImageView_image_horizontal_offcenter_percentage</a></td>
+ <td class="jd-descrcol" width="100%">
+ <p>This symbol is the offset where the <code><a href="../../../../reference/android/support/wearable/R.attr.html#image_horizontal_offcenter_percentage">image_horizontal_offcenter_percentage</a></code>
+ attribute's value can be found in the <code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView">CircledImageView</a></code> array.
+
+
+
+ </td>
+ </tr>
+
+
+ <tr class=" api apilevel-" >
+ <td class="jd-typecol"><nobr>
+ public
+ static
+
+ int</nobr></td>
+ <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_image_tint">CircledImageView_image_tint</a></td>
+ <td class="jd-descrcol" width="100%">
+ <p>This symbol is the offset where the <code><a href="../../../../reference/android/support/wearable/R.attr.html#image_tint">image_tint</a></code>
+ attribute's value can be found in the <code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView">CircledImageView</a></code> array.
+
+
+
+ </td>
+ </tr>
+
+
+ <tr class="alt-color api apilevel-" >
+ <td class="jd-typecol"><nobr>
+ public
+ static
+
+ int</nobr></td>
<td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_shadow_width">CircledImageView_shadow_width</a></td>
<td class="jd-descrcol" width="100%">
<p>This symbol is the offset where the <code><a href="../../../../reference/android/support/wearable/R.attr.html#shadow_width">shadow_width</a></code>
@@ -1401,7 +1453,7 @@
</tr>
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -1417,7 +1469,7 @@
</tr>
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -1434,7 +1486,7 @@
</tr>
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -1451,7 +1503,7 @@
</tr>
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -1468,7 +1520,7 @@
</tr>
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -1485,6 +1537,23 @@
</tr>
+ <tr class="alt-color api apilevel-" >
+ <td class="jd-typecol"><nobr>
+ public
+ static
+
+ int</nobr></td>
+ <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton_buttonRippleColor">CircularButton_buttonRippleColor</a></td>
+ <td class="jd-descrcol" width="100%">
+ <p>This symbol is the offset where the <code><a href="../../../../reference/android/support/wearable/R.attr.html#buttonRippleColor">buttonRippleColor</a></code>
+ attribute's value can be found in the <code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton">CircularButton</a></code> array.
+
+
+
+ </td>
+ </tr>
+
+
<tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
public
@@ -1508,9 +1577,9 @@
static
int</nobr></td>
- <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton_pressedTranslationZ">CircularButton_pressedTranslationZ</a></td>
+ <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton_pressedButtonTranslationZ">CircularButton_pressedButtonTranslationZ</a></td>
<td class="jd-descrcol" width="100%">
- <p>This symbol is the offset where the <code><a href="../../../../reference/android/support/wearable/R.attr.html#pressedTranslationZ">pressedTranslationZ</a></code>
+ <p>This symbol is the offset where the <code><a href="../../../../reference/android/support/wearable/R.attr.html#pressedButtonTranslationZ">pressedButtonTranslationZ</a></code>
attribute's value can be found in the <code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton">CircularButton</a></code> array.
@@ -1523,23 +1592,6 @@
<td class="jd-typecol"><nobr>
public
static
-
- int</nobr></td>
- <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton_rippleColor">CircularButton_rippleColor</a></td>
- <td class="jd-descrcol" width="100%">
- <p>This symbol is the offset where the <code><a href="../../../../reference/android/support/wearable/R.attr.html#rippleColor">rippleColor</a></code>
- attribute's value can be found in the <code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton">CircularButton</a></code> array.
-
-
-
- </td>
- </tr>
-
-
- <tr class="alt-color api apilevel-" >
- <td class="jd-typecol"><nobr>
- public
- static
final
int[]</nobr></td>
<td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.styleable.html#DelayedConfirmationView">DelayedConfirmationView</a></td>
@@ -1552,7 +1604,7 @@
</tr>
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -1569,7 +1621,7 @@
</tr>
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -1585,7 +1637,7 @@
</tr>
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -1602,7 +1654,7 @@
</tr>
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -1619,7 +1671,7 @@
</tr>
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -1636,7 +1688,7 @@
</tr>
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -1653,7 +1705,7 @@
</tr>
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -1670,7 +1722,7 @@
</tr>
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -1687,7 +1739,7 @@
</tr>
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -1704,7 +1756,7 @@
</tr>
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -1721,7 +1773,7 @@
</tr>
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -1738,7 +1790,7 @@
</tr>
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -1755,7 +1807,7 @@
</tr>
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -1772,7 +1824,7 @@
</tr>
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -1789,7 +1841,7 @@
</tr>
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -1806,10 +1858,43 @@
</tr>
+ <tr class=" api apilevel-" >
+ <td class="jd-typecol"><nobr>
+ public
+ static
+ final
+ int[]</nobr></td>
+ <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.styleable.html#ProgressSpinner">ProgressSpinner</a></td>
+ <td class="jd-descrcol" width="100%">
+ Attributes that can be used with a ProgressSpinner.
+
+
+
+ </td>
+ </tr>
+
+
<tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
+
+ int</nobr></td>
+ <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.styleable.html#ProgressSpinner_color_sequence">ProgressSpinner_color_sequence</a></td>
+ <td class="jd-descrcol" width="100%">
+ <p>This symbol is the offset where the <code><a href="../../../../reference/android/support/wearable/R.attr.html#color_sequence">color_sequence</a></code>
+ attribute's value can be found in the <code><a href="../../../../reference/android/support/wearable/R.styleable.html#ProgressSpinner">ProgressSpinner</a></code> array.
+
+
+
+ </td>
+ </tr>
+
+
+ <tr class=" api apilevel-" >
+ <td class="jd-typecol"><nobr>
+ public
+ static
final
int[]</nobr></td>
<td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.styleable.html#WatchViewStub">WatchViewStub</a></td>
@@ -1822,7 +1907,7 @@
</tr>
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -1839,7 +1924,7 @@
</tr>
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -1856,7 +1941,7 @@
</tr>
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -1872,7 +1957,7 @@
</tr>
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -1889,7 +1974,7 @@
</tr>
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -1906,7 +1991,7 @@
</tr>
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -1923,7 +2008,7 @@
</tr>
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -1940,7 +2025,7 @@
</tr>
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -1957,7 +2042,7 @@
</tr>
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -1974,7 +2059,7 @@
</tr>
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -1991,7 +2076,7 @@
</tr>
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -2008,7 +2093,7 @@
</tr>
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -2025,7 +2110,7 @@
</tr>
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -2042,7 +2127,7 @@
</tr>
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -2059,7 +2144,7 @@
</tr>
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -2076,7 +2161,7 @@
</tr>
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -2092,7 +2177,7 @@
</tr>
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -2109,7 +2194,7 @@
</tr>
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
public
static
@@ -2875,15 +2960,15 @@
<tr><td><code><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_textColor">android:textColor</a></code></code></td><td></td></tr>
<tr><td><code><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_textStyle">android:textStyle</a></code></code></td><td></td></tr>
<tr><td><code><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_typeface">android:typeface</a></code></code></td><td></td></tr>
+ <tr><td><code><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_buttonRippleColor">android.support.wearable:buttonRippleColor</a></code></code></td><td></td></tr>
<tr><td><code><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_imageScaleMode">android.support.wearable:imageScaleMode</a></code></code></td><td></td></tr>
<tr><td><code><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_maxTextSize">android.support.wearable:maxTextSize</a></code></code></td><td></td></tr>
<tr><td><code><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_minTextSize">android.support.wearable:minTextSize</a></code></code></td><td></td></tr>
- <tr><td><code><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_pressedTranslationZ">android.support.wearable:pressedTranslationZ</a></code></code></td><td></td></tr>
- <tr><td><code><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_rippleColor">android.support.wearable:rippleColor</a></code></code></td><td></td></tr>
+ <tr><td><code><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_pressedButtonTranslationZ">android.support.wearable:pressedButtonTranslationZ</a></code></code></td><td></td></tr>
</table></p></div>
<div class="jd-tagdata">
<h5 class="jd-tagtitle">See Also</h5>
- <ul class="nolist"><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_color">ActionPage_android_color</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_elevation">ActionPage_android_elevation</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_fontFamily">ActionPage_android_fontFamily</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_gravity">ActionPage_android_gravity</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_lineSpacingExtra">ActionPage_android_lineSpacingExtra</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_lineSpacingMultiplier">ActionPage_android_lineSpacingMultiplier</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_maxLines">ActionPage_android_maxLines</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_src">ActionPage_android_src</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_stateListAnimator">ActionPage_android_stateListAnimator</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_text">ActionPage_android_text</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_textColor">ActionPage_android_textColor</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_textStyle">ActionPage_android_textStyle</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_typeface">ActionPage_android_typeface</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_imageScaleMode">ActionPage_imageScaleMode</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_maxTextSize">ActionPage_maxTextSize</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_minTextSize">ActionPage_minTextSize</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_pressedTranslationZ">ActionPage_pressedTranslationZ</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_rippleColor">ActionPage_rippleColor</a></code></li>
+ <ul class="nolist"><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_color">ActionPage_android_color</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_elevation">ActionPage_android_elevation</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_fontFamily">ActionPage_android_fontFamily</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_gravity">ActionPage_android_gravity</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_lineSpacingExtra">ActionPage_android_lineSpacingExtra</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_lineSpacingMultiplier">ActionPage_android_lineSpacingMultiplier</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_maxLines">ActionPage_android_maxLines</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_src">ActionPage_android_src</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_stateListAnimator">ActionPage_android_stateListAnimator</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_text">ActionPage_android_text</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_textColor">ActionPage_android_textColor</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_textStyle">ActionPage_android_textStyle</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_typeface">ActionPage_android_typeface</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_buttonRippleColor">ActionPage_buttonRippleColor</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_imageScaleMode">ActionPage_imageScaleMode</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_maxTextSize">ActionPage_maxTextSize</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_minTextSize">ActionPage_minTextSize</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_pressedButtonTranslationZ">ActionPage_pressedButtonTranslationZ</a></code></li>
</ul>
</div>
@@ -3309,6 +3394,44 @@
+<A NAME="ActionPage_buttonRippleColor"></A>
+
+<div class="jd-details api apilevel-">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ public
+ static
+
+ int
+ </span>
+ ActionPage_buttonRippleColor
+ </h4>
+ <div class="api-level">
+
+
+
+
+ </div>
+ <div class="jd-details-descr">
+
+
+
+
+ <div class="jd-tagdata jd-tagdescr"><p><p>This symbol is the offset where the <code><a href="../../../../reference/android/support/wearable/R.attr.html#buttonRippleColor">buttonRippleColor</a></code>
+ attribute's value can be found in the <code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage">ActionPage</a></code> array.
+
+
+ <p>May be a reference to another resource, in the form "<code>@[+][<i>package</i>:]<i>type</i>:<i>name</i></code>"
+or to a theme attribute in the form "<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>".
+<p>May be a color value, in the form of "<code>#<i>rgb</i></code>", "<code>#<i>argb</i></code>",
+"<code>#<i>rrggbb</i></code>", or "<code>#<i>aarrggbb</i></code>".</p></div>
+
+
+ </div>
+</div>
+
+
+
<A NAME="ActionPage_imageScaleMode"></A>
<div class="jd-details api apilevel-">
@@ -3436,7 +3559,7 @@
-<A NAME="ActionPage_pressedTranslationZ"></A>
+<A NAME="ActionPage_pressedButtonTranslationZ"></A>
<div class="jd-details api apilevel-">
<h4 class="jd-details-title">
@@ -3446,7 +3569,7 @@
int
</span>
- ActionPage_pressedTranslationZ
+ ActionPage_pressedButtonTranslationZ
</h4>
<div class="api-level">
@@ -3459,7 +3582,7 @@
- <div class="jd-tagdata jd-tagdescr"><p><p>This symbol is the offset where the <code><a href="../../../../reference/android/support/wearable/R.attr.html#pressedTranslationZ">pressedTranslationZ</a></code>
+ <div class="jd-tagdata jd-tagdescr"><p><p>This symbol is the offset where the <code><a href="../../../../reference/android/support/wearable/R.attr.html#pressedButtonTranslationZ">pressedButtonTranslationZ</a></code>
attribute's value can be found in the <code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage">ActionPage</a></code> array.
@@ -3478,44 +3601,6 @@
-<A NAME="ActionPage_rippleColor"></A>
-
-<div class="jd-details api apilevel-">
- <h4 class="jd-details-title">
- <span class="normal">
- public
- static
-
- int
- </span>
- ActionPage_rippleColor
- </h4>
- <div class="api-level">
-
-
-
-
- </div>
- <div class="jd-details-descr">
-
-
-
-
- <div class="jd-tagdata jd-tagdescr"><p><p>This symbol is the offset where the <code><a href="../../../../reference/android/support/wearable/R.attr.html#rippleColor">rippleColor</a></code>
- attribute's value can be found in the <code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage">ActionPage</a></code> array.
-
-
- <p>May be a reference to another resource, in the form "<code>@[+][<i>package</i>:]<i>type</i>:<i>name</i></code>"
-or to a theme attribute in the form "<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>".
-<p>May be a color value, in the form of "<code>#<i>rgb</i></code>", "<code>#<i>argb</i></code>",
-"<code>#<i>rrggbb</i></code>", or "<code>#<i>aarrggbb</i></code>".</p></div>
-
-
- </div>
-</div>
-
-
-
<A NAME="BoxInsetLayout_Layout"></A>
<div class="jd-details api apilevel-">
@@ -3641,11 +3726,14 @@
<tr><td><code><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_circle_padding">android.support.wearable:circle_padding</a></code></code></td><td></td></tr>
<tr><td><code><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_circle_radius">android.support.wearable:circle_radius</a></code></code></td><td></td></tr>
<tr><td><code><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_circle_radius_pressed">android.support.wearable:circle_radius_pressed</a></code></code></td><td></td></tr>
+ <tr><td><code><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_image_circle_percentage">android.support.wearable:image_circle_percentage</a></code></code></td><td></td></tr>
+ <tr><td><code><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_image_horizontal_offcenter_percentage">android.support.wearable:image_horizontal_offcenter_percentage</a></code></code></td><td></td></tr>
+ <tr><td><code><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_image_tint">android.support.wearable:image_tint</a></code></code></td><td></td></tr>
<tr><td><code><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_shadow_width">android.support.wearable:shadow_width</a></code></code></td><td></td></tr>
</table></p></div>
<div class="jd-tagdata">
<h5 class="jd-tagtitle">See Also</h5>
- <ul class="nolist"><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_android_src">CircledImageView_android_src</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_circle_border_color">CircledImageView_circle_border_color</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_circle_border_width">CircledImageView_circle_border_width</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_circle_color">CircledImageView_circle_color</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_circle_padding">CircledImageView_circle_padding</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_circle_radius">CircledImageView_circle_radius</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_circle_radius_pressed">CircledImageView_circle_radius_pressed</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_shadow_width">CircledImageView_shadow_width</a></code></li>
+ <ul class="nolist"><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_android_src">CircledImageView_android_src</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_circle_border_color">CircledImageView_circle_border_color</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_circle_border_width">CircledImageView_circle_border_width</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_circle_color">CircledImageView_circle_color</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_circle_padding">CircledImageView_circle_padding</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_circle_radius">CircledImageView_circle_radius</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_circle_radius_pressed">CircledImageView_circle_radius_pressed</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_image_circle_percentage">CircledImageView_image_circle_percentage</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_image_horizontal_offcenter_percentage">CircledImageView_image_horizontal_offcenter_percentage</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_image_tint">CircledImageView_image_tint</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_shadow_width">CircledImageView_shadow_width</a></code></li>
</ul>
</div>
@@ -3937,6 +4025,131 @@
+<A NAME="CircledImageView_image_circle_percentage"></A>
+
+<div class="jd-details api apilevel-">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ public
+ static
+
+ int
+ </span>
+ CircledImageView_image_circle_percentage
+ </h4>
+ <div class="api-level">
+
+
+
+
+ </div>
+ <div class="jd-details-descr">
+
+
+
+
+ <div class="jd-tagdata jd-tagdescr"><p><p>This symbol is the offset where the <code><a href="../../../../reference/android/support/wearable/R.attr.html#image_circle_percentage">image_circle_percentage</a></code>
+ attribute's value can be found in the <code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView">CircledImageView</a></code> array.
+
+
+ <p>Must be a dimension value, which is a floating point number appended with a unit such as "<code>14.5sp</code>".
+Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size),
+in (inches), mm (millimeters).
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.</p></div>
+
+
+ </div>
+</div>
+
+
+
+<A NAME="CircledImageView_image_horizontal_offcenter_percentage"></A>
+
+<div class="jd-details api apilevel-">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ public
+ static
+
+ int
+ </span>
+ CircledImageView_image_horizontal_offcenter_percentage
+ </h4>
+ <div class="api-level">
+
+
+
+
+ </div>
+ <div class="jd-details-descr">
+
+
+
+
+ <div class="jd-tagdata jd-tagdescr"><p><p>This symbol is the offset where the <code><a href="../../../../reference/android/support/wearable/R.attr.html#image_horizontal_offcenter_percentage">image_horizontal_offcenter_percentage</a></code>
+ attribute's value can be found in the <code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView">CircledImageView</a></code> array.
+
+
+ <p>Must be a dimension value, which is a floating point number appended with a unit such as "<code>14.5sp</code>".
+Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size),
+in (inches), mm (millimeters).
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.</p></div>
+
+
+ </div>
+</div>
+
+
+
+<A NAME="CircledImageView_image_tint"></A>
+
+<div class="jd-details api apilevel-">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ public
+ static
+
+ int
+ </span>
+ CircledImageView_image_tint
+ </h4>
+ <div class="api-level">
+
+
+
+
+ </div>
+ <div class="jd-details-descr">
+
+
+
+
+ <div class="jd-tagdata jd-tagdescr"><p><p>This symbol is the offset where the <code><a href="../../../../reference/android/support/wearable/R.attr.html#image_tint">image_tint</a></code>
+ attribute's value can be found in the <code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView">CircledImageView</a></code> array.
+
+
+ <p>Must be a color value, in the form of "<code>#<i>rgb</i></code>", "<code>#<i>argb</i></code>",
+"<code>#<i>rrggbb</i></code>", or "<code>#<i>aarrggbb</i></code>".
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.</p></div>
+
+
+ </div>
+</div>
+
+
+
<A NAME="CircledImageView_shadow_width"></A>
<div class="jd-details api apilevel-">
@@ -4012,13 +4225,13 @@
<tr><td><code><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton_android_elevation">android:elevation</a></code></code></td><td></td></tr>
<tr><td><code><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton_android_src">android:src</a></code></code></td><td></td></tr>
<tr><td><code><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton_android_stateListAnimator">android:stateListAnimator</a></code></code></td><td></td></tr>
+ <tr><td><code><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton_buttonRippleColor">android.support.wearable:buttonRippleColor</a></code></code></td><td></td></tr>
<tr><td><code><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton_imageScaleMode">android.support.wearable:imageScaleMode</a></code></code></td><td></td></tr>
- <tr><td><code><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton_pressedTranslationZ">android.support.wearable:pressedTranslationZ</a></code></code></td><td></td></tr>
- <tr><td><code><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton_rippleColor">android.support.wearable:rippleColor</a></code></code></td><td></td></tr>
+ <tr><td><code><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton_pressedButtonTranslationZ">android.support.wearable:pressedButtonTranslationZ</a></code></code></td><td></td></tr>
</table></p></div>
<div class="jd-tagdata">
<h5 class="jd-tagtitle">See Also</h5>
- <ul class="nolist"><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton_android_color">CircularButton_android_color</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton_android_elevation">CircularButton_android_elevation</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton_android_src">CircularButton_android_src</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton_android_stateListAnimator">CircularButton_android_stateListAnimator</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton_imageScaleMode">CircularButton_imageScaleMode</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton_pressedTranslationZ">CircularButton_pressedTranslationZ</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton_rippleColor">CircularButton_rippleColor</a></code></li>
+ <ul class="nolist"><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton_android_color">CircularButton_android_color</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton_android_elevation">CircularButton_android_elevation</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton_android_src">CircularButton_android_src</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton_android_stateListAnimator">CircularButton_android_stateListAnimator</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton_buttonRippleColor">CircularButton_buttonRippleColor</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton_imageScaleMode">CircularButton_imageScaleMode</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton_pressedButtonTranslationZ">CircularButton_pressedButtonTranslationZ</a></code></li>
</ul>
</div>
@@ -4156,6 +4369,44 @@
+<A NAME="CircularButton_buttonRippleColor"></A>
+
+<div class="jd-details api apilevel-">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ public
+ static
+
+ int
+ </span>
+ CircularButton_buttonRippleColor
+ </h4>
+ <div class="api-level">
+
+
+
+
+ </div>
+ <div class="jd-details-descr">
+
+
+
+
+ <div class="jd-tagdata jd-tagdescr"><p><p>This symbol is the offset where the <code><a href="../../../../reference/android/support/wearable/R.attr.html#buttonRippleColor">buttonRippleColor</a></code>
+ attribute's value can be found in the <code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton">CircularButton</a></code> array.
+
+
+ <p>May be a reference to another resource, in the form "<code>@[+][<i>package</i>:]<i>type</i>:<i>name</i></code>"
+or to a theme attribute in the form "<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>".
+<p>May be a color value, in the form of "<code>#<i>rgb</i></code>", "<code>#<i>argb</i></code>",
+"<code>#<i>rrggbb</i></code>", or "<code>#<i>aarrggbb</i></code>".</p></div>
+
+
+ </div>
+</div>
+
+
+
<A NAME="CircularButton_imageScaleMode"></A>
<div class="jd-details api apilevel-">
@@ -4199,7 +4450,7 @@
-<A NAME="CircularButton_pressedTranslationZ"></A>
+<A NAME="CircularButton_pressedButtonTranslationZ"></A>
<div class="jd-details api apilevel-">
<h4 class="jd-details-title">
@@ -4209,7 +4460,7 @@
int
</span>
- CircularButton_pressedTranslationZ
+ CircularButton_pressedButtonTranslationZ
</h4>
<div class="api-level">
@@ -4222,7 +4473,7 @@
- <div class="jd-tagdata jd-tagdescr"><p><p>This symbol is the offset where the <code><a href="../../../../reference/android/support/wearable/R.attr.html#pressedTranslationZ">pressedTranslationZ</a></code>
+ <div class="jd-tagdata jd-tagdescr"><p><p>This symbol is the offset where the <code><a href="../../../../reference/android/support/wearable/R.attr.html#pressedButtonTranslationZ">pressedButtonTranslationZ</a></code>
attribute's value can be found in the <code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton">CircularButton</a></code> array.
@@ -4241,44 +4492,6 @@
-<A NAME="CircularButton_rippleColor"></A>
-
-<div class="jd-details api apilevel-">
- <h4 class="jd-details-title">
- <span class="normal">
- public
- static
-
- int
- </span>
- CircularButton_rippleColor
- </h4>
- <div class="api-level">
-
-
-
-
- </div>
- <div class="jd-details-descr">
-
-
-
-
- <div class="jd-tagdata jd-tagdescr"><p><p>This symbol is the offset where the <code><a href="../../../../reference/android/support/wearable/R.attr.html#rippleColor">rippleColor</a></code>
- attribute's value can be found in the <code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton">CircularButton</a></code> array.
-
-
- <p>May be a reference to another resource, in the form "<code>@[+][<i>package</i>:]<i>type</i>:<i>name</i></code>"
-or to a theme attribute in the form "<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>".
-<p>May be a color value, in the form of "<code>#<i>rgb</i></code>", "<code>#<i>argb</i></code>",
-"<code>#<i>rrggbb</i></code>", or "<code>#<i>aarrggbb</i></code>".</p></div>
-
-
- </div>
-</div>
-
-
-
<A NAME="DelayedConfirmationView"></A>
<div class="jd-details api apilevel-">
@@ -4952,6 +5165,87 @@
+<A NAME="ProgressSpinner"></A>
+
+<div class="jd-details api apilevel-">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ public
+ static
+ final
+ int[]
+ </span>
+ ProgressSpinner
+ </h4>
+ <div class="api-level">
+
+
+
+
+ </div>
+ <div class="jd-details-descr">
+
+
+
+
+ <div class="jd-tagdata jd-tagdescr"><p>Attributes that can be used with a ProgressSpinner.
+ <p>Includes the following attributes:</p>
+ <table>
+ <colgroup align="left" />
+ <colgroup align="left" />
+ <tr><th>Attribute</th><th>Description</th></tr>
+ <tr><td><code><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ProgressSpinner_color_sequence">android.support.wearable:color_sequence</a></code></code></td><td></td></tr>
+ </table></p></div>
+ <div class="jd-tagdata">
+ <h5 class="jd-tagtitle">See Also</h5>
+ <ul class="nolist"><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ProgressSpinner_color_sequence">ProgressSpinner_color_sequence</a></code></li>
+ </ul>
+ </div>
+
+
+ </div>
+</div>
+
+
+
+<A NAME="ProgressSpinner_color_sequence"></A>
+
+<div class="jd-details api apilevel-">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ public
+ static
+
+ int
+ </span>
+ ProgressSpinner_color_sequence
+ </h4>
+ <div class="api-level">
+
+
+
+
+ </div>
+ <div class="jd-details-descr">
+
+
+
+
+ <div class="jd-tagdata jd-tagdescr"><p><p>This symbol is the offset where the <code><a href="../../../../reference/android/support/wearable/R.attr.html#color_sequence">color_sequence</a></code>
+ attribute's value can be found in the <code><a href="../../../../reference/android/support/wearable/R.styleable.html#ProgressSpinner">ProgressSpinner</a></code> array.
+
+
+ <p>May be a reference to another resource, in the form "<code>@[+][<i>package</i>:]<i>type</i>:<i>name</i></code>"
+or to a theme attribute in the form "<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>".
+<p>May be a color value, in the form of "<code>#<i>rgb</i></code>", "<code>#<i>argb</i></code>",
+"<code>#<i>rrggbb</i></code>", or "<code>#<i>aarrggbb</i></code>".</p></div>
+
+
+ </div>
+</div>
+
+
+
<A NAME="WatchViewStub"></A>
<div class="jd-details api apilevel-">
@@ -5847,6 +6141,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/activity/ConfirmationActivity.html b/docs/html/reference/android/support/wearable/activity/ConfirmationActivity.html
index f7cd613..92bfeca 100644
--- a/docs/html/reference/android/support/wearable/activity/ConfirmationActivity.html
+++ b/docs/html/reference/android/support/wearable/activity/ConfirmationActivity.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -713,7 +713,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -10110,6 +10110,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/activity/WearableActivity.html b/docs/html/reference/android/support/wearable/activity/WearableActivity.html
index 2698dca..6f70f74 100644
--- a/docs/html/reference/android/support/wearable/activity/WearableActivity.html
+++ b/docs/html/reference/android/support/wearable/activity/WearableActivity.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -716,7 +716,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -10513,6 +10513,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/activity/package-summary.html b/docs/html/reference/android/support/wearable/activity/package-summary.html
index 4dd01b7..e3a691a 100644
--- a/docs/html/reference/android/support/wearable/activity/package-summary.html
+++ b/docs/html/reference/android/support/wearable/activity/package-summary.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -542,7 +542,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
@@ -654,6 +654,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/companion/WatchFaceCompanion.html b/docs/html/reference/android/support/wearable/companion/WatchFaceCompanion.html
index ce369f2..8174777 100644
--- a/docs/html/reference/android/support/wearable/companion/WatchFaceCompanion.html
+++ b/docs/html/reference/android/support/wearable/companion/WatchFaceCompanion.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -599,7 +599,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -1158,6 +1158,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/companion/package-summary.html b/docs/html/reference/android/support/wearable/companion/package-summary.html
index 0447708..7404dcd 100644
--- a/docs/html/reference/android/support/wearable/companion/package-summary.html
+++ b/docs/html/reference/android/support/wearable/companion/package-summary.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -541,7 +541,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
@@ -641,6 +641,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/input/RemoteInputConstants.html b/docs/html/reference/android/support/wearable/input/RemoteInputConstants.html
index f3cb90c..35fe2d5 100644
--- a/docs/html/reference/android/support/wearable/input/RemoteInputConstants.html
+++ b/docs/html/reference/android/support/wearable/input/RemoteInputConstants.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -603,7 +603,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -1151,6 +1151,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/input/RemoteInputIntent.html b/docs/html/reference/android/support/wearable/input/RemoteInputIntent.html
index 92d90bc..34ae2d5 100644
--- a/docs/html/reference/android/support/wearable/input/RemoteInputIntent.html
+++ b/docs/html/reference/android/support/wearable/input/RemoteInputIntent.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -603,7 +603,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -644,7 +644,7 @@
new RemoteInput.Builder(KEY_QUICK_REPLY_TEXT).setLabel("Quick reply").build()
};
Intent intent = new Intent(ACTION_REMOTE_INPUT);
- intent.putExtra(EXTRA_REMOTE_INPUT, remoteInputs);
+ intent.putExtra(EXTRA_REMOTE_INPUTS, remoteInputs);
startActivity(intent);
</pre>
@@ -1496,6 +1496,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/input/package-summary.html b/docs/html/reference/android/support/wearable/input/package-summary.html
index 2071e28..314838d 100644
--- a/docs/html/reference/android/support/wearable/input/package-summary.html
+++ b/docs/html/reference/android/support/wearable/input/package-summary.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -542,7 +542,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
@@ -653,6 +653,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/media/MediaControlConstants.html b/docs/html/reference/android/support/wearable/media/MediaControlConstants.html
index 42c141b..30ddc45 100644
--- a/docs/html/reference/android/support/wearable/media/MediaControlConstants.html
+++ b/docs/html/reference/android/support/wearable/media/MediaControlConstants.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -602,7 +602,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -1370,6 +1370,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/media/package-summary.html b/docs/html/reference/android/support/wearable/media/package-summary.html
index 3310b5a..72dce84 100644
--- a/docs/html/reference/android/support/wearable/media/package-summary.html
+++ b/docs/html/reference/android/support/wearable/media/package-summary.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -541,7 +541,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
@@ -641,6 +641,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/package-summary.html b/docs/html/reference/android/support/wearable/package-summary.html
index a8e3db057..a4ef376 100644
--- a/docs/html/reference/android/support/wearable/package-summary.html
+++ b/docs/html/reference/android/support/wearable/package-summary.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -474,6 +474,7 @@
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.html">R</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.anim.html">R.anim</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.animator.html">R.animator</a></li>
+ <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.array.html">R.array</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.attr.html">R.attr</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.color.html">R.color</a></li>
<li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.dimen.html">R.dimen</a></li>
@@ -553,7 +554,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
@@ -607,6 +608,17 @@
<tr class=" api apilevel-" >
+ <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.array.html">R.array</a></td>
+ <td class="jd-descrcol" width="100%">
+
+
+
+
+ </td>
+ </tr>
+
+
+ <tr class="alt-color api apilevel-" >
<td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.attr.html">R.attr</a></td>
<td class="jd-descrcol" width="100%">
@@ -617,7 +629,7 @@
</tr>
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.color.html">R.color</a></td>
<td class="jd-descrcol" width="100%">
@@ -628,7 +640,7 @@
</tr>
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.dimen.html">R.dimen</a></td>
<td class="jd-descrcol" width="100%">
@@ -639,7 +651,7 @@
</tr>
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.drawable.html">R.drawable</a></td>
<td class="jd-descrcol" width="100%">
@@ -650,7 +662,7 @@
</tr>
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.id.html">R.id</a></td>
<td class="jd-descrcol" width="100%">
@@ -661,7 +673,7 @@
</tr>
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.interpolator.html">R.interpolator</a></td>
<td class="jd-descrcol" width="100%">
@@ -672,7 +684,7 @@
</tr>
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.layout.html">R.layout</a></td>
<td class="jd-descrcol" width="100%">
@@ -683,7 +695,7 @@
</tr>
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.string.html">R.string</a></td>
<td class="jd-descrcol" width="100%">
@@ -694,7 +706,7 @@
</tr>
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.style.html">R.style</a></td>
<td class="jd-descrcol" width="100%">
@@ -705,7 +717,7 @@
</tr>
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.styleable.html">R.styleable</a></td>
<td class="jd-descrcol" width="100%">
@@ -785,6 +797,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/provider/WearableCalendarContract.Attendees.html b/docs/html/reference/android/support/wearable/provider/WearableCalendarContract.Attendees.html
index ba439b3..794973f 100644
--- a/docs/html/reference/android/support/wearable/provider/WearableCalendarContract.Attendees.html
+++ b/docs/html/reference/android/support/wearable/provider/WearableCalendarContract.Attendees.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -602,7 +602,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -1063,6 +1063,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/provider/WearableCalendarContract.Instances.html b/docs/html/reference/android/support/wearable/provider/WearableCalendarContract.Instances.html
index 70ad4d9..77c3c67 100644
--- a/docs/html/reference/android/support/wearable/provider/WearableCalendarContract.Instances.html
+++ b/docs/html/reference/android/support/wearable/provider/WearableCalendarContract.Instances.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -602,7 +602,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -1063,6 +1063,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/provider/WearableCalendarContract.Reminders.html b/docs/html/reference/android/support/wearable/provider/WearableCalendarContract.Reminders.html
index 752da5e..9dfd7f7 100644
--- a/docs/html/reference/android/support/wearable/provider/WearableCalendarContract.Reminders.html
+++ b/docs/html/reference/android/support/wearable/provider/WearableCalendarContract.Reminders.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -602,7 +602,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -1063,6 +1063,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/provider/WearableCalendarContract.html b/docs/html/reference/android/support/wearable/provider/WearableCalendarContract.html
index 919306b..588ae71 100644
--- a/docs/html/reference/android/support/wearable/provider/WearableCalendarContract.html
+++ b/docs/html/reference/android/support/wearable/provider/WearableCalendarContract.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -611,7 +611,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -1265,6 +1265,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/provider/package-summary.html b/docs/html/reference/android/support/wearable/provider/package-summary.html
index f82ce5c..bb4c581 100644
--- a/docs/html/reference/android/support/wearable/provider/package-summary.html
+++ b/docs/html/reference/android/support/wearable/provider/package-summary.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -544,7 +544,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
@@ -677,6 +677,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/ActionLabel.html b/docs/html/reference/android/support/wearable/view/ActionLabel.html
index 3716018..f8cb733 100644
--- a/docs/html/reference/android/support/wearable/view/ActionLabel.html
+++ b/docs/html/reference/android/support/wearable/view/ActionLabel.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -501,6 +501,7 @@
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+ <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -684,7 +685,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -12362,6 +12363,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/ActionPage.html b/docs/html/reference/android/support/wearable/view/ActionPage.html
index 268bba1..69c4dfb 100644
--- a/docs/html/reference/android/support/wearable/view/ActionPage.html
+++ b/docs/html/reference/android/support/wearable/view/ActionPage.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -501,6 +501,7 @@
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+ <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -714,7 +715,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -15449,6 +15450,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/BoxInsetLayout.LayoutParams.html b/docs/html/reference/android/support/wearable/view/BoxInsetLayout.LayoutParams.html
index 43097b4..d716836 100644
--- a/docs/html/reference/android/support/wearable/view/BoxInsetLayout.LayoutParams.html
+++ b/docs/html/reference/android/support/wearable/view/BoxInsetLayout.LayoutParams.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -501,6 +501,7 @@
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+ <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -687,7 +688,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -2431,6 +2432,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/BoxInsetLayout.html b/docs/html/reference/android/support/wearable/view/BoxInsetLayout.html
index 5619e75..d315135 100644
--- a/docs/html/reference/android/support/wearable/view/BoxInsetLayout.html
+++ b/docs/html/reference/android/support/wearable/view/BoxInsetLayout.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -501,6 +501,7 @@
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+ <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -725,7 +726,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -15573,6 +15574,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/CardFragment.html b/docs/html/reference/android/support/wearable/view/CardFragment.html
index 9437e93..b73c6ca 100644
--- a/docs/html/reference/android/support/wearable/view/CardFragment.html
+++ b/docs/html/reference/android/support/wearable/view/CardFragment.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -501,6 +501,7 @@
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+ <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -679,7 +680,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -4875,6 +4876,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/CardFrame.html b/docs/html/reference/android/support/wearable/view/CardFrame.html
index 1beeda2..32224d5 100644
--- a/docs/html/reference/android/support/wearable/view/CardFrame.html
+++ b/docs/html/reference/android/support/wearable/view/CardFrame.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -501,6 +501,7 @@
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+ <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -714,7 +715,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -15930,6 +15931,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/CardScrollView.html b/docs/html/reference/android/support/wearable/view/CardScrollView.html
index 0364eb9..a361847 100644
--- a/docs/html/reference/android/support/wearable/view/CardScrollView.html
+++ b/docs/html/reference/android/support/wearable/view/CardScrollView.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -501,6 +501,7 @@
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+ <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -722,7 +723,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -15898,6 +15899,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/CircledImageView.html b/docs/html/reference/android/support/wearable/view/CircledImageView.html
index 1c9451b..a2ba3f7 100644
--- a/docs/html/reference/android/support/wearable/view/CircledImageView.html
+++ b/docs/html/reference/android/support/wearable/view/CircledImageView.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -501,6 +501,7 @@
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+ <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -684,7 +685,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -2857,12 +2858,44 @@
void</nobr>
</td>
<td class="jd-linkcol" width="100%"><nobr>
+ <span class="sympad"><a href="../../../../../reference/android/support/wearable/view/CircledImageView.html#setImageCirclePercentage(float)">setImageCirclePercentage</a></span>(float percentage)</nobr>
+
+ </td></tr>
+
+
+
+ <tr class=" api apilevel-" >
+ <td class="jd-typecol"><nobr>
+
+
+
+
+
+ void</nobr>
+ </td>
+ <td class="jd-linkcol" width="100%"><nobr>
<span class="sympad"><a href="../../../../../reference/android/support/wearable/view/CircledImageView.html#setImageDrawable(android.graphics.drawable.Drawable)">setImageDrawable</a></span>(Drawable drawable)</nobr>
</td></tr>
+ <tr class="alt-color api apilevel-" >
+ <td class="jd-typecol"><nobr>
+
+
+
+
+
+ void</nobr>
+ </td>
+ <td class="jd-linkcol" width="100%"><nobr>
+ <span class="sympad"><a href="../../../../../reference/android/support/wearable/view/CircledImageView.html#setImageHorizontalOffcenterPercentage(float)">setImageHorizontalOffcenterPercentage</a></span>(float percentage)</nobr>
+
+ </td></tr>
+
+
+
<tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -2889,7 +2922,7 @@
void</nobr>
</td>
<td class="jd-linkcol" width="100%"><nobr>
- <span class="sympad"><a href="../../../../../reference/android/support/wearable/view/CircledImageView.html#setPressed(boolean)">setPressed</a></span>(boolean pressed)</nobr>
+ <span class="sympad"><a href="../../../../../reference/android/support/wearable/view/CircledImageView.html#setImageTint(int)">setImageTint</a></span>(int tint)</nobr>
</td></tr>
@@ -2905,7 +2938,7 @@
void</nobr>
</td>
<td class="jd-linkcol" width="100%"><nobr>
- <span class="sympad"><a href="../../../../../reference/android/support/wearable/view/CircledImageView.html#setProgress(float)">setProgress</a></span>(float progress)</nobr>
+ <span class="sympad"><a href="../../../../../reference/android/support/wearable/view/CircledImageView.html#setPressed(boolean)">setPressed</a></span>(boolean pressed)</nobr>
</td></tr>
@@ -2921,6 +2954,22 @@
void</nobr>
</td>
<td class="jd-linkcol" width="100%"><nobr>
+ <span class="sympad"><a href="../../../../../reference/android/support/wearable/view/CircledImageView.html#setProgress(float)">setProgress</a></span>(float progress)</nobr>
+
+ </td></tr>
+
+
+
+ <tr class=" api apilevel-" >
+ <td class="jd-typecol"><nobr>
+
+
+
+
+
+ void</nobr>
+ </td>
+ <td class="jd-linkcol" width="100%"><nobr>
<span class="sympad"><a href="../../../../../reference/android/support/wearable/view/CircledImageView.html#setShadowVisibility(float)">setShadowVisibility</a></span>(float shadowVisibility)</nobr>
<div class="jd-descrdiv">
@@ -2934,7 +2983,7 @@
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -11857,6 +11906,38 @@
</div>
+<A NAME="setImageCirclePercentage(float)"></A>
+
+<div class="jd-details api apilevel-">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ public
+
+
+
+
+ void
+ </span>
+ <span class="sympad">setImageCirclePercentage</span>
+ <span class="normal">(float percentage)</span>
+ </h4>
+ <div class="api-level">
+ <div></div>
+
+
+
+ </div>
+ <div class="jd-details-descr">
+
+
+
+
+ <div class="jd-tagdata jd-tagdescr"><p></p></div>
+
+ </div>
+</div>
+
+
<A NAME="setImageDrawable(android.graphics.drawable.Drawable)"></A>
<div class="jd-details api apilevel-">
@@ -11889,6 +11970,38 @@
</div>
+<A NAME="setImageHorizontalOffcenterPercentage(float)"></A>
+
+<div class="jd-details api apilevel-">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ public
+
+
+
+
+ void
+ </span>
+ <span class="sympad">setImageHorizontalOffcenterPercentage</span>
+ <span class="normal">(float percentage)</span>
+ </h4>
+ <div class="api-level">
+ <div></div>
+
+
+
+ </div>
+ <div class="jd-details-descr">
+
+
+
+
+ <div class="jd-tagdata jd-tagdescr"><p></p></div>
+
+ </div>
+</div>
+
+
<A NAME="setImageResource(int)"></A>
<div class="jd-details api apilevel-">
@@ -11921,6 +12034,38 @@
</div>
+<A NAME="setImageTint(int)"></A>
+
+<div class="jd-details api apilevel-">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ public
+
+
+
+
+ void
+ </span>
+ <span class="sympad">setImageTint</span>
+ <span class="normal">(int tint)</span>
+ </h4>
+ <div class="api-level">
+ <div></div>
+
+
+
+ </div>
+ <div class="jd-details-descr">
+
+
+
+
+ <div class="jd-tagdata jd-tagdescr"><p></p></div>
+
+ </div>
+</div>
+
+
<A NAME="setPressed(boolean)"></A>
<div class="jd-details api apilevel-">
@@ -12330,6 +12475,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/CircularButton.html b/docs/html/reference/android/support/wearable/view/CircularButton.html
index edcb3f2..ff626ce 100644
--- a/docs/html/reference/android/support/wearable/view/CircularButton.html
+++ b/docs/html/reference/android/support/wearable/view/CircularButton.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -501,6 +501,7 @@
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+ <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -687,7 +688,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -11986,6 +11987,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/CrossfadeDrawable.html b/docs/html/reference/android/support/wearable/view/CrossfadeDrawable.html
index f346b82..176e532 100644
--- a/docs/html/reference/android/support/wearable/view/CrossfadeDrawable.html
+++ b/docs/html/reference/android/support/wearable/view/CrossfadeDrawable.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -501,6 +501,7 @@
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+ <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -665,7 +666,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -3562,6 +3563,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/DelayedConfirmationView.DelayedConfirmationListener.html b/docs/html/reference/android/support/wearable/view/DelayedConfirmationView.DelayedConfirmationListener.html
index 6159875..459b683 100644
--- a/docs/html/reference/android/support/wearable/view/DelayedConfirmationView.DelayedConfirmationListener.html
+++ b/docs/html/reference/android/support/wearable/view/DelayedConfirmationView.DelayedConfirmationListener.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -501,6 +501,7 @@
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+ <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -602,7 +603,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -908,6 +909,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/DelayedConfirmationView.html b/docs/html/reference/android/support/wearable/view/DelayedConfirmationView.html
index 3b61bf0..10e10b9 100644
--- a/docs/html/reference/android/support/wearable/view/DelayedConfirmationView.html
+++ b/docs/html/reference/android/support/wearable/view/DelayedConfirmationView.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -501,6 +501,7 @@
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+ <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -698,7 +699,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -3164,12 +3165,44 @@
void</nobr>
</td>
<td class="jd-linkcol" width="100%"><nobr>
+ <span class="sympad"><a href="../../../../../reference/android/support/wearable/view/CircledImageView.html#setImageCirclePercentage(float)">setImageCirclePercentage</a></span>(float percentage)</nobr>
+
+ </td></tr>
+
+
+
+ <tr class=" api apilevel-" >
+ <td class="jd-typecol"><nobr>
+
+
+
+
+
+ void</nobr>
+ </td>
+ <td class="jd-linkcol" width="100%"><nobr>
<span class="sympad"><a href="../../../../../reference/android/support/wearable/view/CircledImageView.html#setImageDrawable(android.graphics.drawable.Drawable)">setImageDrawable</a></span>(Drawable drawable)</nobr>
</td></tr>
+ <tr class="alt-color api apilevel-" >
+ <td class="jd-typecol"><nobr>
+
+
+
+
+
+ void</nobr>
+ </td>
+ <td class="jd-linkcol" width="100%"><nobr>
+ <span class="sympad"><a href="../../../../../reference/android/support/wearable/view/CircledImageView.html#setImageHorizontalOffcenterPercentage(float)">setImageHorizontalOffcenterPercentage</a></span>(float percentage)</nobr>
+
+ </td></tr>
+
+
+
<tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -3196,7 +3229,7 @@
void</nobr>
</td>
<td class="jd-linkcol" width="100%"><nobr>
- <span class="sympad"><a href="../../../../../reference/android/support/wearable/view/CircledImageView.html#setPressed(boolean)">setPressed</a></span>(boolean pressed)</nobr>
+ <span class="sympad"><a href="../../../../../reference/android/support/wearable/view/CircledImageView.html#setImageTint(int)">setImageTint</a></span>(int tint)</nobr>
</td></tr>
@@ -3212,7 +3245,7 @@
void</nobr>
</td>
<td class="jd-linkcol" width="100%"><nobr>
- <span class="sympad"><a href="../../../../../reference/android/support/wearable/view/CircledImageView.html#setProgress(float)">setProgress</a></span>(float progress)</nobr>
+ <span class="sympad"><a href="../../../../../reference/android/support/wearable/view/CircledImageView.html#setPressed(boolean)">setPressed</a></span>(boolean pressed)</nobr>
</td></tr>
@@ -3228,6 +3261,22 @@
void</nobr>
</td>
<td class="jd-linkcol" width="100%"><nobr>
+ <span class="sympad"><a href="../../../../../reference/android/support/wearable/view/CircledImageView.html#setProgress(float)">setProgress</a></span>(float progress)</nobr>
+
+ </td></tr>
+
+
+
+ <tr class=" api apilevel-" >
+ <td class="jd-typecol"><nobr>
+
+
+
+
+
+ void</nobr>
+ </td>
+ <td class="jd-linkcol" width="100%"><nobr>
<span class="sympad"><a href="../../../../../reference/android/support/wearable/view/CircledImageView.html#setShadowVisibility(float)">setShadowVisibility</a></span>(float shadowVisibility)</nobr>
<div class="jd-descrdiv">
@@ -3241,7 +3290,7 @@
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -11914,6 +11963,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/DismissOverlayView.html b/docs/html/reference/android/support/wearable/view/DismissOverlayView.html
index f455403..f146daf 100644
--- a/docs/html/reference/android/support/wearable/view/DismissOverlayView.html
+++ b/docs/html/reference/android/support/wearable/view/DismissOverlayView.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -501,6 +501,7 @@
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+ <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -719,7 +720,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -15317,6 +15318,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/DotsPageIndicator.html b/docs/html/reference/android/support/wearable/view/DotsPageIndicator.html
index 006a270..634cf95 100644
--- a/docs/html/reference/android/support/wearable/view/DotsPageIndicator.html
+++ b/docs/html/reference/android/support/wearable/view/DotsPageIndicator.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -501,6 +501,7 @@
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+ <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -705,7 +706,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -13437,6 +13438,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/FragmentGridPagerAdapter.html b/docs/html/reference/android/support/wearable/view/FragmentGridPagerAdapter.html
index 9df4ae7..ed7fecd 100644
--- a/docs/html/reference/android/support/wearable/view/FragmentGridPagerAdapter.html
+++ b/docs/html/reference/android/support/wearable/view/FragmentGridPagerAdapter.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -501,6 +501,7 @@
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+ <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -611,6 +612,9 @@
+ | <a href="#promethods">Protected Methods</a>
+
+
| <a href="#inhmethods">Inherited Methods</a>
@@ -660,7 +664,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -965,6 +969,22 @@
+ Fragment</nobr>
+ </td>
+ <td class="jd-linkcol" width="100%"><nobr>
+ <span class="sympad"><a href="../../../../../reference/android/support/wearable/view/FragmentGridPagerAdapter.html#findExistingFragment(int, int)">findExistingFragment</a></span>(int row, int column)</nobr>
+
+ </td></tr>
+
+
+
+ <tr class="alt-color api apilevel-" >
+ <td class="jd-typecol"><nobr>
+
+
+
+
+
void</nobr>
</td>
<td class="jd-linkcol" width="100%"><nobr>
@@ -981,7 +1001,7 @@
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1004,7 +1024,7 @@
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
abstract
@@ -1027,7 +1047,7 @@
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1050,7 +1070,7 @@
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1074,7 +1094,7 @@
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1097,7 +1117,7 @@
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1126,6 +1146,71 @@
+<!-- ========== METHOD SUMMARY =========== -->
+<table id="promethods" class="jd-sumtable"><tr><th colspan="12">Protected Methods</th></tr>
+
+
+
+
+ <tr class="alt-color api apilevel-" >
+ <td class="jd-typecol"><nobr>
+
+
+
+
+
+ void</nobr>
+ </td>
+ <td class="jd-linkcol" width="100%"><nobr>
+ <span class="sympad"><a href="../../../../../reference/android/support/wearable/view/FragmentGridPagerAdapter.html#applyItemPosition(java.lang.Object, android.graphics.Point)">applyItemPosition</a></span>(Object object, Point position)</nobr>
+
+ <div class="jd-descrdiv">
+ Called after <code><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html#getItemPosition(java.lang.Object)">getItemPosition(Object)</a></code> to allow superclasses to update their
+ internal bookkeeping if a subclass has overridden <code><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html#getItemPosition(java.lang.Object)">getItemPosition(Object)</a></code>.
+
+
+
+ </div>
+
+ </td></tr>
+
+
+
+ <tr class=" api apilevel-" >
+ <td class="jd-typecol"><nobr>
+
+
+
+
+
+ void</nobr>
+ </td>
+ <td class="jd-linkcol" width="100%"><nobr>
+ <span class="sympad"><a href="../../../../../reference/android/support/wearable/view/FragmentGridPagerAdapter.html#removeFragment(android.app.Fragment, android.app.FragmentTransaction)">removeFragment</a></span>(Fragment fragment, FragmentTransaction transaction)</nobr>
+
+ </td></tr>
+
+
+
+ <tr class="alt-color api apilevel-" >
+ <td class="jd-typecol"><nobr>
+
+
+
+
+
+ void</nobr>
+ </td>
+ <td class="jd-linkcol" width="100%"><nobr>
+ <span class="sympad"><a href="../../../../../reference/android/support/wearable/view/FragmentGridPagerAdapter.html#restoreFragment(android.app.Fragment, android.app.FragmentTransaction)">restoreFragment</a></span>(Fragment fragment, FragmentTransaction transaction)</nobr>
+
+ </td></tr>
+
+
+
+</table>
+
+
@@ -1157,6 +1242,30 @@
<tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
+
+
+
+
+
+ void</nobr>
+ </td>
+ <td class="jd-linkcol" width="100%"><nobr>
+ <span class="sympad"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html#applyItemPosition(java.lang.Object, android.graphics.Point)">applyItemPosition</a></span>(Object object, Point position)</nobr>
+
+ <div class="jd-descrdiv">
+ Called after <code><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html#getItemPosition(java.lang.Object)">getItemPosition(Object)</a></code> to allow superclasses to update their
+ internal bookkeeping if a subclass has overridden <code><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html#getItemPosition(java.lang.Object)">getItemPosition(Object)</a></code>.
+
+
+
+ </div>
+
+ </td></tr>
+
+
+
+ <tr class=" api apilevel-" >
+ <td class="jd-typecol"><nobr>
abstract
@@ -1178,7 +1287,7 @@
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1201,7 +1310,7 @@
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1224,7 +1333,7 @@
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1247,7 +1356,7 @@
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
abstract
@@ -1270,7 +1379,7 @@
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1293,7 +1402,7 @@
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1316,7 +1425,7 @@
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1339,7 +1448,7 @@
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
abstract
@@ -1362,7 +1471,7 @@
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
abstract
@@ -1385,7 +1494,7 @@
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
abstract
@@ -1409,7 +1518,7 @@
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1433,7 +1542,7 @@
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1457,7 +1566,7 @@
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1481,7 +1590,7 @@
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1504,7 +1613,7 @@
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1527,7 +1636,7 @@
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1550,7 +1659,7 @@
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1573,7 +1682,7 @@
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1596,7 +1705,7 @@
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1964,6 +2073,38 @@
</div>
+<A NAME="findExistingFragment(int, int)"></A>
+
+<div class="jd-details api apilevel-">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ public
+
+
+
+
+ Fragment
+ </span>
+ <span class="sympad">findExistingFragment</span>
+ <span class="normal">(int row, int column)</span>
+ </h4>
+ <div class="api-level">
+ <div></div>
+
+
+
+ </div>
+ <div class="jd-details-descr">
+
+
+
+
+ <div class="jd-tagdata jd-tagdescr"><p></p></div>
+
+ </div>
+</div>
+
+
<A NAME="finishUpdate(android.view.ViewGroup)"></A>
<div class="jd-details api apilevel-">
@@ -2331,6 +2472,122 @@
<!-- ========= METHOD DETAIL ======== -->
+<h2>Protected Methods</h2>
+
+
+
+<A NAME="applyItemPosition(java.lang.Object, android.graphics.Point)"></A>
+
+<div class="jd-details api apilevel-">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ protected
+
+
+
+
+ void
+ </span>
+ <span class="sympad">applyItemPosition</span>
+ <span class="normal">(Object object, Point position)</span>
+ </h4>
+ <div class="api-level">
+ <div></div>
+
+
+
+ </div>
+ <div class="jd-details-descr">
+
+
+
+
+ <div class="jd-tagdata jd-tagdescr"><p>Called after <code><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html#getItemPosition(java.lang.Object)">getItemPosition(Object)</a></code> to allow superclasses to update their
+ internal bookkeeping if a subclass has overridden <code><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html#getItemPosition(java.lang.Object)">getItemPosition(Object)</a></code>.</p></div>
+ <div class="jd-tagdata">
+ <h5 class="jd-tagtitle">Parameters</h5>
+ <table class="jd-tagtable">
+ <tr>
+ <th>object</td>
+ <td>Object representing the item passed to <code><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html#getItemPosition(java.lang.Object)">getItemPosition(Object)</a></code>.</td>
+ </tr>
+ <tr>
+ <th>position</td>
+ <td>position which was returned from <code><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html#getItemPosition(java.lang.Object)">getItemPosition(Object)</a></code>.
+</td>
+ </tr>
+ </table>
+ </div>
+
+ </div>
+</div>
+
+
+<A NAME="removeFragment(android.app.Fragment, android.app.FragmentTransaction)"></A>
+
+<div class="jd-details api apilevel-">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ protected
+
+
+
+
+ void
+ </span>
+ <span class="sympad">removeFragment</span>
+ <span class="normal">(Fragment fragment, FragmentTransaction transaction)</span>
+ </h4>
+ <div class="api-level">
+ <div></div>
+
+
+
+ </div>
+ <div class="jd-details-descr">
+
+
+
+
+ <div class="jd-tagdata jd-tagdescr"><p></p></div>
+
+ </div>
+</div>
+
+
+<A NAME="restoreFragment(android.app.Fragment, android.app.FragmentTransaction)"></A>
+
+<div class="jd-details api apilevel-">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ protected
+
+
+
+
+ void
+ </span>
+ <span class="sympad">restoreFragment</span>
+ <span class="normal">(Fragment fragment, FragmentTransaction transaction)</span>
+ </h4>
+ <div class="api-level">
+ <div></div>
+
+
+
+ </div>
+ <div class="jd-details-descr">
+
+
+
+
+ <div class="jd-tagdata jd-tagdescr"><p></p></div>
+
+ </div>
+</div>
+
+
+
<!-- ========= END OF CLASS DATA ========= -->
@@ -2389,6 +2646,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/GridPageOptions.BackgroundListener.html b/docs/html/reference/android/support/wearable/view/GridPageOptions.BackgroundListener.html
index a37d8f8a..1e066c1 100644
--- a/docs/html/reference/android/support/wearable/view/GridPageOptions.BackgroundListener.html
+++ b/docs/html/reference/android/support/wearable/view/GridPageOptions.BackgroundListener.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -501,6 +501,7 @@
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+ <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -602,7 +603,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -853,6 +854,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/GridPageOptions.html b/docs/html/reference/android/support/wearable/view/GridPageOptions.html
index 56cfa05..8c22582 100644
--- a/docs/html/reference/android/support/wearable/view/GridPageOptions.html
+++ b/docs/html/reference/android/support/wearable/view/GridPageOptions.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -501,6 +501,7 @@
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+ <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -602,7 +603,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -948,6 +949,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/GridPagerAdapter.html b/docs/html/reference/android/support/wearable/view/GridPagerAdapter.html
index 9876a82..b157c39 100644
--- a/docs/html/reference/android/support/wearable/view/GridPagerAdapter.html
+++ b/docs/html/reference/android/support/wearable/view/GridPagerAdapter.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -501,6 +501,7 @@
<li class="selected api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+ <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -600,6 +601,9 @@
+ | <a href="#promethods">Protected Methods</a>
+
+
| <a href="#inhmethods">Inherited Methods</a>
@@ -645,7 +649,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -1369,6 +1373,39 @@
+<!-- ========== METHOD SUMMARY =========== -->
+<table id="promethods" class="jd-sumtable"><tr><th colspan="12">Protected Methods</th></tr>
+
+
+
+
+ <tr class="alt-color api apilevel-" >
+ <td class="jd-typecol"><nobr>
+
+
+
+
+
+ void</nobr>
+ </td>
+ <td class="jd-linkcol" width="100%"><nobr>
+ <span class="sympad"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html#applyItemPosition(java.lang.Object, android.graphics.Point)">applyItemPosition</a></span>(Object object, Point position)</nobr>
+
+ <div class="jd-descrdiv">
+ Called after <code><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html#getItemPosition(java.lang.Object)">getItemPosition(Object)</a></code> to allow superclasses to update their
+ internal bookkeeping if a subclass has overridden <code><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html#getItemPosition(java.lang.Object)">getItemPosition(Object)</a></code>.
+
+
+
+ </div>
+
+ </td></tr>
+
+
+
+</table>
+
+
@@ -2742,6 +2779,58 @@
<!-- ========= METHOD DETAIL ======== -->
+<h2>Protected Methods</h2>
+
+
+
+<A NAME="applyItemPosition(java.lang.Object, android.graphics.Point)"></A>
+
+<div class="jd-details api apilevel-">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ protected
+
+
+
+
+ void
+ </span>
+ <span class="sympad">applyItemPosition</span>
+ <span class="normal">(Object object, Point position)</span>
+ </h4>
+ <div class="api-level">
+ <div></div>
+
+
+
+ </div>
+ <div class="jd-details-descr">
+
+
+
+
+ <div class="jd-tagdata jd-tagdescr"><p>Called after <code><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html#getItemPosition(java.lang.Object)">getItemPosition(Object)</a></code> to allow superclasses to update their
+ internal bookkeeping if a subclass has overridden <code><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html#getItemPosition(java.lang.Object)">getItemPosition(Object)</a></code>.</p></div>
+ <div class="jd-tagdata">
+ <h5 class="jd-tagtitle">Parameters</h5>
+ <table class="jd-tagtable">
+ <tr>
+ <th>object</td>
+ <td>Object representing the item passed to <code><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html#getItemPosition(java.lang.Object)">getItemPosition(Object)</a></code>.</td>
+ </tr>
+ <tr>
+ <th>position</td>
+ <td>position which was returned from <code><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html#getItemPosition(java.lang.Object)">getItemPosition(Object)</a></code>.
+</td>
+ </tr>
+ </table>
+ </div>
+
+ </div>
+</div>
+
+
+
<!-- ========= END OF CLASS DATA ========= -->
@@ -2800,6 +2889,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/GridViewPager.LayoutParams.html b/docs/html/reference/android/support/wearable/view/GridViewPager.LayoutParams.html
index 9db55c9..c4d63e22 100644
--- a/docs/html/reference/android/support/wearable/view/GridViewPager.LayoutParams.html
+++ b/docs/html/reference/android/support/wearable/view/GridViewPager.LayoutParams.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -501,6 +501,7 @@
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
<li class="selected api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+ <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -673,7 +674,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -1787,6 +1788,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/GridViewPager.OnAdapterChangeListener.html b/docs/html/reference/android/support/wearable/view/GridViewPager.OnAdapterChangeListener.html
index 1cbec14..fcd6a3d 100644
--- a/docs/html/reference/android/support/wearable/view/GridViewPager.OnAdapterChangeListener.html
+++ b/docs/html/reference/android/support/wearable/view/GridViewPager.OnAdapterChangeListener.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -501,6 +501,7 @@
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+ <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -621,7 +622,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -968,6 +969,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/GridViewPager.OnPageChangeListener.html b/docs/html/reference/android/support/wearable/view/GridViewPager.OnPageChangeListener.html
index fd81fbe..072f6c5 100644
--- a/docs/html/reference/android/support/wearable/view/GridViewPager.OnPageChangeListener.html
+++ b/docs/html/reference/android/support/wearable/view/GridViewPager.OnPageChangeListener.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -501,6 +501,7 @@
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+ <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -621,7 +622,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -1085,6 +1086,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/GridViewPager.html b/docs/html/reference/android/support/wearable/view/GridViewPager.html
index b92720c..3e2179d 100644
--- a/docs/html/reference/android/support/wearable/view/GridViewPager.html
+++ b/docs/html/reference/android/support/wearable/view/GridViewPager.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -501,6 +501,7 @@
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
<li class="selected api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+ <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -717,7 +718,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -16881,6 +16882,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/SimpleAnimatorListener.html b/docs/html/reference/android/support/wearable/view/SimpleAnimatorListener.html
index 454f420..9940f3b 100644
--- a/docs/html/reference/android/support/wearable/view/SimpleAnimatorListener.html
+++ b/docs/html/reference/android/support/wearable/view/SimpleAnimatorListener.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -501,6 +501,7 @@
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+ <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
<li class="selected api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -651,7 +652,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -1525,6 +1526,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/WatchViewStub.OnLayoutInflatedListener.html b/docs/html/reference/android/support/wearable/view/WatchViewStub.OnLayoutInflatedListener.html
index b05ce34..9492429 100644
--- a/docs/html/reference/android/support/wearable/view/WatchViewStub.OnLayoutInflatedListener.html
+++ b/docs/html/reference/android/support/wearable/view/WatchViewStub.OnLayoutInflatedListener.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -501,6 +501,7 @@
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+ <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -602,7 +603,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -847,6 +848,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/WatchViewStub.html b/docs/html/reference/android/support/wearable/view/WatchViewStub.html
index 8fd5fee..170a165 100644
--- a/docs/html/reference/android/support/wearable/view/WatchViewStub.html
+++ b/docs/html/reference/android/support/wearable/view/WatchViewStub.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -501,6 +501,7 @@
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+ <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
<li class="selected api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -725,7 +726,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -15465,6 +15466,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/WearableFrameLayout.LayoutParams.html b/docs/html/reference/android/support/wearable/view/WearableFrameLayout.LayoutParams.html
index 93f4b0d..fb54c95 100644
--- a/docs/html/reference/android/support/wearable/view/WearableFrameLayout.LayoutParams.html
+++ b/docs/html/reference/android/support/wearable/view/WearableFrameLayout.LayoutParams.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -501,6 +501,7 @@
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+ <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -684,7 +685,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -2322,6 +2323,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/WearableFrameLayout.html b/docs/html/reference/android/support/wearable/view/WearableFrameLayout.html
index f2b0df7..e269ab8 100644
--- a/docs/html/reference/android/support/wearable/view/WearableFrameLayout.html
+++ b/docs/html/reference/android/support/wearable/view/WearableFrameLayout.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -501,6 +501,7 @@
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+ <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
<li class="selected api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -714,7 +715,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -16352,6 +16353,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/WearableListView.Adapter.html b/docs/html/reference/android/support/wearable/view/WearableListView.Adapter.html
index 9619c5d..0686ff2 100644
--- a/docs/html/reference/android/support/wearable/view/WearableListView.Adapter.html
+++ b/docs/html/reference/android/support/wearable/view/WearableListView.Adapter.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -501,6 +501,7 @@
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+ <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -647,7 +648,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -1561,6 +1562,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/WearableListView.ClickListener.html b/docs/html/reference/android/support/wearable/view/WearableListView.ClickListener.html
index 84cb188..17431c4 100644
--- a/docs/html/reference/android/support/wearable/view/WearableListView.ClickListener.html
+++ b/docs/html/reference/android/support/wearable/view/WearableListView.ClickListener.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -501,6 +501,7 @@
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+ <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -602,7 +603,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -919,6 +920,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/WearableListView.OnCenterProximityListener.html b/docs/html/reference/android/support/wearable/view/WearableListView.OnCenterProximityListener.html
index b2b9246..936a163 100644
--- a/docs/html/reference/android/support/wearable/view/WearableListView.OnCenterProximityListener.html
+++ b/docs/html/reference/android/support/wearable/view/WearableListView.OnCenterProximityListener.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -501,6 +501,7 @@
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+ <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -602,7 +603,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -930,6 +931,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/WearableListView.OnCentralPositionChangedListener.html b/docs/html/reference/android/support/wearable/view/WearableListView.OnCentralPositionChangedListener.html
index 66eeac3..c49bbcc 100644
--- a/docs/html/reference/android/support/wearable/view/WearableListView.OnCentralPositionChangedListener.html
+++ b/docs/html/reference/android/support/wearable/view/WearableListView.OnCentralPositionChangedListener.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -501,6 +501,7 @@
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+ <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -602,7 +603,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -861,6 +862,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/WearableListView.OnScrollListener.html b/docs/html/reference/android/support/wearable/view/WearableListView.OnScrollListener.html
index de2bcd7..2871600 100644
--- a/docs/html/reference/android/support/wearable/view/WearableListView.OnScrollListener.html
+++ b/docs/html/reference/android/support/wearable/view/WearableListView.OnScrollListener.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -501,6 +501,7 @@
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+ <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -602,7 +603,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -1065,6 +1066,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/WearableListView.ViewHolder.html b/docs/html/reference/android/support/wearable/view/WearableListView.ViewHolder.html
index b7953d4..270d8d8 100644
--- a/docs/html/reference/android/support/wearable/view/WearableListView.ViewHolder.html
+++ b/docs/html/reference/android/support/wearable/view/WearableListView.ViewHolder.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -501,6 +501,7 @@
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+ <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -652,7 +653,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -1346,6 +1347,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/WearableListView.html b/docs/html/reference/android/support/wearable/view/WearableListView.html
index eec5c32..7fb9565 100644
--- a/docs/html/reference/android/support/wearable/view/WearableListView.html
+++ b/docs/html/reference/android/support/wearable/view/WearableListView.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -501,6 +501,7 @@
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+ <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -724,7 +725,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -3236,7 +3237,7 @@
boolean</nobr>
</td>
<td class="jd-linkcol" width="100%"><nobr>
- <span class="sympad"><a href="../../../../../reference/android/support/wearable/view/WearableListView.html#onInterceptTouchEvent(android.view.MotionEvent)">onInterceptTouchEvent</a></span>(MotionEvent event)</nobr>
+ <span class="sympad"><a href="../../../../../reference/android/support/wearable/view/WearableListView.html#isAtTop()">isAtTop</a></span>()</nobr>
</td></tr>
@@ -3252,7 +3253,7 @@
boolean</nobr>
</td>
<td class="jd-linkcol" width="100%"><nobr>
- <span class="sympad"><a href="../../../../../reference/android/support/wearable/view/WearableListView.html#onTouchEvent(android.view.MotionEvent)">onTouchEvent</a></span>(MotionEvent event)</nobr>
+ <span class="sympad"><a href="../../../../../reference/android/support/wearable/view/WearableListView.html#onInterceptTouchEvent(android.view.MotionEvent)">onInterceptTouchEvent</a></span>(MotionEvent event)</nobr>
</td></tr>
@@ -3265,6 +3266,22 @@
+ boolean</nobr>
+ </td>
+ <td class="jd-linkcol" width="100%"><nobr>
+ <span class="sympad"><a href="../../../../../reference/android/support/wearable/view/WearableListView.html#onTouchEvent(android.view.MotionEvent)">onTouchEvent</a></span>(MotionEvent event)</nobr>
+
+ </td></tr>
+
+
+
+ <tr class=" api apilevel-" >
+ <td class="jd-typecol"><nobr>
+
+
+
+
+
void</nobr>
</td>
<td class="jd-linkcol" width="100%"><nobr>
@@ -3281,7 +3298,7 @@
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -3304,7 +3321,7 @@
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -3327,7 +3344,7 @@
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -3343,7 +3360,7 @@
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -3366,7 +3383,7 @@
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -3390,7 +3407,7 @@
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -3413,7 +3430,7 @@
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -3436,6 +3453,22 @@
</td></tr>
+
+ <tr class=" api apilevel-" >
+ <td class="jd-typecol"><nobr>
+
+
+
+
+
+ void</nobr>
+ </td>
+ <td class="jd-linkcol" width="100%"><nobr>
+ <span class="sympad"><a href="../../../../../reference/android/support/wearable/view/WearableListView.html#smoothScrollToPosition(int, android.support.v7.widget.RecyclerView.SmoothScroller)">smoothScrollToPosition</a></span>(int position, RecyclerView.SmoothScroller smoothScroller)</nobr>
+
+ </td></tr>
+
+
</table>
@@ -16613,6 +16646,43 @@
</div>
+<A NAME="isAtTop()"></A>
+
+<div class="jd-details api apilevel-">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ public
+
+
+
+
+ boolean
+ </span>
+ <span class="sympad">isAtTop</span>
+ <span class="normal">()</span>
+ </h4>
+ <div class="api-level">
+ <div></div>
+
+
+
+ </div>
+ <div class="jd-details-descr">
+
+
+
+
+ <div class="jd-tagdata jd-tagdescr"><p></p></div>
+ <div class="jd-tagdata">
+ <h5 class="jd-tagtitle">Returns</h5>
+ <ul class="nolist"><li>true if the list is scrolled all the way to the top.
+</li></ul>
+ </div>
+
+ </div>
+</div>
+
+
<A NAME="onInterceptTouchEvent(android.view.MotionEvent)"></A>
<div class="jd-details api apilevel-">
@@ -16963,6 +17033,38 @@
</div>
+<A NAME="smoothScrollToPosition(int, android.support.v7.widget.RecyclerView.SmoothScroller)"></A>
+
+<div class="jd-details api apilevel-">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ public
+
+
+
+
+ void
+ </span>
+ <span class="sympad">smoothScrollToPosition</span>
+ <span class="normal">(int position, RecyclerView.SmoothScroller smoothScroller)</span>
+ </h4>
+ <div class="api-level">
+ <div></div>
+
+
+
+ </div>
+ <div class="jd-details-descr">
+
+
+
+
+ <div class="jd-tagdata jd-tagdescr"><p></p></div>
+
+ </div>
+</div>
+
+
@@ -17026,6 +17128,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/package-summary.html b/docs/html/reference/android/support/wearable/view/package-summary.html
index 28f94db..f76e378 100644
--- a/docs/html/reference/android/support/wearable/view/package-summary.html
+++ b/docs/html/reference/android/support/wearable/view/package-summary.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -502,6 +502,7 @@
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+ <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
<li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -578,7 +579,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
@@ -920,6 +921,17 @@
<tr class=" api apilevel-" >
+ <td class="jd-linkcol"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></td>
+ <td class="jd-descrcol" width="100%">
+ An indeterminate progress spinner designed for wearables which cycles through colors.
+
+
+
+ </td>
+ </tr>
+
+
+ <tr class="alt-color api apilevel-" >
<td class="jd-linkcol"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></td>
<td class="jd-descrcol" width="100%">
Convenience class for listening for Animator events that implements the AnimatorListener
@@ -931,7 +943,7 @@
</tr>
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-linkcol"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></td>
<td class="jd-descrcol" width="100%">
A WatchViewStub allows for the use of different sub-layouts depending on the
@@ -944,7 +956,7 @@
</tr>
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-linkcol"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></td>
<td class="jd-descrcol" width="100%">
WearableFrameLayout works exactly like FrameLayout, except it can have overrides for a round
@@ -956,7 +968,7 @@
</tr>
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-linkcol"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.LayoutParams.html">WearableFrameLayout.LayoutParams</a></td>
<td class="jd-descrcol" width="100%">
Per-child layout information for layouts on wearable devices.
@@ -967,7 +979,7 @@
</tr>
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-linkcol"><a href="../../../../../reference/android/support/wearable/view/WearableListView.html">WearableListView</a></td>
<td class="jd-descrcol" width="100%">
An alternative version of ListView that is optimized for ease of use on small screen wearable
@@ -979,7 +991,7 @@
</tr>
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-linkcol"><a href="../../../../../reference/android/support/wearable/view/WearableListView.Adapter.html">WearableListView.Adapter</a></td>
<td class="jd-descrcol" width="100%">
Base class for adapters providing data for the WearableListView.
@@ -990,7 +1002,7 @@
</tr>
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-linkcol"><a href="../../../../../reference/android/support/wearable/view/WearableListView.ViewHolder.html">WearableListView.ViewHolder</a></td>
<td class="jd-descrcol" width="100%">
Wrapper around items displayed in the list view.
@@ -1070,6 +1082,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/watchface/CanvasWatchFaceService.Engine.html b/docs/html/reference/android/support/wearable/watchface/CanvasWatchFaceService.Engine.html
index bbae62a..1a7aa76 100644
--- a/docs/html/reference/android/support/wearable/watchface/CanvasWatchFaceService.Engine.html
+++ b/docs/html/reference/android/support/wearable/watchface/CanvasWatchFaceService.Engine.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -466,6 +466,11 @@
<ul>
+ <li><h2>Annotations</h2>
+ <ul>
+ <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.TapType.html">WatchFaceService.TapType</a></li>
+ </ul>
+ </li>
<li><h2>Classes</h2>
@@ -631,7 +636,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -968,6 +973,29 @@
final
+ int</nobr>
+ </td>
+ <td class="jd-linkcol" width="100%"><nobr>
+ <span class="sympad"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.Engine.html#getNotificationCount()">getNotificationCount</a></span>()</nobr>
+
+ <div class="jd-descrdiv">
+ Returns the total number of notification cards in the stream.
+
+
+
+ </div>
+
+ </td></tr>
+
+
+
+ <tr class="alt-color api apilevel-" >
+ <td class="jd-typecol"><nobr>
+
+
+ final
+
+
Rect</nobr>
</td>
<td class="jd-linkcol" width="100%"><nobr>
@@ -984,7 +1012,7 @@
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1007,7 +1035,7 @@
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1030,7 +1058,7 @@
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1053,7 +1081,7 @@
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1069,7 +1097,7 @@
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1085,7 +1113,7 @@
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1101,7 +1129,7 @@
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1124,6 +1152,29 @@
+ <tr class="alt-color api apilevel-" >
+ <td class="jd-typecol"><nobr>
+
+
+
+
+
+ void</nobr>
+ </td>
+ <td class="jd-linkcol" width="100%"><nobr>
+ <span class="sympad"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.Engine.html#onNotificationCountChanged(int)">onNotificationCountChanged</a></span>(int count)</nobr>
+
+ <div class="jd-descrdiv">
+ Called when the total number of notification cards in the stream has changed.
+
+
+
+ </div>
+
+ </td></tr>
+
+
+
<tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1180,6 +1231,29 @@
void</nobr>
</td>
<td class="jd-linkcol" width="100%"><nobr>
+ <span class="sympad"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.Engine.html#onTapCommand(int, int, int, long)">onTapCommand</a></span>(int tapType, int x, int y, long eventTime)</nobr>
+
+ <div class="jd-descrdiv">
+ Called when a tap or touch related event occurs.
+
+
+
+ </div>
+
+ </td></tr>
+
+
+
+ <tr class="alt-color api apilevel-" >
+ <td class="jd-typecol"><nobr>
+
+
+
+
+
+ void</nobr>
+ </td>
+ <td class="jd-linkcol" width="100%"><nobr>
<span class="sympad"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.Engine.html#onTimeTick()">onTimeTick</a></span>()</nobr>
<div class="jd-descrdiv">
@@ -1193,7 +1267,7 @@
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1216,7 +1290,7 @@
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1239,7 +1313,7 @@
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -2201,6 +2275,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/watchface/CanvasWatchFaceService.html b/docs/html/reference/android/support/wearable/watchface/CanvasWatchFaceService.html
index 5dbd8ea..aee337f 100644
--- a/docs/html/reference/android/support/wearable/watchface/CanvasWatchFaceService.html
+++ b/docs/html/reference/android/support/wearable/watchface/CanvasWatchFaceService.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -466,6 +466,11 @@
<ul>
+ <li><h2>Annotations</h2>
+ <ul>
+ <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.TapType.html">WatchFaceService.TapType</a></li>
+ </ul>
+ </li>
<li><h2>Classes</h2>
@@ -694,7 +699,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -952,6 +957,44 @@
</tr>
+ <tr class=" api apilevel-" >
+ <td class="jd-typecol">int</td>
+ <td class="jd-linkcol"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.html#TAP_TYPE_TAP">TAP_TYPE_TAP</a></td>
+ <td class="jd-descrcol" width="100%">
+ Used in onTapCommaned to indicate that an "up" event on the watch face has occurred that
+ has not been consumed by another activity.
+
+
+
+ </td>
+ </tr>
+
+
+ <tr class="alt-color api apilevel-" >
+ <td class="jd-typecol">int</td>
+ <td class="jd-linkcol"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.html#TAP_TYPE_TOUCH">TAP_TYPE_TOUCH</a></td>
+ <td class="jd-descrcol" width="100%">
+ Used in onTapCommand to indicate a "down" touch event on the watch face.
+
+
+
+ </td>
+ </tr>
+
+
+ <tr class=" api apilevel-" >
+ <td class="jd-typecol">int</td>
+ <td class="jd-linkcol"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.html#TAP_TYPE_TOUCH_CANCEL">TAP_TYPE_TOUCH_CANCEL</a></td>
+ <td class="jd-descrcol" width="100%">
+ Used in onTapCaommand to indicate that a previous TAP_TYPE_TOUCH touch event has been
+ canceled.
+
+
+
+ </td>
+ </tr>
+
+
</table>
</div>
</div>
@@ -6238,6 +6281,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/watchface/Gles2WatchFaceService.Engine.html b/docs/html/reference/android/support/wearable/watchface/Gles2WatchFaceService.Engine.html
index 761917877..aba23a6 100644
--- a/docs/html/reference/android/support/wearable/watchface/Gles2WatchFaceService.Engine.html
+++ b/docs/html/reference/android/support/wearable/watchface/Gles2WatchFaceService.Engine.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -466,6 +466,11 @@
<ul>
+ <li><h2>Annotations</h2>
+ <ul>
+ <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.TapType.html">WatchFaceService.TapType</a></li>
+ </ul>
+ </li>
<li><h2>Classes</h2>
@@ -631,7 +636,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -1138,6 +1143,29 @@
final
+ int</nobr>
+ </td>
+ <td class="jd-linkcol" width="100%"><nobr>
+ <span class="sympad"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.Engine.html#getNotificationCount()">getNotificationCount</a></span>()</nobr>
+
+ <div class="jd-descrdiv">
+ Returns the total number of notification cards in the stream.
+
+
+
+ </div>
+
+ </td></tr>
+
+
+
+ <tr class="alt-color api apilevel-" >
+ <td class="jd-typecol"><nobr>
+
+
+ final
+
+
Rect</nobr>
</td>
<td class="jd-linkcol" width="100%"><nobr>
@@ -1154,7 +1182,7 @@
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1177,7 +1205,7 @@
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1200,7 +1228,7 @@
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1223,7 +1251,7 @@
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1239,7 +1267,7 @@
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1255,7 +1283,7 @@
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1271,7 +1299,7 @@
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1294,6 +1322,29 @@
+ <tr class="alt-color api apilevel-" >
+ <td class="jd-typecol"><nobr>
+
+
+
+
+
+ void</nobr>
+ </td>
+ <td class="jd-linkcol" width="100%"><nobr>
+ <span class="sympad"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.Engine.html#onNotificationCountChanged(int)">onNotificationCountChanged</a></span>(int count)</nobr>
+
+ <div class="jd-descrdiv">
+ Called when the total number of notification cards in the stream has changed.
+
+
+
+ </div>
+
+ </td></tr>
+
+
+
<tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1350,6 +1401,29 @@
void</nobr>
</td>
<td class="jd-linkcol" width="100%"><nobr>
+ <span class="sympad"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.Engine.html#onTapCommand(int, int, int, long)">onTapCommand</a></span>(int tapType, int x, int y, long eventTime)</nobr>
+
+ <div class="jd-descrdiv">
+ Called when a tap or touch related event occurs.
+
+
+
+ </div>
+
+ </td></tr>
+
+
+
+ <tr class="alt-color api apilevel-" >
+ <td class="jd-typecol"><nobr>
+
+
+
+
+
+ void</nobr>
+ </td>
+ <td class="jd-linkcol" width="100%"><nobr>
<span class="sympad"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.Engine.html#onTimeTick()">onTimeTick</a></span>()</nobr>
<div class="jd-descrdiv">
@@ -1363,7 +1437,7 @@
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1386,7 +1460,7 @@
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1409,7 +1483,7 @@
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -2668,6 +2742,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/watchface/Gles2WatchFaceService.html b/docs/html/reference/android/support/wearable/watchface/Gles2WatchFaceService.html
index 6371290..1dcc7dd 100644
--- a/docs/html/reference/android/support/wearable/watchface/Gles2WatchFaceService.html
+++ b/docs/html/reference/android/support/wearable/watchface/Gles2WatchFaceService.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -466,6 +466,11 @@
<ul>
+ <li><h2>Annotations</h2>
+ <ul>
+ <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.TapType.html">WatchFaceService.TapType</a></li>
+ </ul>
+ </li>
<li><h2>Classes</h2>
@@ -694,7 +699,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -955,6 +960,44 @@
</tr>
+ <tr class=" api apilevel-" >
+ <td class="jd-typecol">int</td>
+ <td class="jd-linkcol"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.html#TAP_TYPE_TAP">TAP_TYPE_TAP</a></td>
+ <td class="jd-descrcol" width="100%">
+ Used in onTapCommaned to indicate that an "up" event on the watch face has occurred that
+ has not been consumed by another activity.
+
+
+
+ </td>
+ </tr>
+
+
+ <tr class="alt-color api apilevel-" >
+ <td class="jd-typecol">int</td>
+ <td class="jd-linkcol"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.html#TAP_TYPE_TOUCH">TAP_TYPE_TOUCH</a></td>
+ <td class="jd-descrcol" width="100%">
+ Used in onTapCommand to indicate a "down" touch event on the watch face.
+
+
+
+ </td>
+ </tr>
+
+
+ <tr class=" api apilevel-" >
+ <td class="jd-typecol">int</td>
+ <td class="jd-linkcol"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.html#TAP_TYPE_TOUCH_CANCEL">TAP_TYPE_TOUCH_CANCEL</a></td>
+ <td class="jd-descrcol" width="100%">
+ Used in onTapCaommand to indicate that a previous TAP_TYPE_TOUCH touch event has been
+ canceled.
+
+
+
+ </td>
+ </tr>
+
+
</table>
</div>
</div>
@@ -6241,6 +6284,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/watchface/WatchFaceService.Engine.html b/docs/html/reference/android/support/wearable/watchface/WatchFaceService.Engine.html
index 2326386..ad6cc2c 100644
--- a/docs/html/reference/android/support/wearable/watchface/WatchFaceService.Engine.html
+++ b/docs/html/reference/android/support/wearable/watchface/WatchFaceService.Engine.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -466,6 +466,11 @@
<ul>
+ <li><h2>Annotations</h2>
+ <ul>
+ <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.TapType.html">WatchFaceService.TapType</a></li>
+ </ul>
+ </li>
<li><h2>Classes</h2>
@@ -620,7 +625,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -831,6 +836,29 @@
final
+ int</nobr>
+ </td>
+ <td class="jd-linkcol" width="100%"><nobr>
+ <span class="sympad"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.Engine.html#getNotificationCount()">getNotificationCount</a></span>()</nobr>
+
+ <div class="jd-descrdiv">
+ Returns the total number of notification cards in the stream.
+
+
+
+ </div>
+
+ </td></tr>
+
+
+
+ <tr class="alt-color api apilevel-" >
+ <td class="jd-typecol"><nobr>
+
+
+ final
+
+
Rect</nobr>
</td>
<td class="jd-linkcol" width="100%"><nobr>
@@ -847,7 +875,7 @@
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -870,7 +898,7 @@
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -893,7 +921,7 @@
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -916,7 +944,7 @@
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -932,7 +960,7 @@
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -948,7 +976,7 @@
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -964,7 +992,7 @@
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -987,6 +1015,29 @@
+ <tr class="alt-color api apilevel-" >
+ <td class="jd-typecol"><nobr>
+
+
+
+
+
+ void</nobr>
+ </td>
+ <td class="jd-linkcol" width="100%"><nobr>
+ <span class="sympad"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.Engine.html#onNotificationCountChanged(int)">onNotificationCountChanged</a></span>(int count)</nobr>
+
+ <div class="jd-descrdiv">
+ Called when the total number of notification cards in the stream has changed.
+
+
+
+ </div>
+
+ </td></tr>
+
+
+
<tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1043,6 +1094,29 @@
void</nobr>
</td>
<td class="jd-linkcol" width="100%"><nobr>
+ <span class="sympad"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.Engine.html#onTapCommand(int, int, int, long)">onTapCommand</a></span>(int tapType, int x, int y, long eventTime)</nobr>
+
+ <div class="jd-descrdiv">
+ Called when a tap or touch related event occurs.
+
+
+
+ </div>
+
+ </td></tr>
+
+
+
+ <tr class="alt-color api apilevel-" >
+ <td class="jd-typecol"><nobr>
+
+
+
+
+
+ void</nobr>
+ </td>
+ <td class="jd-linkcol" width="100%"><nobr>
<span class="sympad"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.Engine.html#onTimeTick()">onTimeTick</a></span>()</nobr>
<div class="jd-descrdiv">
@@ -1056,7 +1130,7 @@
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1079,7 +1153,7 @@
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1102,7 +1176,7 @@
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1805,6 +1879,39 @@
</div>
+<A NAME="getNotificationCount()"></A>
+
+<div class="jd-details api apilevel-">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ public
+
+ final
+
+
+ int
+ </span>
+ <span class="sympad">getNotificationCount</span>
+ <span class="normal">()</span>
+ </h4>
+ <div class="api-level">
+ <div></div>
+
+
+
+ </div>
+ <div class="jd-details-descr">
+
+
+
+
+ <div class="jd-tagdata jd-tagdescr"><p>Returns the total number of notification cards in the stream.
+</p></div>
+
+ </div>
+</div>
+
+
<A NAME="getPeekCardPosition()"></A>
<div class="jd-details api apilevel-">
@@ -2075,6 +2182,48 @@
</div>
+<A NAME="onNotificationCountChanged(int)"></A>
+
+<div class="jd-details api apilevel-">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ public
+
+
+
+
+ void
+ </span>
+ <span class="sympad">onNotificationCountChanged</span>
+ <span class="normal">(int count)</span>
+ </h4>
+ <div class="api-level">
+ <div></div>
+
+
+
+ </div>
+ <div class="jd-details-descr">
+
+
+
+
+ <div class="jd-tagdata jd-tagdescr"><p>Called when the total number of notification cards in the stream has changed.</p></div>
+ <div class="jd-tagdata">
+ <h5 class="jd-tagtitle">Parameters</h5>
+ <table class="jd-tagtable">
+ <tr>
+ <th>count</td>
+ <td>total number of the notification cards in the stream
+</td>
+ </tr>
+ </table>
+ </div>
+
+ </div>
+</div>
+
+
<A NAME="onPeekCardPositionUpdate(android.graphics.Rect)"></A>
<div class="jd-details api apilevel-">
@@ -2154,6 +2303,60 @@
</div>
+<A NAME="onTapCommand(int, int, int, long)"></A>
+
+<div class="jd-details api apilevel-">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ public
+
+
+
+
+ void
+ </span>
+ <span class="sympad">onTapCommand</span>
+ <span class="normal">(int tapType, int x, int y, long eventTime)</span>
+ </h4>
+ <div class="api-level">
+ <div></div>
+
+
+
+ </div>
+ <div class="jd-details-descr">
+
+
+
+
+ <div class="jd-tagdata jd-tagdescr"><p>Called when a tap or touch related event occurs.</p></div>
+ <div class="jd-tagdata">
+ <h5 class="jd-tagtitle">Parameters</h5>
+ <table class="jd-tagtable">
+ <tr>
+ <th>tapType</td>
+ <td>Value representing the event sent to the wallpaper.</td>
+ </tr>
+ <tr>
+ <th>x</td>
+ <td>X coordinate of the event.</td>
+ </tr>
+ <tr>
+ <th>y</td>
+ <td>Y coordinate of the event.</td>
+ </tr>
+ <tr>
+ <th>eventTime</td>
+ <td>The time, in millis, of the event.
+</td>
+ </tr>
+ </table>
+ </div>
+
+ </div>
+</div>
+
+
<A NAME="onTimeTick()"></A>
<div class="jd-details api apilevel-">
@@ -2369,6 +2572,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/watchface/WatchFaceService.html b/docs/html/reference/android/support/wearable/watchface/WatchFaceService.html
index f566e7e..40cf0a3 100644
--- a/docs/html/reference/android/support/wearable/watchface/WatchFaceService.html
+++ b/docs/html/reference/android/support/wearable/watchface/WatchFaceService.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -466,6 +466,11 @@
<ul>
+ <li><h2>Annotations</h2>
+ <ul>
+ <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.TapType.html">WatchFaceService.TapType</a></li>
+ </ul>
+ </li>
<li><h2>Classes</h2>
@@ -684,7 +689,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -922,6 +927,23 @@
</tr>
+ <tr class=" api apilevel-" >
+ <td class="jd-typecol"><nobr>
+
+
+
+
+ @interface</nobr></td>
+ <td class="jd-linkcol"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.TapType.html">WatchFaceService.TapType</a></td>
+ <td class="jd-descrcol" width="100%">
+
+
+
+
+ </td>
+ </tr>
+
+
@@ -1005,6 +1027,44 @@
</tr>
+ <tr class=" api apilevel-" >
+ <td class="jd-typecol">int</td>
+ <td class="jd-linkcol"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.html#TAP_TYPE_TAP">TAP_TYPE_TAP</a></td>
+ <td class="jd-descrcol" width="100%">
+ Used in onTapCommaned to indicate that an "up" event on the watch face has occurred that
+ has not been consumed by another activity.
+
+
+
+ </td>
+ </tr>
+
+
+ <tr class="alt-color api apilevel-" >
+ <td class="jd-typecol">int</td>
+ <td class="jd-linkcol"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.html#TAP_TYPE_TOUCH">TAP_TYPE_TOUCH</a></td>
+ <td class="jd-descrcol" width="100%">
+ Used in onTapCommand to indicate a "down" touch event on the watch face.
+
+
+
+ </td>
+ </tr>
+
+
+ <tr class=" api apilevel-" >
+ <td class="jd-typecol">int</td>
+ <td class="jd-linkcol"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.html#TAP_TYPE_TOUCH_CANCEL">TAP_TYPE_TOUCH_CANCEL</a></td>
+ <td class="jd-descrcol" width="100%">
+ Used in onTapCaommand to indicate that a previous TAP_TYPE_TOUCH touch event has been
+ canceled.
+
+
+
+ </td>
+ </tr>
+
+
</table>
@@ -6330,6 +6390,136 @@
+<A NAME="TAP_TYPE_TAP"></A>
+
+<div class="jd-details api apilevel-">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ public
+ static
+ final
+ int
+ </span>
+ TAP_TYPE_TAP
+ </h4>
+ <div class="api-level">
+
+
+
+
+ </div>
+ <div class="jd-details-descr">
+
+
+
+
+ <div class="jd-tagdata jd-tagdescr"><p>Used in onTapCommaned to indicate that an "up" event on the watch face has occurred that
+ has not been consumed by another activity. A TAP_TYPE_TOUCH will always occur first. This
+ event will not occur if a TAP_TYPE_TOUCH_CANCEL is sent.
+</p></div>
+
+
+ <div class="jd-tagdata">
+ <span class="jd-tagtitle">Constant Value: </span>
+ <span>
+
+ 2
+ (0x00000002)
+
+ </span>
+ </div>
+
+ </div>
+</div>
+
+
+
+<A NAME="TAP_TYPE_TOUCH"></A>
+
+<div class="jd-details api apilevel-">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ public
+ static
+ final
+ int
+ </span>
+ TAP_TYPE_TOUCH
+ </h4>
+ <div class="api-level">
+
+
+
+
+ </div>
+ <div class="jd-details-descr">
+
+
+
+
+ <div class="jd-tagdata jd-tagdescr"><p>Used in onTapCommand to indicate a "down" touch event on the watch face.
+</p></div>
+
+
+ <div class="jd-tagdata">
+ <span class="jd-tagtitle">Constant Value: </span>
+ <span>
+
+ 0
+ (0x00000000)
+
+ </span>
+ </div>
+
+ </div>
+</div>
+
+
+
+<A NAME="TAP_TYPE_TOUCH_CANCEL"></A>
+
+<div class="jd-details api apilevel-">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ public
+ static
+ final
+ int
+ </span>
+ TAP_TYPE_TOUCH_CANCEL
+ </h4>
+ <div class="api-level">
+
+
+
+
+ </div>
+ <div class="jd-details-descr">
+
+
+
+
+ <div class="jd-tagdata jd-tagdescr"><p>Used in onTapCaommand to indicate that a previous TAP_TYPE_TOUCH touch event has been
+ canceled. This generally happens when the watch face is touched but then a move or long
+ press occurs.
+</p></div>
+
+
+ <div class="jd-tagdata">
+ <span class="jd-tagtitle">Constant Value: </span>
+ <span>
+
+ 1
+ (0x00000001)
+
+ </span>
+ </div>
+
+ </div>
+</div>
+
+
+
<!-- Fields -->
@@ -6484,6 +6674,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/watchface/WatchFaceStyle.Builder.html b/docs/html/reference/android/support/wearable/watchface/WatchFaceStyle.Builder.html
index 956e3a8..a5401e5 100644
--- a/docs/html/reference/android/support/wearable/watchface/WatchFaceStyle.Builder.html
+++ b/docs/html/reference/android/support/wearable/watchface/WatchFaceStyle.Builder.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -466,6 +466,11 @@
<ul>
+ <li><h2>Annotations</h2>
+ <ul>
+ <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.TapType.html">WatchFaceService.TapType</a></li>
+ </ul>
+ </li>
<li><h2>Classes</h2>
@@ -609,7 +614,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -758,6 +763,29 @@
<a href="../../../../../reference/android/support/wearable/watchface/WatchFaceStyle.Builder.html">WatchFaceStyle.Builder</a></nobr>
</td>
<td class="jd-linkcol" width="100%"><nobr>
+ <span class="sympad"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceStyle.Builder.html#setAcceptsTapEvents(boolean)">setAcceptsTapEvents</a></span>(boolean acceptsTapEvents)</nobr>
+
+ <div class="jd-descrdiv">
+ Sets whether this watchface accepts tap events.
+
+
+
+ </div>
+
+ </td></tr>
+
+
+
+ <tr class="alt-color api apilevel-" >
+ <td class="jd-typecol"><nobr>
+
+
+
+
+
+ <a href="../../../../../reference/android/support/wearable/watchface/WatchFaceStyle.Builder.html">WatchFaceStyle.Builder</a></nobr>
+ </td>
+ <td class="jd-linkcol" width="100%"><nobr>
<span class="sympad"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceStyle.Builder.html#setAmbientPeekMode(int)">setAmbientPeekMode</a></span>(int ambientPeekMode)</nobr>
<div class="jd-descrdiv">
@@ -772,7 +800,7 @@
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -795,7 +823,7 @@
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -818,7 +846,7 @@
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -841,7 +869,7 @@
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -864,7 +892,7 @@
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -887,7 +915,7 @@
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -910,7 +938,7 @@
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -933,7 +961,7 @@
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -959,7 +987,7 @@
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1312,6 +1340,53 @@
</div>
+<A NAME="setAcceptsTapEvents(boolean)"></A>
+
+<div class="jd-details api apilevel-">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ public
+
+
+
+
+ <a href="../../../../../reference/android/support/wearable/watchface/WatchFaceStyle.Builder.html">WatchFaceStyle.Builder</a>
+ </span>
+ <span class="sympad">setAcceptsTapEvents</span>
+ <span class="normal">(boolean acceptsTapEvents)</span>
+ </h4>
+ <div class="api-level">
+ <div></div>
+
+
+
+ </div>
+ <div class="jd-details-descr">
+
+
+
+
+ <div class="jd-tagdata jd-tagdescr"><p>Sets whether this watchface accepts tap events. The default is false.
+ <p>
+ Watchfaces that set this <code>true</code> are indicating they are prepared to receive
+ <code><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.html#TAP_TYPE_TOUCH">TAP_TYPE_TOUCH</a></code>,
+ <code><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.html#TAP_TYPE_TOUCH_CANCEL">TAP_TYPE_TOUCH_CANCEL</a></code>,
+ and <code><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.html#TAP_TYPE_TAP">TAP_TYPE_TAP</a></code></p></div>
+ <div class="jd-tagdata">
+ <h5 class="jd-tagtitle">Parameters</h5>
+ <table class="jd-tagtable">
+ <tr>
+ <th>acceptsTapEvents</td>
+ <td>whether to receive touch events.
+</td>
+ </tr>
+ </table>
+ </div>
+
+ </div>
+</div>
+
+
<A NAME="setAmbientPeekMode(int)"></A>
<div class="jd-details api apilevel-">
@@ -1825,6 +1900,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/watchface/WatchFaceStyle.html b/docs/html/reference/android/support/wearable/watchface/WatchFaceStyle.html
index e08608f..70c3851 100644
--- a/docs/html/reference/android/support/wearable/watchface/WatchFaceStyle.html
+++ b/docs/html/reference/android/support/wearable/watchface/WatchFaceStyle.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -466,6 +466,11 @@
<ul>
+ <li><h2>Annotations</h2>
+ <ul>
+ <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.TapType.html">WatchFaceService.TapType</a></li>
+ </ul>
+ </li>
<li><h2>Classes</h2>
@@ -632,7 +637,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
<table class="jd-inheritance-table">
@@ -1022,6 +1027,29 @@
+ boolean</nobr>
+ </td>
+ <td class="jd-linkcol" width="100%"><nobr>
+ <span class="sympad"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceStyle.html#getAcceptsTapEvents()">getAcceptsTapEvents</a></span>()</nobr>
+
+ <div class="jd-descrdiv">
+ Whether the watchface accepts tap events.
+
+
+
+ </div>
+
+ </td></tr>
+
+
+
+ <tr class=" api apilevel-" >
+ <td class="jd-typecol"><nobr>
+
+
+
+
+
int</nobr>
</td>
<td class="jd-linkcol" width="100%"><nobr>
@@ -1039,7 +1067,7 @@
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1062,7 +1090,7 @@
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1085,7 +1113,7 @@
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1108,7 +1136,7 @@
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1131,7 +1159,7 @@
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1154,7 +1182,7 @@
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1177,7 +1205,7 @@
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1200,7 +1228,7 @@
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1223,7 +1251,7 @@
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1247,7 +1275,7 @@
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1263,7 +1291,7 @@
- <tr class=" api apilevel-" >
+ <tr class="alt-color api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1279,7 +1307,7 @@
- <tr class="alt-color api apilevel-" >
+ <tr class=" api apilevel-" >
<td class="jd-typecol"><nobr>
@@ -1706,7 +1734,8 @@
<div class="jd-tagdata jd-tagdescr"><p>When this background visibility is selected, the background of the peek card should only be
- shown briefly, and only if the peek card represents an interruptive notification.
+ shown briefly, and only if the peek card represents an interruptive notification. This is the
+ default mode.
</p></div>
@@ -1749,7 +1778,7 @@
<div class="jd-tagdata jd-tagdescr"><p>When this background visibility is selected, the background of the peek card should always
- be shown. This is the default mode.
+ be shown.
Note that this will obscure your watch face whenever there is a peek card showing.
</p></div>
@@ -2191,6 +2220,39 @@
</div>
+<A NAME="getAcceptsTapEvents()"></A>
+
+<div class="jd-details api apilevel-">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ public
+
+
+
+
+ boolean
+ </span>
+ <span class="sympad">getAcceptsTapEvents</span>
+ <span class="normal">()</span>
+ </h4>
+ <div class="api-level">
+ <div></div>
+
+
+
+ </div>
+ <div class="jd-details-descr">
+
+
+
+
+ <div class="jd-tagdata jd-tagdescr"><p>Whether the watchface accepts tap events. The default is false.
+</p></div>
+
+ </div>
+</div>
+
+
<A NAME="getAmbientPeekMode()"></A>
<div class="jd-details api apilevel-">
@@ -2705,6 +2767,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/watchface/package-summary.html b/docs/html/reference/android/support/wearable/watchface/package-summary.html
index 6853fc4..a654b13 100644
--- a/docs/html/reference/android/support/wearable/watchface/package-summary.html
+++ b/docs/html/reference/android/support/wearable/watchface/package-summary.html
@@ -128,7 +128,7 @@
var metaTags = [];
var devsite = false;
</script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
@@ -467,6 +467,11 @@
<ul>
+ <li><h2>Annotations</h2>
+ <ul>
+ <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.TapType.html">WatchFaceService.TapType</a></li>
+ </ul>
+ </li>
<li><h2>Classes</h2>
@@ -548,7 +553,7 @@
<div id="naMessage"></div>
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
@@ -556,6 +561,27 @@
+ <h2>Annotations</h2>
+ <div class="jd-sumtable">
+
+
+ <table class="jd-sumtable-expando">
+
+ <tr class="alt-color api apilevel-" >
+ <td class="jd-linkcol"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.TapType.html">WatchFaceService.TapType</a></td>
+ <td class="jd-descrcol" width="100%">
+
+
+
+
+ </td>
+ </tr>
+
+
+ </table>
+
+ </div>
+
@@ -726,6 +752,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/tools/help/adb.jd b/docs/html/tools/help/adb.jd
index 641d463..2faff4f 100644
--- a/docs/html/tools/help/adb.jd
+++ b/docs/html/tools/help/adb.jd
@@ -420,62 +420,54 @@
<ol>
<li>
-Connect Android device and adb host computer
+<p>Connect your Android device and adb host computer
to a common Wi-Fi network accessible to both.
We have found that not all access points
are suitable; you may need to use an access point
-whose firewall is configured properly to support adb.
+whose firewall is configured properly to support adb.</p>
+
+<p class="note"><strong>Note: </strong>If you are attempting to connect
+to a Wear device, force it to connect to Wi-Fi by shutting off Bluetooth
+on the phone connected to it.</p>
</li>
<li>
-Connect the device with USB cable to host.
+Connect the device to the host computer with a USB cable.
</li>
<li>
-Make sure adb is running in USB mode on host.
-<pre>
-$ adb usb
-restarting in USB mode
-</pre>
-</li>
-
-<li>
-Connect to the device over USB.
-<pre>
-$ adb devices
-List of devices attached
-######## device
-</pre>
-</li>
-
-<li>
-Restart host adb in tcpip mode.
-<pre>
+Set the target device to listen for a TCP/IP connection on port 5555.
+<pre class="no-pretty-print">
$ adb tcpip 5555
-restarting in TCP mode port: 5555
</pre>
</li>
<li>
-Find out the IP address of the Android device:
-Settings -> About tablet -> Status -> IP address.
-Remember the IP address, of the form <code>#.#.#.#</code>.
+Disconnect the USB cable from the target device.
</li>
<li>
-Connect adb host to device:
-<pre>
-$ adb connect #.#.#.#
-connected to #.#.#.#:5555
+Find the IP address of the Android device. For example, on a Nexus device, you can find
+the IP address at <strong>Settings</strong> > <strong>About tablet</strong>
+(or <strong>About phone</strong>) > <strong>Status</strong> > <strong>IP address</strong>. Or,
+on an Android Wear device, you can find the IP address at <strong>Settings</strong> >
+<strong>Wi-Fi Settings</strong> > <strong>Advanced</strong> > <strong>IP address</strong>.
+</li>
+
+<li>
+Connect to the device, identifying it by IP address.
+<pre class="no-pretty-print">
+$ adb connect <device-ip-address>
</pre>
</li>
+
<li>
-Remove USB cable from device, and confirm you can still access device:
-<pre>
+Confirm that your host computer is connected to the target device:
+<pre class="no-pretty-print">
$ adb devices
List of devices attached
-#.#.#.#:5555 device
+<device-ip-address>:5555 device
</pre>
</ol>
@@ -500,10 +492,10 @@
<li>
Or if that doesn't work, reset your adb host:
-<pre>
+<pre class="no-pretty-print">
adb kill-server
</pre>
and then start over from the beginning.
</li>
-</ol>
\ No newline at end of file
+</ol>
diff --git a/docs/html/training/training_toc.cs b/docs/html/training/training_toc.cs
index 5279969..7cffdd8 100644
--- a/docs/html/training/training_toc.cs
+++ b/docs/html/training/training_toc.cs
@@ -989,6 +989,9 @@
<a href="<?cs var:toroot ?>training/wearables/watch-faces/information.html">Showing Information in Watch Faces</a>
</li>
<li>
+ <a href="<?cs var:toroot ?>training/wearables/watch-faces/interacting.html">Creating Interactive Watch Faces</a>
+ </li>
+ <li>
<a href="<?cs var:toroot ?>training/wearables/watch-faces/configuration.html">Providing Configuration Activities</a>
</li>
<li>
diff --git a/docs/html/training/wearables/watch-faces/index.jd b/docs/html/training/wearables/watch-faces/index.jd
index ec428c1..a329fda 100644
--- a/docs/html/training/wearables/watch-faces/index.jd
+++ b/docs/html/training/wearables/watch-faces/index.jd
@@ -65,6 +65,9 @@
<dt><a href="{@docRoot}training/wearables/watch-faces/information.html">
Showing Information in Watch Faces</a></dt>
<dd>Learn how to incorporate contextual information into your watch face.</dd>
+<dt><a href="{@docRoot}training/wearables/watch-faces/interacting.html">
+Creating Interactive Watch Faces</a></dt>
+<dd>Learn how to enable the user to interact with your watch face.</dd>
<dt><a href="{@docRoot}training/wearables/watch-faces/configuration.html">
Providing Configuration Activities</a></dt>
<dd>Learn how to create watch faces with configurable parameters.</dd>
diff --git a/docs/html/training/wearables/watch-faces/interacting.jd b/docs/html/training/wearables/watch-faces/interacting.jd
new file mode 100644
index 0000000..5a44fde
--- /dev/null
+++ b/docs/html/training/wearables/watch-faces/interacting.jd
@@ -0,0 +1,133 @@
+page.title=Creating Interactive Watch Faces
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+<h2>This lesson teaches you to</h2>
+<ol>
+ <li><a href="#Construct">Construct an Interactive Watch Face</a></li>
+ <li><a href="#Handle">Handle Gestures</a></li>
+</ol>
+<h2>You should also read</h2>
+<ul>
+ <li><a href="{@docRoot}design/wear/watchfaces.html">Watch Faces for Android Wear</a></li>
+</ul>
+<h2>Related Samples</h2>
+ <ul>
+ <li><a href="{@docRoot}samples/WatchFace/index.html">WatchFace</a></li>
+ </ul>
+</div>
+</div>
+
+<p>Your watch's display is more than just a pretty face: Users can interact with it.
+For example, a user might tap the watch face to learn what song is currently playing, or
+to see the day's agenda. Android Wear allows Android Wear watch faces to accept
+the single-tap gesture at a given location on the watch face, as long as there's not another
+UI element that also responds to that gesture.
+
+<p>This lesson teaches you how to implement an interactive watch face by first constructing the
+watch face style, and then implementing gesture handling.</p>
+
+<p class="note"><strong>Note:</strong> Before beginning development work on your interactive watch
+face, you should be sure to read the <a href="{@docRoot}design/wear/watchfaces.html">Watch Faces for
+Android Wear</a> design guide.
+
+<h2 id="Construct">Handling Tap Events</h2>
+
+<p>When constructing an interactive watch-face style, the first thing the app must do is tell the
+system that the watch face receives <a href="{@docRoot}design/wear/watchfaces.html#ag">tap events</a>.
+The following example shows how to do this:
+
+<pre>
+setWatchFaceStyle(new WatchFaceStyle.Builder(mService)
+ .setAcceptsTapEvents(true)
+ // other style customizations
+ .build());
+</pre>
+
+<p>When the system detects a tap on the watch face, it triggers the
+<a href="{@docRoot}reference/android/support/wearable/watchface/WatchFaceService.Engine.html#onTapCommand(int, int, int, long)">
+{@code WatchFaceService.Engine.onTapCommand()}</a> method. Override this method in your
+implementation of
+<a href="{@docRoot}reference/android/support/wearable/watchface/WatchFaceService.Engine.html">
+{@code WatchFaceService.Engine}</a>to initiate the action you wish to perform, such
+as showing a detailed step count or changing the theme of the watch face. The code snippet
+in <a href="#Handle">Handle Gestures</a> shows an example of such an
+implementation.</p>
+
+<h2 id="Handle">Handle Gestures</h2>
+
+<p> To provide a consistent user experience, the system
+reserves gestures such as drag and long-press for system UI elements.
+Therefore, the system does not send raw touch events to the watch face. Instead, the system forwards specific commands to the
+<a href="{@docRoot}reference/android/support/wearable/watchface/WatchFaceService.Engine.html#onTapCommand(int, int, int, long)">
+onTapCommand()</a> method.
+
+<p>The system sends the first command,
+<a href="{@docRoot}reference/android/support/wearable/watchface/WatchFaceService.html#TAP_TYPE_TOUCH">
+{@code TAP_TYPE_TOUCH}</a>, when the user initially touches the
+screen. This event lets you provide visual feedback to the user on touch. Your app should not
+launch a UI when this event triggers. Launching a UI prevents drag events from opening the app
+launcher, settings shade, and notifications stream.</p>
+
+<p>Before sending the next command, the system judges whether the contact is a single tap, which is
+<a href="{@docRoot}design/wear/watchfaces.html#ag">the only gesture allowed</a>. If the user
+immediately lifts their finger, the system determines that a single tap took place, and forwards
+a
+<a href="{@docRoot}reference/android/support/wearable/watchface/WatchFaceService.html#TAP_TYPE_TAP"</a>
+{@code TAP_TYPE_TAP}</a> event. If the user does not immediately lift their finger, the system
+forwards a
+<a href="{@docRoot}reference/android/support/wearable/watchface/WatchFaceService.html#TAP_TYPE_TOUCH_CANCEL"</a>
+{@code TAP_TYPE_TOUCH_CANCEL}</a> event. Once the user has triggered a
+<a href="{@docRoot}reference/android/support/wearable/watchface/WatchFaceService.html#TAP_TYPE_TOUCH_CANCEL"</a>
+{@code TAP_TYPE_TOUCH_CANCEL}</a> event, they cannot trigger a
+<a href="{@docRoot}reference/android/support/wearable/watchface/WatchFaceService.html#TAP_TYPE_TAP"</a>
+{@code TAP_TYPE_TAP}</a> event until they
+make a new contact with the screen.</p>
+
+<p>The following example shows you how to implement tap events on a watch face:</p>
+
+
+<pre>
+@Override
+public void onTapCommand(
+ @TapType int tapType, int x, int y, long eventTime) {
+ switch (tapType) {
+ case WatchFaceService.TAP_TYPE_TAP:
+ hideTapHighlight();
+ if (withinTapRegion(x, y)) {
+ // Implement the tap action
+ // (e.g. show detailed step count)
+ onWatchFaceTap();
+ }
+ break;
+
+ case WatchFaceService.TAP_TYPE_TOUCH:
+ if (withinTapRegion(x, y)) {
+ // Provide visual feedback of touch event
+ startTapHighlight(x, y, eventTime);
+ }
+ break;
+
+ case WatchFaceService.TAP_TYPE_TOUCH_CANCEL:
+ hideTapHighlight();
+ break;
+
+ default:
+ super.onTapCommand(tapType, x, y, eventTime);
+ break;
+ }
+}
+</pre>
+
+<p>In this example, the app determines what kind of event has taken place,
+and responds accordingly. If the event is initial contact by the user's finger,
+the app displays visual feedback. If the event is an immediate lifting
+of the finger after contact, it performs the action on which the
+user tapped. If the event is prolonged contact by the finger, the app
+does nothing.</p>
+
+
+
+
diff --git a/graphics/java/android/graphics/Path.java b/graphics/java/android/graphics/Path.java
index 0e9823d..91e704a 100644
--- a/graphics/java/android/graphics/Path.java
+++ b/graphics/java/android/graphics/Path.java
@@ -486,9 +486,9 @@
*/
public enum Direction {
/** clockwise */
- CW (1), // must match enum in SkPath.h
+ CW (0), // must match enum in SkPath.h
/** counter-clockwise */
- CCW (2); // must match enum in SkPath.h
+ CCW (1); // must match enum in SkPath.h
Direction(int ni) {
nativeInt = ni;
diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java
index 32f6a89..464f3de 100644
--- a/graphics/java/android/graphics/drawable/RippleDrawable.java
+++ b/graphics/java/android/graphics/drawable/RippleDrawable.java
@@ -855,7 +855,8 @@
// Position the shader to account for canvas translation.
if (mMaskShader != null) {
- mMaskMatrix.setTranslate(-x, -y);
+ final Rect bounds = getBounds();
+ mMaskMatrix.setTranslate(bounds.left - x, bounds.top - y);
mMaskShader.setLocalMatrix(mMaskMatrix);
}
diff --git a/libs/hwui/AmbientShadow.cpp b/libs/hwui/AmbientShadow.cpp
index 751531e..20ecda2 100644
--- a/libs/hwui/AmbientShadow.cpp
+++ b/libs/hwui/AmbientShadow.cpp
@@ -52,14 +52,14 @@
// If this is set to negative value, then all the edge will be tessellated.
#define ALPHA_THRESHOLD (0.1f / 255.0f)
-#include <math.h>
-#include <utils/Log.h>
-
#include "AmbientShadow.h"
+
#include "ShadowTessellator.h"
#include "Vertex.h"
#include "VertexBuffer.h"
-#include "utils/MathUtils.h"
+
+#include <algorithm>
+#include <utils/Log.h>
namespace android {
namespace uirenderer {
@@ -78,7 +78,7 @@
// The input z value will be converted to be non-negative inside.
// The output must be ranged from 0 to 1.
inline float getAlphaFromFactoredZ(float factoredZ) {
- return 1.0 / (1 + MathUtils::max(factoredZ, 0.0f));
+ return 1.0 / (1 + std::max(factoredZ, 0.0f));
}
// The shader is using gaussian function e^-(1-x)*(1-x)*4, therefore, we transform
diff --git a/libs/hwui/Animator.cpp b/libs/hwui/Animator.cpp
index 512e0e2..5ca2a2f 100644
--- a/libs/hwui/Animator.cpp
+++ b/libs/hwui/Animator.cpp
@@ -36,8 +36,8 @@
, mFinalValue(finalValue)
, mDeltaValue(0)
, mFromValue(0)
- , mStagingPlayState(NOT_STARTED)
- , mPlayState(NOT_STARTED)
+ , mStagingPlayState(PlayState::NotStarted)
+ , mPlayState(PlayState::NotStarted)
, mHasStartValue(false)
, mStartTime(0)
, mDuration(300)
@@ -50,7 +50,7 @@
void BaseRenderNodeAnimator::checkMutable() {
// Should be impossible to hit as the Java-side also has guards for this
- LOG_ALWAYS_FATAL_IF(mStagingPlayState != NOT_STARTED,
+ LOG_ALWAYS_FATAL_IF(mStagingPlayState != PlayState::NotStarted,
"Animator has already been started!");
}
@@ -92,9 +92,9 @@
if (mStagingPlayState > mPlayState) {
mPlayState = mStagingPlayState;
// Oh boy, we're starting! Man the battle stations!
- if (mPlayState == RUNNING) {
+ if (mPlayState == PlayState::Running) {
transitionToRunning(context);
- } else if (mPlayState == FINISHED) {
+ } else if (mPlayState == PlayState::Finished) {
callOnFinishedListener(context);
}
}
@@ -124,10 +124,10 @@
}
bool BaseRenderNodeAnimator::animate(AnimationContext& context) {
- if (mPlayState < RUNNING) {
+ if (mPlayState < PlayState::Running) {
return false;
}
- if (mPlayState == FINISHED) {
+ if (mPlayState == PlayState::Finished) {
return true;
}
@@ -141,18 +141,18 @@
}
float fraction = 1.0f;
- if (mPlayState == RUNNING && mDuration > 0) {
+ if (mPlayState == PlayState::Running && mDuration > 0) {
fraction = (float)(context.frameTimeMs() - mStartTime) / mDuration;
}
if (fraction >= 1.0f) {
fraction = 1.0f;
- mPlayState = FINISHED;
+ mPlayState = PlayState::Finished;
}
fraction = mInterpolator->interpolate(fraction);
setValue(mTarget, mFromValue + (mDeltaValue * fraction));
- if (mPlayState == FINISHED) {
+ if (mPlayState == PlayState::Finished) {
callOnFinishedListener(context);
return true;
}
@@ -161,8 +161,8 @@
}
void BaseRenderNodeAnimator::forceEndNow(AnimationContext& context) {
- if (mPlayState < FINISHED) {
- mPlayState = FINISHED;
+ if (mPlayState < PlayState::Finished) {
+ mPlayState = PlayState::Finished;
callOnFinishedListener(context);
}
}
@@ -212,9 +212,9 @@
}
void RenderPropertyAnimator::onStagingPlayStateChanged() {
- if (mStagingPlayState == RUNNING) {
+ if (mStagingPlayState == PlayState::Running) {
(mTarget->mutateStagingProperties().*mPropertyAccess->setter)(finalValue());
- } else if (mStagingPlayState == FINISHED) {
+ } else if (mStagingPlayState == PlayState::Finished) {
// We're being canceled, so make sure that whatever values the UI thread
// is observing for us is pushed over
mTarget->setPropertyFieldsDirty(dirtyMask());
diff --git a/libs/hwui/Animator.h b/libs/hwui/Animator.h
index 1b3d8e7..aea95bf 100644
--- a/libs/hwui/Animator.h
+++ b/libs/hwui/Animator.h
@@ -59,8 +59,8 @@
mMayRunAsync = mayRunAsync;
}
bool mayRunAsync() { return mMayRunAsync; }
- ANDROID_API void start() { mStagingPlayState = RUNNING; onStagingPlayStateChanged(); }
- ANDROID_API void end() { mStagingPlayState = FINISHED; onStagingPlayStateChanged(); }
+ ANDROID_API void start() { mStagingPlayState = PlayState::Running; onStagingPlayStateChanged(); }
+ ANDROID_API void end() { mStagingPlayState = PlayState::Finished; onStagingPlayStateChanged(); }
void attach(RenderNode* target);
virtual void onAttached() {}
@@ -68,8 +68,8 @@
void pushStaging(AnimationContext& context);
bool animate(AnimationContext& context);
- bool isRunning() { return mPlayState == RUNNING; }
- bool isFinished() { return mPlayState == FINISHED; }
+ bool isRunning() { return mPlayState == PlayState::Running; }
+ bool isFinished() { return mPlayState == PlayState::Finished; }
float finalValue() { return mFinalValue; }
ANDROID_API virtual uint32_t dirtyMask() = 0;
@@ -77,6 +77,12 @@
void forceEndNow(AnimationContext& context);
protected:
+ enum class PlayState {
+ NotStarted,
+ Running,
+ Finished,
+ };
+
BaseRenderNodeAnimator(float finalValue);
virtual ~BaseRenderNodeAnimator();
@@ -88,12 +94,6 @@
virtual void onStagingPlayStateChanged() {}
- enum PlayState {
- NOT_STARTED,
- RUNNING,
- FINISHED,
- };
-
RenderNode* mTarget;
float mFinalValue;
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index f663f07..ff71313 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -245,7 +245,7 @@
FLUSH_LOGD("Flushing caches (mode %d)", mode);
switch (mode) {
- case kFlushMode_Full:
+ case FlushMode::Full:
textureCache.clear();
patchCache.clear();
dropShadowCache.clear();
@@ -254,13 +254,13 @@
fboCache.clear();
dither.clear();
// fall through
- case kFlushMode_Moderate:
+ case FlushMode::Moderate:
fontRenderer->flush();
textureCache.flush();
pathCache.clear();
tessellationCache.clear();
// fall through
- case kFlushMode_Layers:
+ case FlushMode::Layers:
layerCache.clear();
renderBufferCache.clear();
break;
diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h
index a02e15d..929db17 100644
--- a/libs/hwui/Caches.h
+++ b/libs/hwui/Caches.h
@@ -83,10 +83,10 @@
static Caches* sInstance;
public:
- enum FlushMode {
- kFlushMode_Layers = 0,
- kFlushMode_Moderate,
- kFlushMode_Full
+ enum class FlushMode {
+ Layers = 0,
+ Moderate,
+ Full
};
/**
@@ -103,7 +103,7 @@
/**
* Destroys all resources associated with this cache. This should
- * be called after a flush(kFlushMode_Full).
+ * be called after a flush(FlushMode::Full).
*/
void terminate();
diff --git a/libs/hwui/Canvas.h b/libs/hwui/Canvas.h
index 3c77b3d..4bd4ac8 100644
--- a/libs/hwui/Canvas.h
+++ b/libs/hwui/Canvas.h
@@ -85,10 +85,6 @@
virtual void getMatrix(SkMatrix* outMatrix) const = 0;
virtual void setMatrix(const SkMatrix& matrix) = 0;
- /// Like setMatrix(), but to be translated into local / view-relative coordinates
- /// rather than executed in global / device coordinates at rendering time.
- virtual void setLocalMatrix(const SkMatrix& matrix) = 0;
-
virtual void concat(const SkMatrix& matrix) = 0;
virtual void rotate(float degrees) = 0;
virtual void scale(float sx, float sy) = 0;
diff --git a/libs/hwui/CanvasState.cpp b/libs/hwui/CanvasState.cpp
index e22b0d3..e307ad9 100644
--- a/libs/hwui/CanvasState.cpp
+++ b/libs/hwui/CanvasState.cpp
@@ -138,7 +138,7 @@
}
void CanvasState::setMatrix(const Matrix4& matrix) {
- mSnapshot->transform->load(matrix);
+ *(mSnapshot->transform) = matrix;
}
void CanvasState::concatMatrix(const SkMatrix& matrix) {
@@ -155,17 +155,20 @@
///////////////////////////////////////////////////////////////////////////////
bool CanvasState::clipRect(float left, float top, float right, float bottom, SkRegion::Op op) {
- mDirtyClip |= mSnapshot->clip(left, top, right, bottom, op);
+ mSnapshot->clip(left, top, right, bottom, op);
+ mDirtyClip = true;
return !mSnapshot->clipIsEmpty();
}
bool CanvasState::clipPath(const SkPath* path, SkRegion::Op op) {
- mDirtyClip |= mSnapshot->clipPath(*path, op);
+ mSnapshot->clipPath(*path, op);
+ mDirtyClip = true;
return !mSnapshot->clipIsEmpty();
}
bool CanvasState::clipRegion(const SkRegion* region, SkRegion::Op op) {
- mDirtyClip |= mSnapshot->clipRegionTransformed(*region, op);
+ mSnapshot->clipRegionTransformed(*region, op);
+ mDirtyClip = true;
return !mSnapshot->clipIsEmpty();
}
diff --git a/libs/hwui/ClipArea.cpp b/libs/hwui/ClipArea.cpp
index b1a6844..8e7efb4 100644
--- a/libs/hwui/ClipArea.cpp
+++ b/libs/hwui/ClipArea.cpp
@@ -32,9 +32,7 @@
}
static void handlePoint(Rect& transformedBounds, const Matrix4& transform, float x, float y) {
- Vertex v;
- v.x = x;
- v.y = y;
+ Vertex v = {x, y};
transform.mapPoint(v.x, v.y);
transformedBounds.expandToCoverVertex(v.x, v.y);
}
@@ -187,7 +185,7 @@
*/
ClipArea::ClipArea()
- : mMode(kModeRectangle) {
+ : mMode(Mode::Rectangle) {
}
/*
@@ -200,45 +198,46 @@
}
void ClipArea::setEmpty() {
- mMode = kModeRectangle;
+ mMode = Mode::Rectangle;
mClipRect.setEmpty();
mClipRegion.setEmpty();
mRectangleList.setEmpty();
}
void ClipArea::setClip(float left, float top, float right, float bottom) {
- mMode = kModeRectangle;
+ mMode = Mode::Rectangle;
mClipRect.set(left, top, right, bottom);
mClipRegion.setEmpty();
}
-bool ClipArea::clipRectWithTransform(float left, float top, float right,
+void ClipArea::clipRectWithTransform(float left, float top, float right,
float bottom, const mat4* transform, SkRegion::Op op) {
Rect r(left, top, right, bottom);
- return clipRectWithTransform(r, transform, op);
+ clipRectWithTransform(r, transform, op);
}
-bool ClipArea::clipRectWithTransform(const Rect& r, const mat4* transform,
+void ClipArea::clipRectWithTransform(const Rect& r, const mat4* transform,
SkRegion::Op op) {
switch (mMode) {
- case kModeRectangle:
- return rectangleModeClipRectWithTransform(r, transform, op);
- case kModeRectangleList:
- return rectangleListModeClipRectWithTransform(r, transform, op);
- case kModeRegion:
- return regionModeClipRectWithTransform(r, transform, op);
+ case Mode::Rectangle:
+ rectangleModeClipRectWithTransform(r, transform, op);
+ break;
+ case Mode::RectangleList:
+ rectangleListModeClipRectWithTransform(r, transform, op);
+ break;
+ case Mode::Region:
+ regionModeClipRectWithTransform(r, transform, op);
+ break;
}
- return false;
}
-bool ClipArea::clipRegion(const SkRegion& region, SkRegion::Op op) {
+void ClipArea::clipRegion(const SkRegion& region, SkRegion::Op op) {
enterRegionMode();
mClipRegion.op(region, op);
onClipRegionUpdated();
- return true;
}
-bool ClipArea::clipPathWithTransform(const SkPath& path, const mat4* transform,
+void ClipArea::clipPathWithTransform(const SkPath& path, const mat4* transform,
SkRegion::Op op) {
SkMatrix skTransform;
transform->copyTo(skTransform);
@@ -246,7 +245,7 @@
path.transform(skTransform, &transformed);
SkRegion region;
regionFromPath(transformed, region);
- return clipRegion(region, op);
+ clipRegion(region, op);
}
/*
@@ -257,19 +256,20 @@
// Entering rectangle mode discards any
// existing clipping information from the other modes.
// The only way this occurs is by a clip setting operation.
- mMode = kModeRectangle;
+ mMode = Mode::Rectangle;
}
-bool ClipArea::rectangleModeClipRectWithTransform(const Rect& r,
+void ClipArea::rectangleModeClipRectWithTransform(const Rect& r,
const mat4* transform, SkRegion::Op op) {
if (op == SkRegion::kReplace_Op && transform->rectToRect()) {
mClipRect = r;
transform->mapRect(mClipRect);
- return true;
+ return;
} else if (op != SkRegion::kIntersect_Op) {
enterRegionMode();
- return regionModeClipRectWithTransform(r, transform, op);
+ regionModeClipRectWithTransform(r, transform, op);
+ return;
}
if (transform->rectToRect()) {
@@ -279,19 +279,18 @@
if (!hasIntersection) {
mClipRect.setEmpty();
}
- return true;
+ return;
}
enterRectangleListMode();
- return rectangleListModeClipRectWithTransform(r, transform, op);
+ rectangleListModeClipRectWithTransform(r, transform, op);
}
-bool ClipArea::rectangleModeClipRectWithTransform(float left, float top,
+void ClipArea::rectangleModeClipRectWithTransform(float left, float top,
float right, float bottom, const mat4* transform, SkRegion::Op op) {
Rect r(left, top, right, bottom);
- bool result = rectangleModeClipRectWithTransform(r, transform, op);
+ rectangleModeClipRectWithTransform(r, transform, op);
mClipRect = mRectangleList.calculateBounds();
- return result;
}
/*
@@ -302,25 +301,24 @@
// Is is only legal to enter rectangle list mode from
// rectangle mode, since rectangle list mode cannot represent
// all clip areas that can be represented by a region.
- ALOG_ASSERT(mMode == kModeRectangle);
- mMode = kModeRectangleList;
+ ALOG_ASSERT(mMode == Mode::Rectangle);
+ mMode = Mode::RectangleList;
mRectangleList.set(mClipRect, Matrix4::identity());
}
-bool ClipArea::rectangleListModeClipRectWithTransform(const Rect& r,
+void ClipArea::rectangleListModeClipRectWithTransform(const Rect& r,
const mat4* transform, SkRegion::Op op) {
if (op != SkRegion::kIntersect_Op
|| !mRectangleList.intersectWith(r, *transform)) {
enterRegionMode();
- return regionModeClipRectWithTransform(r, transform, op);
+ regionModeClipRectWithTransform(r, transform, op);
}
- return true;
}
-bool ClipArea::rectangleListModeClipRectWithTransform(float left, float top,
+void ClipArea::rectangleListModeClipRectWithTransform(float left, float top,
float right, float bottom, const mat4* transform, SkRegion::Op op) {
Rect r(left, top, right, bottom);
- return rectangleListModeClipRectWithTransform(r, transform, op);
+ rectangleListModeClipRectWithTransform(r, transform, op);
}
/*
@@ -329,9 +327,9 @@
void ClipArea::enterRegionMode() {
Mode oldMode = mMode;
- mMode = kModeRegion;
- if (oldMode != kModeRegion) {
- if (oldMode == kModeRectangle) {
+ mMode = Mode::Region;
+ if (oldMode != Mode::Region) {
+ if (oldMode == Mode::Rectangle) {
mClipRegion.setRect(mClipRect.left, mClipRect.top,
mClipRect.right, mClipRect.bottom);
} else {
@@ -341,20 +339,18 @@
}
}
-bool ClipArea::regionModeClipRectWithTransform(const Rect& r,
+void ClipArea::regionModeClipRectWithTransform(const Rect& r,
const mat4* transform, SkRegion::Op op) {
SkPath transformedRect = pathFromTransformedRectangle(r, *transform);
SkRegion transformedRectRegion;
regionFromPath(transformedRect, transformedRectRegion);
mClipRegion.op(transformedRectRegion, op);
onClipRegionUpdated();
- return true;
}
-bool ClipArea::regionModeClipRectWithTransform(float left, float top,
+void ClipArea::regionModeClipRectWithTransform(float left, float top,
float right, float bottom, const mat4* transform, SkRegion::Op op) {
- return regionModeClipRectWithTransform(Rect(left, top, right, bottom),
- transform, op);
+ regionModeClipRectWithTransform(Rect(left, top, right, bottom), transform, op);
}
void ClipArea::onClipRegionUpdated() {
diff --git a/libs/hwui/ClipArea.h b/libs/hwui/ClipArea.h
index 51ef27b..38fefe5 100644
--- a/libs/hwui/ClipArea.h
+++ b/libs/hwui/ClipArea.h
@@ -80,6 +80,13 @@
};
class ClipArea {
+private:
+ enum class Mode {
+ Rectangle,
+ Region,
+ RectangleList
+ };
+
public:
ClipArea();
@@ -91,12 +98,12 @@
void setEmpty();
void setClip(float left, float top, float right, float bottom);
- bool clipRectWithTransform(float left, float top, float right, float bottom,
- const mat4* transform, SkRegion::Op op = SkRegion::kIntersect_Op);
- bool clipRectWithTransform(const Rect& r, const mat4* transform,
- SkRegion::Op op = SkRegion::kIntersect_Op);
- bool clipRegion(const SkRegion& region, SkRegion::Op op = SkRegion::kIntersect_Op);
- bool clipPathWithTransform(const SkPath& path, const mat4* transform,
+ void clipRectWithTransform(float left, float top, float right, float bottom,
+ const mat4* transform, SkRegion::Op op);
+ void clipRectWithTransform(const Rect& r, const mat4* transform,
+ SkRegion::Op op);
+ void clipRegion(const SkRegion& region, SkRegion::Op op);
+ void clipPathWithTransform(const SkPath& path, const mat4* transform,
SkRegion::Op op);
const Rect& getClipRect() const {
@@ -112,41 +119,39 @@
}
bool isRegion() const {
- return kModeRegion == mMode;
+ return Mode::Region == mMode;
}
bool isSimple() const {
- return mMode == kModeRectangle;
+ return mMode == Mode::Rectangle;
}
bool isRectangleList() const {
- return mMode == kModeRectangleList;
+ return mMode == Mode::RectangleList;
}
private:
void enterRectangleMode();
- bool rectangleModeClipRectWithTransform(const Rect& r, const mat4* transform, SkRegion::Op op);
- bool rectangleModeClipRectWithTransform(float left, float top, float right,
+ void rectangleModeClipRectWithTransform(const Rect& r, const mat4* transform, SkRegion::Op op);
+ void rectangleModeClipRectWithTransform(float left, float top, float right,
float bottom, const mat4* transform, SkRegion::Op op);
void enterRectangleListMode();
- bool rectangleListModeClipRectWithTransform(float left, float top,
+ void rectangleListModeClipRectWithTransform(float left, float top,
float right, float bottom, const mat4* transform, SkRegion::Op op);
- bool rectangleListModeClipRectWithTransform(const Rect& r,
+ void rectangleListModeClipRectWithTransform(const Rect& r,
const mat4* transform, SkRegion::Op op);
void enterRegionModeFromRectangleMode();
void enterRegionModeFromRectangleListMode();
void enterRegionMode();
- bool regionModeClipRectWithTransform(const Rect& r, const mat4* transform,
+ void regionModeClipRectWithTransform(const Rect& r, const mat4* transform,
SkRegion::Op op);
- bool regionModeClipRectWithTransform(float left, float top, float right,
+ void regionModeClipRectWithTransform(float left, float top, float right,
float bottom, const mat4* transform, SkRegion::Op op);
void ensureClipRegion();
void onClipRegionUpdated();
- bool clipRegionOp(float left, float top, float right, float bottom,
- SkRegion::Op op);
SkRegion createViewportRegion() {
return SkRegion(mViewportBounds.toSkIRect());
@@ -158,12 +163,6 @@
pathAsRegion.setPath(path, createViewportRegion());
}
- enum Mode {
- kModeRectangle,
- kModeRegion,
- kModeRectangleList
- };
-
Mode mMode;
Rect mViewportBounds;
Rect mClipRect;
diff --git a/libs/hwui/DisplayListCanvas.cpp b/libs/hwui/DisplayListCanvas.cpp
index 61c5883..506bfad 100644
--- a/libs/hwui/DisplayListCanvas.cpp
+++ b/libs/hwui/DisplayListCanvas.cpp
@@ -168,11 +168,6 @@
mState.setMatrix(matrix);
}
-void DisplayListCanvas::setLocalMatrix(const SkMatrix& matrix) {
- addStateOp(new (alloc()) SetLocalMatrixOp(matrix));
- mState.setMatrix(matrix);
-}
-
void DisplayListCanvas::concat(const SkMatrix& matrix) {
addStateOp(new (alloc()) ConcatMatrixOp(matrix));
mState.concatMatrix(matrix);
@@ -221,11 +216,11 @@
addRenderNodeOp(op);
}
-void DisplayListCanvas::drawLayer(DeferredLayerUpdater* layerHandle, float x, float y) {
+void DisplayListCanvas::drawLayer(DeferredLayerUpdater* layerHandle) {
// We ref the DeferredLayerUpdater due to its thread-safe ref-counting
// semantics.
mDisplayListData->ref(layerHandle);
- addDrawOp(new (alloc()) DrawLayerOp(layerHandle->backingLayer(), x, y));
+ addDrawOp(new (alloc()) DrawLayerOp(layerHandle->backingLayer()));
}
void DisplayListCanvas::drawBitmap(const SkBitmap* bitmap, const SkPaint* paint) {
diff --git a/libs/hwui/DisplayListCanvas.h b/libs/hwui/DisplayListCanvas.h
index 3b61904..392bb3e 100644
--- a/libs/hwui/DisplayListCanvas.h
+++ b/libs/hwui/DisplayListCanvas.h
@@ -91,7 +91,7 @@
// ----------------------------------------------------------------------------
// HWUI Canvas draw operations - special
// ----------------------------------------------------------------------------
- void drawLayer(DeferredLayerUpdater* layerHandle, float x, float y);
+ void drawLayer(DeferredLayerUpdater* layerHandle);
void drawRenderNode(RenderNode* renderNode);
// TODO: rename for consistency
@@ -143,7 +143,6 @@
// Matrix
virtual void getMatrix(SkMatrix* outMatrix) const override { mState.getMatrix(outMatrix); }
virtual void setMatrix(const SkMatrix& matrix) override;
- virtual void setLocalMatrix(const SkMatrix& matrix) override;
virtual void concat(const SkMatrix& matrix) override;
virtual void rotate(float degrees) override;
diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h
index 8ff58d4..14126a9 100644
--- a/libs/hwui/DisplayListOp.h
+++ b/libs/hwui/DisplayListOp.h
@@ -472,7 +472,9 @@
: mMatrix(matrix) {}
virtual void applyState(OpenGLRenderer& renderer, int saveCount) const override {
- renderer.setMatrix(mMatrix);
+ // Setting a matrix on a Canvas isn't equivalent to setting a total matrix on the scene.
+ // Set a canvas-relative matrix on the renderer instead.
+ renderer.setLocalMatrix(mMatrix);
}
virtual void output(int level, uint32_t logFlags) const override {
@@ -489,25 +491,6 @@
const SkMatrix mMatrix;
};
-class SetLocalMatrixOp : public StateOp {
-public:
- SetLocalMatrixOp(const SkMatrix& matrix)
- : mMatrix(matrix) {}
-
- virtual void applyState(OpenGLRenderer& renderer, int saveCount) const override {
- renderer.setLocalMatrix(mMatrix);
- }
-
- virtual void output(int level, uint32_t logFlags) const override {
- OP_LOG("SetLocalMatrix " SK_MATRIX_STRING, SK_MATRIX_ARGS(&mMatrix));
- }
-
- virtual const char* name() override { return "SetLocalMatrix"; }
-
-private:
- const SkMatrix mMatrix;
-};
-
class ConcatMatrixOp : public StateOp {
public:
ConcatMatrixOp(const SkMatrix& matrix)
@@ -1541,23 +1524,21 @@
class DrawLayerOp : public DrawOp {
public:
- DrawLayerOp(Layer* layer, float x, float y)
- : DrawOp(nullptr), mLayer(layer), mX(x), mY(y) {}
+ DrawLayerOp(Layer* layer)
+ : DrawOp(nullptr), mLayer(layer) {}
virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override {
- renderer.drawLayer(mLayer, mX, mY);
+ renderer.drawLayer(mLayer);
}
virtual void output(int level, uint32_t logFlags) const override {
- OP_LOG("Draw Layer %p at %f %f", mLayer, mX, mY);
+ OP_LOG("Draw Layer %p", mLayer);
}
virtual const char* name() override { return "DrawLayer"; }
private:
Layer* mLayer;
- float mX;
- float mY;
};
}; // namespace uirenderer
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index 057c231..75c3ead 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -26,14 +26,12 @@
#include "Rect.h"
#include "renderstate/RenderState.h"
#include "utils/Blur.h"
-#include "utils/MathUtils.h"
#include "utils/Timing.h"
+#include <algorithm>
+#include <cutils/properties.h>
#include <SkGlyph.h>
#include <SkUtils.h>
-
-#include <cutils/properties.h>
-
#include <utils/Log.h>
#ifdef ANDROID_ENABLE_RENDERSCRIPT
@@ -118,10 +116,10 @@
uint32_t maxTextureSize = (uint32_t) Caches::getInstance().maxTextureSize;
- mSmallCacheWidth = MathUtils::min(mSmallCacheWidth, maxTextureSize);
- mSmallCacheHeight = MathUtils::min(mSmallCacheHeight, maxTextureSize);
- mLargeCacheWidth = MathUtils::min(mLargeCacheWidth, maxTextureSize);
- mLargeCacheHeight = MathUtils::min(mLargeCacheHeight, maxTextureSize);
+ mSmallCacheWidth = std::min(mSmallCacheWidth, maxTextureSize);
+ mSmallCacheHeight = std::min(mSmallCacheHeight, maxTextureSize);
+ mLargeCacheWidth = std::min(mLargeCacheWidth, maxTextureSize);
+ mLargeCacheHeight = std::min(mLargeCacheHeight, maxTextureSize);
if (sLogFontRendererCreate) {
INIT_LOGD(" Text cache sizes, in pixels: %i x %i, %i x %i, %i x %i, %i x %i",
diff --git a/libs/hwui/GlopBuilder.cpp b/libs/hwui/GlopBuilder.cpp
index 288fed3..e27b26b 100644
--- a/libs/hwui/GlopBuilder.cpp
+++ b/libs/hwui/GlopBuilder.cpp
@@ -274,7 +274,7 @@
SkXfermode::Mode mode;
SkScalar srcColorMatrix[20];
if (colorFilter->asColorMode(&color, &mode)) {
- mOutGlop->fill.filterMode = mDescription.colorOp = ProgramDescription::kColorBlend;
+ mOutGlop->fill.filterMode = mDescription.colorOp = ProgramDescription::ColorFilterMode::Blend;
mDescription.colorMode = mode;
const float alpha = SkColorGetA(color) / 255.0f;
@@ -286,7 +286,7 @@
alpha,
};
} else if (colorFilter->asColorMatrix(srcColorMatrix)) {
- mOutGlop->fill.filterMode = mDescription.colorOp = ProgramDescription::kColorMatrix;
+ mOutGlop->fill.filterMode = mDescription.colorOp = ProgramDescription::ColorFilterMode::Matrix;
float* colorMatrix = mOutGlop->fill.filter.matrix.matrix;
memcpy(colorMatrix, srcColorMatrix, 4 * sizeof(float));
@@ -305,7 +305,7 @@
LOG_ALWAYS_FATAL("unsupported ColorFilter");
}
} else {
- mOutGlop->fill.filterMode = ProgramDescription::kColorNone;
+ mOutGlop->fill.filterMode = ProgramDescription::ColorFilterMode::None;
}
}
@@ -467,8 +467,8 @@
const int transformFlags) {
TRIGGER_STAGE(kTransformStage);
- mOutGlop->transform.ortho.load(ortho);
- mOutGlop->transform.canvas.load(canvas);
+ mOutGlop->transform.ortho = ortho;
+ mOutGlop->transform.canvas = canvas;
mOutGlop->transform.transformFlags = transformFlags;
}
@@ -615,7 +615,7 @@
shaderMatrix.loadInverse(mOutGlop->transform.canvas);
shaderMatrix.multiply(mOutGlop->transform.modelView);
} else {
- shaderMatrix.load(mOutGlop->transform.modelView);
+ shaderMatrix = mOutGlop->transform.modelView;
}
SkiaShader::store(mCaches, *mShader, shaderMatrix,
&textureUnit, &mDescription, &(mOutGlop->fill.skiaShaderData));
diff --git a/libs/hwui/Interpolator.cpp b/libs/hwui/Interpolator.cpp
index e1b0fc3..cc47f00 100644
--- a/libs/hwui/Interpolator.cpp
+++ b/libs/hwui/Interpolator.cpp
@@ -16,11 +16,11 @@
#include "Interpolator.h"
-#include <cmath>
-#include <cutils/log.h>
-
#include "utils/MathUtils.h"
+#include <algorithm>
+#include <cutils/log.h>
+
namespace android {
namespace uirenderer {
@@ -106,7 +106,7 @@
weight = modff(lutpos, &ipart);
int i1 = (int) ipart;
- int i2 = MathUtils::min(i1 + 1, (int) mSize - 1);
+ int i2 = std::min(i1 + 1, (int) mSize - 1);
LOG_ALWAYS_FATAL_IF(i1 < 0 || i2 < 0, "negatives in interpolation!"
" i1=%d, i2=%d, input=%f, lutpos=%f, size=%zu, values=%p, ipart=%f, weight=%f",
diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp
index 928f91b..e748221 100644
--- a/libs/hwui/Layer.cpp
+++ b/libs/hwui/Layer.cpp
@@ -36,7 +36,7 @@
namespace uirenderer {
Layer::Layer(Type layerType, RenderState& renderState, uint32_t layerWidth, uint32_t layerHeight)
- : state(kState_Uncached)
+ : state(State::Uncached)
, caches(Caches::getInstance())
, renderState(renderState)
, texture(caches)
diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h
index b670870..e90f055 100644
--- a/libs/hwui/Layer.h
+++ b/libs/hwui/Layer.h
@@ -56,19 +56,19 @@
*/
class Layer : public VirtualLightRefBase {
public:
- enum Type {
- kType_Texture,
- kType_DisplayList,
+ enum class Type {
+ Texture,
+ DisplayList,
};
// layer lifecycle, controlled from outside
- enum State {
- kState_Uncached = 0,
- kState_InCache = 1,
- kState_FailedToCache = 2,
- kState_RemovedFromCache = 3,
- kState_DeletedFromCache = 4,
- kState_InGarbageList = 5,
+ enum class State {
+ Uncached = 0,
+ InCache = 1,
+ FailedToCache = 2,
+ RemovedFromCache = 3,
+ DeletedFromCache = 4,
+ InGarbageList = 5,
};
State state; // public for logging/debugging purposes
@@ -241,7 +241,7 @@
}
inline bool isTextureLayer() const {
- return type == kType_Texture;
+ return type == Type::Texture;
}
inline SkColorFilter* getColorFilter() const {
diff --git a/libs/hwui/LayerCache.cpp b/libs/hwui/LayerCache.cpp
index 33f40b0..39cadd1 100644
--- a/libs/hwui/LayerCache.cpp
+++ b/libs/hwui/LayerCache.cpp
@@ -81,7 +81,7 @@
LAYER_LOGD("Destroying layer %dx%d, fbo %d", layer->getWidth(), layer->getHeight(),
layer->getFbo());
mSize -= layer->getWidth() * layer->getHeight() * 4;
- layer->state = Layer::kState_DeletedFromCache;
+ layer->state = Layer::State::DeletedFromCache;
layer->decStrong(nullptr);
}
}
@@ -104,14 +104,14 @@
mCache.erase(iter);
layer = entry.mLayer;
- layer->state = Layer::kState_RemovedFromCache;
+ layer->state = Layer::State::RemovedFromCache;
mSize -= layer->getWidth() * layer->getHeight() * 4;
LAYER_LOGD("Reusing layer %dx%d", layer->getWidth(), layer->getHeight());
} else {
LAYER_LOGD("Creating new layer %dx%d", entry.mWidth, entry.mHeight);
- layer = new Layer(Layer::kType_DisplayList, renderState, entry.mWidth, entry.mHeight);
+ layer = new Layer(Layer::Type::DisplayList, renderState, entry.mWidth, entry.mHeight);
layer->setBlend(true);
layer->generateTexture();
layer->bindTexture();
@@ -156,11 +156,11 @@
mCache.insert(entry);
mSize += size;
- layer->state = Layer::kState_InCache;
+ layer->state = Layer::State::InCache;
return true;
}
- layer->state = Layer::kState_FailedToCache;
+ layer->state = Layer::State::FailedToCache;
return false;
}
diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp
index 00add29..d8e6392 100644
--- a/libs/hwui/LayerRenderer.cpp
+++ b/libs/hwui/LayerRenderer.cpp
@@ -272,7 +272,7 @@
Layer* LayerRenderer::createTextureLayer(RenderState& renderState) {
LAYER_RENDERER_LOGD("Creating new texture layer");
- Layer* layer = new Layer(Layer::kType_Texture, renderState, 0, 0);
+ Layer* layer = new Layer(Layer::Type::Texture, renderState, 0, 0);
layer->setCacheable(false);
layer->layer.set(0.0f, 0.0f, 0.0f, 0.0f);
layer->texCoords.set(0.0f, 1.0f, 1.0f, 0.0f);
diff --git a/libs/hwui/Matrix.cpp b/libs/hwui/Matrix.cpp
index 115e23c..73ebd1304 100644
--- a/libs/hwui/Matrix.cpp
+++ b/libs/hwui/Matrix.cpp
@@ -152,10 +152,6 @@
mType = kTypeUnknown;
}
-void Matrix4::load(const Matrix4& v) {
- *this = v;
-}
-
void Matrix4::load(const SkMatrix& v) {
memset(data, 0, sizeof(data));
diff --git a/libs/hwui/Matrix.h b/libs/hwui/Matrix.h
index ed54a25..ed517ac 100644
--- a/libs/hwui/Matrix.h
+++ b/libs/hwui/Matrix.h
@@ -114,7 +114,6 @@
void loadIdentity();
void load(const float* v);
- void load(const Matrix4& v);
void load(const SkMatrix& v);
void loadInverse(const Matrix4& v);
@@ -139,7 +138,7 @@
void multiply(const Matrix4& v) {
Matrix4 u;
u.loadMultiply(*this, v);
- load(u);
+ *this = u;
}
void multiply(float v);
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 7a56d42..5692d7e 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -1141,7 +1141,7 @@
// Transform and alpha always deferred, since they are used by state operations
// (Note: saveLayer/restore use colorFilter and alpha, so we just save restore everything)
- state.mMatrix.load(*currentMatrix);
+ state.mMatrix = *currentMatrix;
state.mAlpha = currentSnapshot()->alpha;
// always store/restore, since these are just pointers
@@ -1151,7 +1151,7 @@
}
void OpenGLRenderer::restoreDisplayState(const DeferredDisplayState& state, bool skipClipRestore) {
- setMatrix(state.mMatrix);
+ setGlobalMatrix(state.mMatrix);
writableSnapshot()->alpha = state.mAlpha;
writableSnapshot()->roundRectClipState = state.mRoundRectClipState;
writableSnapshot()->projectionPathMask = state.mProjectionPathMask;
@@ -2098,8 +2098,9 @@
mState.skew(sx, sy);
}
-void OpenGLRenderer::setMatrix(const Matrix4& matrix) {
- mState.setMatrix(matrix);
+void OpenGLRenderer::setLocalMatrix(const Matrix4& matrix) {
+ mState.setMatrix(mBaseTransform);
+ mState.concatMatrix(matrix);
}
void OpenGLRenderer::setLocalMatrix(const SkMatrix& matrix) {
@@ -2267,7 +2268,7 @@
mDirty = true;
}
-void OpenGLRenderer::drawLayer(Layer* layer, float x, float y) {
+void OpenGLRenderer::drawLayer(Layer* layer) {
if (!layer) {
return;
}
@@ -2283,7 +2284,7 @@
bool clipRequired = false;
const bool rejected = mState.calculateQuickRejectForScissor(
- x, y, x + layer->layer.getWidth(), y + layer->layer.getHeight(),
+ 0, 0, layer->layer.getWidth(), layer->layer.getHeight(),
&clipRequired, nullptr, false);
if (rejected) {
@@ -2312,7 +2313,7 @@
.setMeshTexturedIndexedQuads(layer->mesh, layer->meshElementCount)
.setFillLayer(layer->getTexture(), layer->getColorFilter(), getLayerAlpha(layer), layer->getMode(), Blend::ModeOrderSwap::NoSwap)
.setTransform(*currentSnapshot(), TransformFlags::None)
- .setModelViewOffsetRectSnap(x, y, Rect(0, 0, layer->layer.getWidth(), layer->layer.getHeight()))
+ .setModelViewOffsetRectSnap(0, 0, Rect(0, 0, layer->layer.getWidth(), layer->layer.getHeight()))
.build();
DRAW_DOUBLE_STENCIL_IF(!layer->hasDrawnSinceUpdate, renderGlop(glop));
#if DEBUG_LAYERS_AS_REGIONS
@@ -2325,7 +2326,7 @@
SkPaint paint;
paint.setColor(0x7f00ff00);
- drawColorRect(x, y, x + layer->layer.getWidth(), y + layer->layer.getHeight(), &paint);
+ drawColorRect(0, 0, layer->layer.getWidth(), layer->layer.getHeight(), &paint);
}
}
layer->hasDrawnSinceUpdate = true;
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 4f75482..af85e8c 100755
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -35,6 +35,7 @@
#include <SkBitmap.h>
#include <SkCanvas.h>
#include <SkColorFilter.h>
+#include <SkDrawLooper.h>
#include <SkMatrix.h>
#include <SkPaint.h>
#include <SkRegion.h>
@@ -187,7 +188,7 @@
const SkPaint* paint, int flags);
void drawRenderNode(RenderNode* displayList, Rect& dirty, int32_t replayFlags = 1);
- void drawLayer(Layer* layer, float x, float y);
+ void drawLayer(Layer* layer);
void drawBitmap(const SkBitmap* bitmap, const SkPaint* paint);
void drawBitmaps(const SkBitmap* bitmap, AssetAtlas::Entry* entry, int bitmapCount,
TextureVertex* vertices, bool pureTranslate, const Rect& bounds, const SkPaint* paint);
@@ -367,8 +368,10 @@
void restore();
void restoreToCount(int saveCount);
- void getMatrix(SkMatrix* outMatrix) const { mState.getMatrix(outMatrix); }
- void setMatrix(const SkMatrix& matrix) { mState.setMatrix(matrix); }
+ void setGlobalMatrix(const Matrix4& matrix) {
+ mState.setMatrix(matrix);
+ }
+ void setLocalMatrix(const Matrix4& matrix);
void setLocalMatrix(const SkMatrix& matrix);
void concatMatrix(const SkMatrix& matrix) { mState.concatMatrix(matrix); }
diff --git a/libs/hwui/Outline.h b/libs/hwui/Outline.h
index 8d4d4f0..4bd4ae1 100644
--- a/libs/hwui/Outline.h
+++ b/libs/hwui/Outline.h
@@ -28,13 +28,13 @@
public:
Outline()
: mShouldClip(false)
- , mType(kOutlineType_None)
+ , mType(Type::None)
, mRadius(0)
, mAlpha(0.0f) {}
void setRoundRect(int left, int top, int right, int bottom, float radius, float alpha) {
mAlpha = alpha;
- if (mType == kOutlineType_RoundRect
+ if (mType == Type::RoundRect
&& left == mBounds.left
&& right == mBounds.right
&& top == mBounds.top
@@ -44,7 +44,7 @@
return;
}
- mType = kOutlineType_RoundRect;
+ mType = Type::RoundRect;
mBounds.set(left, top, right, bottom);
mRadius = radius;
@@ -63,26 +63,26 @@
setEmpty();
return;
}
- mType = kOutlineType_ConvexPath;
+ mType = Type::ConvexPath;
mPath = *outline;
mBounds.set(outline->getBounds());
mAlpha = alpha;
}
void setEmpty() {
- mType = kOutlineType_Empty;
+ mType = Type::Empty;
mPath.reset();
mAlpha = 0.0f;
}
void setNone() {
- mType = kOutlineType_None;
+ mType = Type::None;
mPath.reset();
mAlpha = 0.0f;
}
bool isEmpty() const {
- return mType == kOutlineType_Empty;
+ return mType == Type::Empty;
}
float getAlpha() const {
@@ -99,7 +99,7 @@
bool willClip() const {
// only round rect outlines can be used for clipping
- return mShouldClip && (mType == kOutlineType_RoundRect);
+ return mShouldClip && (mType == Type::RoundRect);
}
bool willRoundRectClip() const {
@@ -108,7 +108,7 @@
}
bool getAsRoundRect(Rect* outRect, float* outRadius) const {
- if (mType == kOutlineType_RoundRect) {
+ if (mType == Type::RoundRect) {
outRect->set(mBounds);
*outRadius = mRadius;
return true;
@@ -117,21 +117,21 @@
}
const SkPath* getPath() const {
- if (mType == kOutlineType_None || mType == kOutlineType_Empty) return nullptr;
+ if (mType == Type::None || mType == Type::Empty) return nullptr;
return &mPath;
}
private:
- enum OutlineType {
- kOutlineType_None = 0,
- kOutlineType_Empty = 1,
- kOutlineType_ConvexPath = 2,
- kOutlineType_RoundRect = 3
+ enum class Type {
+ None = 0,
+ Empty = 1,
+ ConvexPath = 2,
+ RoundRect = 3
};
bool mShouldClip;
- OutlineType mType;
+ Type mType;
Rect mBounds;
float mRadius;
float mAlpha;
diff --git a/libs/hwui/Patch.cpp b/libs/hwui/Patch.cpp
index 500f9e9..b471e78 100644
--- a/libs/hwui/Patch.cpp
+++ b/libs/hwui/Patch.cpp
@@ -14,16 +14,16 @@
* limitations under the License.
*/
-#include <cmath>
-
-#include <utils/Log.h>
+#include "Patch.h"
#include "Caches.h"
-#include "Patch.h"
#include "Properties.h"
#include "UvMapper.h"
#include "utils/MathUtils.h"
+#include <algorithm>
+#include <utils/Log.h>
+
namespace android {
namespace uirenderer {
@@ -189,10 +189,10 @@
const uint32_t oldQuadCount = quadCount;
quadCount++;
- x1 = MathUtils::max(x1, 0.0f);
- x2 = MathUtils::max(x2, 0.0f);
- y1 = MathUtils::max(y1, 0.0f);
- y2 = MathUtils::max(y2, 0.0f);
+ x1 = std::max(x1, 0.0f);
+ x2 = std::max(x2, 0.0f);
+ y1 = std::max(y1, 0.0f);
+ y2 = std::max(y2, 0.0f);
// Skip degenerate and transparent (empty) quads
if ((mColors[oldQuadCount] == 0) || x1 >= x2 || y1 >= y2) {
diff --git a/libs/hwui/PathTessellator.cpp b/libs/hwui/PathTessellator.cpp
index 8fa187c..b57b8f0 100644
--- a/libs/hwui/PathTessellator.cpp
+++ b/libs/hwui/PathTessellator.cpp
@@ -32,6 +32,15 @@
#define DEBUG_DUMP_BUFFER()
#endif
+#include "PathTessellator.h"
+
+#include "Matrix.h"
+#include "Vector.h"
+#include "Vertex.h"
+#include "utils/MathUtils.h"
+
+#include <algorithm>
+
#include <SkPath.h>
#include <SkPaint.h>
#include <SkPoint.h>
@@ -44,12 +53,6 @@
#include <utils/Log.h>
#include <utils/Trace.h>
-#include "PathTessellator.h"
-#include "Matrix.h"
-#include "Vector.h"
-#include "Vertex.h"
-#include "utils/MathUtils.h"
-
namespace android {
namespace uirenderer {
@@ -152,7 +155,7 @@
// always use 2 points for hairline
if (halfStrokeWidth == 0.0f) return 2;
- float threshold = MathUtils::min(inverseScaleX, inverseScaleY) * ROUND_CAP_THRESH;
+ float threshold = std::min(inverseScaleX, inverseScaleY) * ROUND_CAP_THRESH;
return MathUtils::divisionsNeededToApproximateArc(halfStrokeWidth, PI, threshold);
}
return 0;
diff --git a/libs/hwui/PathTessellator.h b/libs/hwui/PathTessellator.h
index b66e832..cddfb04 100644
--- a/libs/hwui/PathTessellator.h
+++ b/libs/hwui/PathTessellator.h
@@ -22,8 +22,12 @@
#include "Vertex.h"
#include "VertexBuffer.h"
+#include <algorithm>
#include <vector>
+class SkPath;
+class SkPaint;
+
namespace android {
namespace uirenderer {
@@ -38,7 +42,7 @@
: thresholdSquared(pixelThreshold * pixelThreshold)
, sqrInvScaleX(invScaleX * invScaleX)
, sqrInvScaleY(invScaleY * invScaleY)
- , thresholdForConicQuads(pixelThreshold * MathUtils::min(invScaleX, invScaleY) / 2.0f) {
+ , thresholdForConicQuads(pixelThreshold * std::min(invScaleX, invScaleY) / 2.0f) {
};
const float thresholdSquared;
diff --git a/libs/hwui/Program.h b/libs/hwui/Program.h
index af1e4a7..b09c207 100644
--- a/libs/hwui/Program.h
+++ b/libs/hwui/Program.h
@@ -103,10 +103,10 @@
* A ProgramDescription must be used in conjunction with a ProgramCache.
*/
struct ProgramDescription {
- enum ColorFilterMode {
- kColorNone = 0,
- kColorMatrix,
- kColorBlend
+ enum class ColorFilterMode {
+ None = 0,
+ Matrix,
+ Blend
};
enum Gradient {
@@ -193,7 +193,7 @@
bitmapWrapS = GL_CLAMP_TO_EDGE;
bitmapWrapT = GL_CLAMP_TO_EDGE;
- colorOp = kColorNone;
+ colorOp = ColorFilterMode::None;
colorMode = SkXfermode::kClear_Mode;
framebufferMode = SkXfermode::kClear_Mode;
@@ -249,14 +249,14 @@
key |= (shadersMode & PROGRAM_MAX_XFERMODE) << PROGRAM_XFERMODE_SHADER_SHIFT;
}
switch (colorOp) {
- case kColorMatrix:
+ case ColorFilterMode::Matrix:
key |= PROGRAM_KEY_COLOR_MATRIX;
break;
- case kColorBlend:
+ case ColorFilterMode::Blend:
key |= PROGRAM_KEY_COLOR_BLEND;
key |= (colorMode & PROGRAM_MAX_XFERMODE) << PROGRAM_XFERMODE_COLOR_OP_SHIFT;
break;
- case kColorNone:
+ case ColorFilterMode::None:
break;
}
key |= (framebufferMode & PROGRAM_MAX_XFERMODE) << PROGRAM_XFERMODE_FRAMEBUFFER_SHIFT;
diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp
index 7f16deb..b25a4ac 100644
--- a/libs/hwui/ProgramCache.cpp
+++ b/libs/hwui/ProgramCache.cpp
@@ -38,7 +38,8 @@
// Vertex shaders snippets
///////////////////////////////////////////////////////////////////////////////
-const char* gVS_Header_Attributes =
+const char* gVS_Header_Start =
+ "#version 100\n"
"attribute vec4 position;\n";
const char* gVS_Header_Attributes_TexCoords =
"attribute vec2 texCoords;\n";
@@ -132,6 +133,8 @@
// Fragment shaders snippets
///////////////////////////////////////////////////////////////////////////////
+const char* gFS_Header_Start =
+ "#version 100\n";
const char* gFS_Header_Extension_FramebufferFetch =
"#extension GL_NV_shader_framebuffer_fetch : enable\n\n";
const char* gFS_Header_Extension_ExternalTexture =
@@ -457,7 +460,7 @@
String8 ProgramCache::generateVertexShader(const ProgramDescription& description) {
// Add attributes
- String8 shader(gVS_Header_Attributes);
+ String8 shader(gVS_Header_Start);
if (description.hasTexture || description.hasExternalTexture) {
shader.append(gVS_Header_Attributes_TexCoords);
}
@@ -543,7 +546,7 @@
}
String8 ProgramCache::generateFragmentShader(const ProgramDescription& description) {
- String8 shader;
+ String8 shader(gFS_Header_Start);
const bool blendFramebuffer = description.framebufferMode >= SkXfermode::kPlus_Mode;
if (blendFramebuffer) {
@@ -604,7 +607,7 @@
if (!description.hasVertexAlpha
&& !blendFramebuffer
&& !description.hasColors
- && description.colorOp == ProgramDescription::kColorNone
+ && description.colorOp == ProgramDescription::ColorFilterMode::None
&& !description.hasDebugHighlight
&& !description.hasRoundRectClip) {
bool fast = false;
@@ -668,13 +671,13 @@
if (description.hasBitmap) {
shader.append(gFS_Uniforms_BitmapSampler);
}
- shader.append(gFS_Uniforms_ColorOp[description.colorOp]);
+ shader.append(gFS_Uniforms_ColorOp[static_cast<int>(description.colorOp)]);
// Generate required functions
if (description.hasGradient && description.hasBitmap) {
generateBlend(shader, "blendShaders", description.shadersMode);
}
- if (description.colorOp == ProgramDescription::kColorBlend) {
+ if (description.colorOp == ProgramDescription::ColorFilterMode::Blend) {
generateBlend(shader, "blendColors", description.colorMode);
}
if (blendFramebuffer) {
@@ -737,7 +740,7 @@
}
// Apply the color op if needed
- shader.append(gFS_Main_ApplyColorOp[description.colorOp]);
+ shader.append(gFS_Main_ApplyColorOp[static_cast<int>(description.colorOp)]);
if (description.hasVertexAlpha) {
if (description.useShadowAlphaInterp) {
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index 48da3e8..7d09c0b 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -532,7 +532,7 @@
if (properties().getProjectBackwards()) {
// composited projectee, flag for out of order draw, save matrix, and store in proj surface
opState->mSkipInOrderDraw = true;
- opState->mTransformFromCompositingAncestor.load(localTransformFromProjectionSurface);
+ opState->mTransformFromCompositingAncestor = localTransformFromProjectionSurface;
compositedChildrenOfProjectionSurface->push_back(opState);
} else {
// standard in order draw
@@ -710,8 +710,8 @@
OpenGLRenderer& renderer, T& handler) {
const int size = zTranslatedNodes.size();
if (size == 0
- || (mode == kNegativeZChildren && zTranslatedNodes[0].key > 0.0f)
- || (mode == kPositiveZChildren && zTranslatedNodes[size - 1].key < 0.0f)) {
+ || (mode == ChildrenSelectMode::NegativeZChildren && zTranslatedNodes[0].key > 0.0f)
+ || (mode == ChildrenSelectMode::PositiveZChildren && zTranslatedNodes[size - 1].key < 0.0f)) {
// no 3d children to draw
return;
}
@@ -719,7 +719,7 @@
// Apply the base transform of the parent of the 3d children. This isolates
// 3d children of the current chunk from transformations made in previous chunks.
int rootRestoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag);
- renderer.setMatrix(initialTransform);
+ renderer.setGlobalMatrix(initialTransform);
/**
* Draw shadows and (potential) casters mostly in order, but allow the shadows of casters
@@ -730,7 +730,7 @@
*/
const size_t nonNegativeIndex = findNonNegativeIndex(zTranslatedNodes);
size_t drawIndex, shadowIndex, endIndex;
- if (mode == kNegativeZChildren) {
+ if (mode == ChildrenSelectMode::NegativeZChildren) {
drawIndex = 0;
endIndex = nonNegativeIndex;
shadowIndex = endIndex; // draw no shadows
@@ -875,7 +875,7 @@
renderer.setBaseTransform(initialTransform);
if (drawLayer) {
- handler(new (alloc) DrawLayerOp(mLayer, 0, 0),
+ handler(new (alloc) DrawLayerOp(mLayer),
renderer.getSaveCount() - 1, properties().getClipToBounds());
} else {
const int saveCountOffset = renderer.getSaveCount() - 1;
@@ -886,7 +886,7 @@
std::vector<ZDrawRenderNodeOpPair> zTranslatedNodes;
buildZSortedChildList(chunk, zTranslatedNodes);
- issueOperationsOf3dChildren(kNegativeZChildren,
+ issueOperationsOf3dChildren(ChildrenSelectMode::NegativeZChildren,
initialTransform, zTranslatedNodes, renderer, handler);
@@ -903,7 +903,7 @@
}
}
- issueOperationsOf3dChildren(kPositiveZChildren,
+ issueOperationsOf3dChildren(ChildrenSelectMode::PositiveZChildren,
initialTransform, zTranslatedNodes, renderer, handler);
}
}
diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h
index 6d1a2b7..3bff2b3 100644
--- a/libs/hwui/RenderNode.h
+++ b/libs/hwui/RenderNode.h
@@ -184,9 +184,9 @@
return nodes.size();
}
- enum ChildrenSelectMode {
- kNegativeZChildren,
- kPositiveZChildren
+ enum class ChildrenSelectMode {
+ NegativeZChildren,
+ PositiveZChildren
};
void computeOrderingImpl(DrawRenderNodeOp* opState,
diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp
index c122d99..36633b5 100644
--- a/libs/hwui/SkiaCanvas.cpp
+++ b/libs/hwui/SkiaCanvas.cpp
@@ -74,7 +74,6 @@
virtual void getMatrix(SkMatrix* outMatrix) const override;
virtual void setMatrix(const SkMatrix& matrix) override;
- virtual void setLocalMatrix(const SkMatrix& matrix) override { this->setMatrix(matrix); }
virtual void concat(const SkMatrix& matrix) override;
virtual void rotate(float degrees) override;
virtual void scale(float sx, float sy) override;
@@ -702,7 +701,7 @@
SkPaint paintCopy(paint);
paintCopy.setTextAlign(SkPaint::kLeft_Align);
- SK_COMPILE_ASSERT(sizeof(SkPoint) == sizeof(float)*2, SkPoint_is_no_longer_2_floats);
+ static_assert(sizeof(SkPoint) == sizeof(float)*2, "SkPoint is no longer two floats");
mCanvas->drawPosText(text, count << 1, reinterpret_cast<const SkPoint*>(positions), paintCopy);
}
diff --git a/libs/hwui/SkiaCanvasProxy.cpp b/libs/hwui/SkiaCanvasProxy.cpp
index 5e6d774..c3f5eb2 100644
--- a/libs/hwui/SkiaCanvasProxy.cpp
+++ b/libs/hwui/SkiaCanvasProxy.cpp
@@ -45,7 +45,7 @@
}
// convert the SkPoints into floats
- SK_COMPILE_ASSERT(sizeof(SkPoint) == sizeof(float)*2, SkPoint_is_no_longer_2_floats);
+ static_assert(sizeof(SkPoint) == sizeof(float)*2, "SkPoint is no longer two floats");
const size_t floatCount = count << 1;
const float* floatArray = &pts[0].fX;
@@ -142,7 +142,7 @@
const SkPaint* paint) {
// TODO: if bitmap is a subset, do we need to add pixelRefOrigin to src?
mCanvas->save(SkCanvas::kMatrixClip_SaveFlag);
- mCanvas->setLocalMatrix(SkMatrix::I());
+ mCanvas->setMatrix(SkMatrix::I());
mCanvas->drawBitmap(bitmap, left, top, paint);
mCanvas->restore();
}
@@ -154,7 +154,7 @@
return;
}
// convert the SkPoints into floats
- SK_COMPILE_ASSERT(sizeof(SkPoint) == sizeof(float)*2, SkPoint_is_no_longer_2_floats);
+ static_assert(sizeof(SkPoint) == sizeof(float)*2, "SkPoint is no longer two floats");
const int floatCount = vertexCount << 1;
const float* vArray = &vertices[0].fX;
const float* tArray = (texs) ? &texs[0].fX : NULL;
@@ -192,9 +192,7 @@
}
void SkiaCanvasProxy::didSetMatrix(const SkMatrix& matrix) {
- // SkCanvas setMatrix() is relative to the Canvas origin, but OpenGLRenderer's
- // setMatrix() is relative to device origin; call setLocalMatrix() instead.
- mCanvas->setLocalMatrix(matrix);
+ mCanvas->setMatrix(matrix);
}
void SkiaCanvasProxy::onDrawDRRect(const SkRRect& outer, const SkRRect& inner,
@@ -286,7 +284,7 @@
}
}
- SK_COMPILE_ASSERT(sizeof(SkPoint) == sizeof(float)*2, SkPoint_is_no_longer_2_floats);
+ static_assert(sizeof(SkPoint) == sizeof(float)*2, "SkPoint is no longer two floats");
mCanvas->drawText(glyphs.glyphIDs, &pointStorage[0].fX, glyphs.count, glyphs.paint,
x, y, bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, 0);
}
@@ -322,7 +320,7 @@
glyphs.paint.measureText(glyphs.glyphIDs, glyphs.count << 1, &bounds);
bounds.offset(x, y);
- SK_COMPILE_ASSERT(sizeof(SkPoint) == sizeof(float)*2, SkPoint_is_no_longer_2_floats);
+ static_assert(sizeof(SkPoint) == sizeof(float)*2, "SkPoint is no longer two floats");
mCanvas->drawText(glyphs.glyphIDs, &posArray[0].fX, glyphs.count, glyphs.paint, x, y,
bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, 0);
}
diff --git a/libs/hwui/SkiaShader.cpp b/libs/hwui/SkiaShader.cpp
index 1f95946..6c105cf 100644
--- a/libs/hwui/SkiaShader.cpp
+++ b/libs/hwui/SkiaShader.cpp
@@ -32,12 +32,19 @@
// Support
///////////////////////////////////////////////////////////////////////////////
-static const GLenum gTileModes[] = {
+static constexpr GLenum gTileModes[] = {
GL_CLAMP_TO_EDGE, // == SkShader::kClamp_TileMode
GL_REPEAT, // == SkShader::kRepeat_Mode
GL_MIRRORED_REPEAT // == SkShader::kMirror_TileMode
};
+static_assert(gTileModes[SkShader::kClamp_TileMode] == GL_CLAMP_TO_EDGE,
+ "SkShader TileModes have changed");
+static_assert(gTileModes[SkShader::kRepeat_TileMode] == GL_REPEAT,
+ "SkShader TileModes have changed");
+static_assert(gTileModes[SkShader::kMirror_TileMode] == GL_MIRRORED_REPEAT,
+ "SkShader TileModes have changed");
+
/**
* This function does not work for n == 0.
*/
diff --git a/libs/hwui/Snapshot.cpp b/libs/hwui/Snapshot.cpp
index fd077d9..4d60b8d 100644
--- a/libs/hwui/Snapshot.cpp
+++ b/libs/hwui/Snapshot.cpp
@@ -58,7 +58,7 @@
, mViewportData(s->mViewportData)
, mRelativeLightCenter(s->mRelativeLightCenter) {
if (saveFlags & SkCanvas::kMatrix_SaveFlag) {
- mTransformRoot.load(*s->transform);
+ mTransformRoot = *s->transform;
transform = &mTransformRoot;
} else {
transform = s->transform;
@@ -83,24 +83,24 @@
// Clipping
///////////////////////////////////////////////////////////////////////////////
-bool Snapshot::clipRegionTransformed(const SkRegion& region, SkRegion::Op op) {
+void Snapshot::clipRegionTransformed(const SkRegion& region, SkRegion::Op op) {
flags |= Snapshot::kFlagClipSet;
- return mClipArea->clipRegion(region, op);
+ mClipArea->clipRegion(region, op);
}
-bool Snapshot::clip(float left, float top, float right, float bottom, SkRegion::Op op) {
+void Snapshot::clip(float left, float top, float right, float bottom, SkRegion::Op op) {
flags |= Snapshot::kFlagClipSet;
- return mClipArea->clipRectWithTransform(left, top, right, bottom, transform, op);
+ mClipArea->clipRectWithTransform(left, top, right, bottom, transform, op);
}
-bool Snapshot::clipPath(const SkPath& path, SkRegion::Op op) {
+void Snapshot::clipPath(const SkPath& path, SkRegion::Op op) {
flags |= Snapshot::kFlagClipSet;
- return mClipArea->clipPathWithTransform(path, transform, op);
+ mClipArea->clipPathWithTransform(path, transform, op);
}
void Snapshot::setClip(float left, float top, float right, float bottom) {
- mClipArea->setClip(left, top, right, bottom);
flags |= Snapshot::kFlagClipSet;
+ mClipArea->setClip(left, top, right, bottom);
}
bool Snapshot::hasPerspectiveTransform() const {
@@ -190,8 +190,7 @@
state->highPriority = highPriority;
// store the inverse drawing matrix
- Matrix4 roundRectDrawingMatrix;
- roundRectDrawingMatrix.load(getOrthoMatrix());
+ Matrix4 roundRectDrawingMatrix = getOrthoMatrix();
roundRectDrawingMatrix.multiply(*transform);
state->matrix.loadInverse(roundRectDrawingMatrix);
diff --git a/libs/hwui/Snapshot.h b/libs/hwui/Snapshot.h
index af6ad72..cf8f11c 100644
--- a/libs/hwui/Snapshot.h
+++ b/libs/hwui/Snapshot.h
@@ -124,26 +124,25 @@
* the specified operation. The specified rectangle is transformed
* by this snapshot's trasnformation.
*/
- bool clip(float left, float top, float right, float bottom,
- SkRegion::Op op = SkRegion::kIntersect_Op);
+ void clip(float left, float top, float right, float bottom, SkRegion::Op op);
/**
* Modifies the current clip with the new clip rectangle and
* the specified operation. The specified rectangle is considered
* already transformed.
*/
- bool clipTransformed(const Rect& r, SkRegion::Op op = SkRegion::kIntersect_Op);
+ void clipTransformed(const Rect& r, SkRegion::Op op = SkRegion::kIntersect_Op);
/**
* Modifies the current clip with the specified region and operation.
* The specified region is considered already transformed.
*/
- bool clipRegionTransformed(const SkRegion& region, SkRegion::Op op);
+ void clipRegionTransformed(const SkRegion& region, SkRegion::Op op);
/**
* Modifies the current clip with the specified path and operation.
*/
- bool clipPath(const SkPath& path, SkRegion::Op op);
+ void clipPath(const SkPath& path, SkRegion::Op op);
/**
* Sets the current clip.
diff --git a/libs/hwui/SpotShadow.cpp b/libs/hwui/SpotShadow.cpp
index eaf0303..9b0a1aa 100644
--- a/libs/hwui/SpotShadow.cpp
+++ b/libs/hwui/SpotShadow.cpp
@@ -46,17 +46,18 @@
#define TRANSFORMED_PENUMBRA_ALPHA 1.0f
#define TRANSFORMED_UMBRA_ALPHA 0.0f
+#include "SpotShadow.h"
+
+#include "ShadowTessellator.h"
+#include "Vertex.h"
+#include "VertexBuffer.h"
+#include "utils/MathUtils.h"
+
#include <algorithm>
#include <math.h>
#include <stdlib.h>
#include <utils/Log.h>
-#include "ShadowTessellator.h"
-#include "SpotShadow.h"
-#include "Vertex.h"
-#include "VertexBuffer.h"
-#include "utils/MathUtils.h"
-
// TODO: After we settle down the new algorithm, we can remove the old one and
// its utility functions.
// Right now, we still need to keep it for comparison purpose and future expansion.
@@ -543,7 +544,7 @@
}
float ratioVI = outlineData[i].radius / distOutline;
- minRaitoVI = MathUtils::min(minRaitoVI, ratioVI);
+ minRaitoVI = std::min(minRaitoVI, ratioVI);
if (ratioVI >= (1 - FAKE_UMBRA_SIZE_RATIO)) {
ratioVI = (1 - FAKE_UMBRA_SIZE_RATIO);
}
diff --git a/libs/hwui/VertexBuffer.h b/libs/hwui/VertexBuffer.h
index 9be4d84..c0373ac 100644
--- a/libs/hwui/VertexBuffer.h
+++ b/libs/hwui/VertexBuffer.h
@@ -17,7 +17,7 @@
#ifndef ANDROID_HWUI_VERTEX_BUFFER_H
#define ANDROID_HWUI_VERTEX_BUFFER_H
-#include "utils/MathUtils.h"
+#include <algorithm>
namespace android {
namespace uirenderer {
@@ -129,10 +129,10 @@
unsigned int getSize() const { return mByteCount; }
unsigned int getIndexCount() const { return mIndexCount; }
void updateIndexCount(unsigned int newCount) {
- mIndexCount = MathUtils::min(newCount, mAllocatedIndexCount);
+ mIndexCount = std::min(newCount, mAllocatedIndexCount);
}
void updateVertexCount(unsigned int newCount) {
- mVertexCount = MathUtils::min(newCount, mAllocatedVertexCount);
+ mVertexCount = std::min(newCount, mAllocatedVertexCount);
}
MeshFeatureFlags getMeshFeatureFlags() const { return mMeshFeatureFlags; }
void setMeshFeatureFlags(int flags) {
diff --git a/libs/hwui/renderstate/Blend.cpp b/libs/hwui/renderstate/Blend.cpp
index 29927ed..b21e15e 100644
--- a/libs/hwui/renderstate/Blend.cpp
+++ b/libs/hwui/renderstate/Blend.cpp
@@ -30,6 +30,26 @@
GLenum dst;
};
+// assumptions made by lookup tables in either this file or ProgramCache
+static_assert(0 == SkXfermode::kClear_Mode, "SkXfermode enums have changed");
+static_assert(1 == SkXfermode::kSrc_Mode, "SkXfermode enums have changed");
+static_assert(2 == SkXfermode::kDst_Mode, "SkXfermode enums have changed");
+static_assert(3 == SkXfermode::kSrcOver_Mode, "SkXfermode enums have changed");
+static_assert(4 == SkXfermode::kDstOver_Mode, "SkXfermode enums have changed");
+static_assert(5 == SkXfermode::kSrcIn_Mode, "SkXfermode enums have changed");
+static_assert(6 == SkXfermode::kDstIn_Mode, "SkXfermode enums have changed");
+static_assert(7 == SkXfermode::kSrcOut_Mode, "SkXfermode enums have changed");
+static_assert(8 == SkXfermode::kDstOut_Mode, "SkXfermode enums have changed");
+static_assert(9 == SkXfermode::kSrcATop_Mode, "SkXfermode enums have changed");
+static_assert(10 == SkXfermode::kDstATop_Mode, "SkXfermode enums have changed");
+static_assert(11 == SkXfermode::kXor_Mode, "SkXfermode enums have changed");
+static_assert(12 == SkXfermode::kPlus_Mode, "SkXfermode enums have changed");
+static_assert(13 == SkXfermode::kModulate_Mode, "SkXfermode enums have changed");
+static_assert(14 == SkXfermode::kScreen_Mode, "SkXfermode enums have changed");
+static_assert(15 == SkXfermode::kOverlay_Mode, "SkXfermode enums have changed");
+static_assert(16 == SkXfermode::kDarken_Mode, "SkXfermode enums have changed");
+static_assert(17 == SkXfermode::kLighten_Mode, "SkXfermode enums have changed");
+
// In this array, the index of each Blender equals the value of the first
// entry. For instance, gBlends[1] == gBlends[SkXfermode::kSrc_Mode]
const Blender kBlends[] = {
diff --git a/libs/hwui/renderstate/RenderState.cpp b/libs/hwui/renderstate/RenderState.cpp
index 1e39bfa..c5126de 100644
--- a/libs/hwui/renderstate/RenderState.cpp
+++ b/libs/hwui/renderstate/RenderState.cpp
@@ -19,6 +19,8 @@
#include "renderthread/EglManager.h"
#include "utils/GLUtils.h"
+#include <algorithm>
+
namespace android {
namespace uirenderer {
@@ -227,11 +229,11 @@
glop.transform.transformFlags & TransformFlags::OffsetByFudgeFactor);
// Color filter uniforms
- if (fill.filterMode == ProgramDescription::kColorBlend) {
+ if (fill.filterMode == ProgramDescription::ColorFilterMode::Blend) {
const FloatColor& color = fill.filter.color;
glUniform4f(mCaches->program().getUniform("colorBlend"),
color.r, color.g, color.b, color.a);
- } else if (fill.filterMode == ProgramDescription::kColorMatrix) {
+ } else if (fill.filterMode == ProgramDescription::ColorFilterMode::Matrix) {
glUniformMatrix4fv(mCaches->program().getUniform("colorMatrix"), 1, GL_FALSE,
fill.filter.matrix.matrix);
glUniform4fv(mCaches->program().getUniform("colorMatrixVector"), 1,
@@ -320,7 +322,7 @@
GLsizei elementsCount = mesh.elementCount;
const GLbyte* vertexData = static_cast<const GLbyte*>(vertices.position);
while (elementsCount > 0) {
- GLsizei drawCount = MathUtils::min(elementsCount, (GLsizei) kMaxNumberOfQuads * 6);
+ GLsizei drawCount = std::min(elementsCount, (GLsizei) kMaxNumberOfQuads * 6);
// rebind pointers without forcing, since initial bind handled above
meshState().bindPositionVertexPointer(false, vertexData, vertices.stride);
diff --git a/libs/hwui/renderstate/Stencil.cpp b/libs/hwui/renderstate/Stencil.cpp
index 319cfe4..d25ad51 100644
--- a/libs/hwui/renderstate/Stencil.cpp
+++ b/libs/hwui/renderstate/Stencil.cpp
@@ -34,10 +34,6 @@
#define STENCIL_MASK_VALUE 0x1
#endif
-Stencil::Stencil()
- : mState(kDisabled) {
-}
-
uint8_t Stencil::getStencilSize() {
return STENCIL_BUFFER_SIZE;
}
@@ -64,14 +60,14 @@
glClearStencil(0);
glClear(GL_STENCIL_BUFFER_BIT);
- if (mState == kTest) {
+ if (mState == StencilState::Test) {
// reset to test state, with immutable stencil
glStencilMask(0);
}
}
void Stencil::enableTest(int incrementThreshold) {
- if (mState != kTest) {
+ if (mState != StencilState::Test) {
enable();
if (incrementThreshold > 0) {
glStencilFunc(GL_EQUAL, incrementThreshold, 0xff);
@@ -82,12 +78,12 @@
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glStencilMask(0);
- mState = kTest;
+ mState = StencilState::Test;
}
}
void Stencil::enableWrite(int incrementThreshold) {
- if (mState != kWrite) {
+ if (mState != StencilState::Write) {
enable();
if (incrementThreshold > 0) {
glStencilFunc(GL_ALWAYS, 1, 0xff);
@@ -100,7 +96,7 @@
}
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glStencilMask(0xff);
- mState = kWrite;
+ mState = StencilState::Write;
}
}
@@ -109,7 +105,7 @@
glStencilFunc(greater ? GL_LESS : GL_EQUAL, value, 0xffffffff);
// We only want to test, let's keep everything
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
- mState = kTest;
+ mState = StencilState::Test;
glStencilMask(0);
}
@@ -119,20 +115,20 @@
// The test always passes so the first two values are meaningless
glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
- mState = kWrite;
+ mState = StencilState::Write;
glStencilMask(0xff);
}
void Stencil::enable() {
- if (mState == kDisabled) {
+ if (mState == StencilState::Disabled) {
glEnable(GL_STENCIL_TEST);
}
}
void Stencil::disable() {
- if (mState != kDisabled) {
+ if (mState != StencilState::Disabled) {
glDisable(GL_STENCIL_TEST);
- mState = kDisabled;
+ mState = StencilState::Disabled;
}
}
diff --git a/libs/hwui/renderstate/Stencil.h b/libs/hwui/renderstate/Stencil.h
index 3261823..5f7d405 100644
--- a/libs/hwui/renderstate/Stencil.h
+++ b/libs/hwui/renderstate/Stencil.h
@@ -30,8 +30,6 @@
class ANDROID_API Stencil {
public:
- Stencil();
-
/**
* Returns the desired size for the stencil buffer. If the returned value
* is 0, then no stencil buffer is required.
@@ -81,32 +79,31 @@
* Indicates whether either test or write is enabled.
*/
bool isEnabled() {
- return mState != kDisabled;
+ return mState != StencilState::Disabled;
}
/**
* Indicates whether testing only is enabled.
*/
bool isTestEnabled() {
- return mState == kTest;
+ return mState == StencilState::Test;
}
bool isWriteEnabled() {
- return mState == kWrite;
+ return mState == StencilState::Write;
}
void dump();
private:
- void enable();
-
- enum StencilState {
- kDisabled,
- kTest,
- kWrite
+ enum class StencilState {
+ Disabled,
+ Test,
+ Write
};
- StencilState mState;
+ void enable();
+ StencilState mState = StencilState::Disabled;
}; // class Stencil
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 67c42f3..7cb7738 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -421,7 +421,7 @@
// Make sure to release all the textures we were owning as there won't
// be another draw
caches.textureCache.resetMarkInUse(this);
- caches.flush(Caches::kFlushMode_Layers);
+ caches.flush(Caches::FlushMode::Layers);
}
}
@@ -431,10 +431,10 @@
ATRACE_CALL();
if (level >= TRIM_MEMORY_COMPLETE) {
- Caches::getInstance().flush(Caches::kFlushMode_Full);
+ Caches::getInstance().flush(Caches::FlushMode::Full);
thread.eglManager().destroy();
} else if (level >= TRIM_MEMORY_UI_HIDDEN) {
- Caches::getInstance().flush(Caches::kFlushMode_Moderate);
+ Caches::getInstance().flush(Caches::FlushMode::Moderate);
}
}
diff --git a/libs/hwui/utils/MathUtils.h b/libs/hwui/utils/MathUtils.h
index 9c3787c..8d20f21 100644
--- a/libs/hwui/utils/MathUtils.h
+++ b/libs/hwui/utils/MathUtils.h
@@ -16,6 +16,7 @@
#ifndef MATHUTILS_H
#define MATHUTILS_H
+#include <algorithm>
#include <math.h>
namespace android {
@@ -82,18 +83,8 @@
}
template<typename T>
- static inline T max(T a, T b) {
- return a > b ? a : b;
- }
-
- template<typename T>
- static inline T min(T a, T b) {
- return a < b ? a : b;
- }
-
- template<typename T>
static inline T clamp(T a, T minValue, T maxValue) {
- return min(max(a, minValue), maxValue);
+ return std::min(std::max(a, minValue), maxValue);
}
inline static float lerp(float v1, float v2, float t) {
diff --git a/media/java/android/mtp/MtpObjectInfo.java b/media/java/android/mtp/MtpObjectInfo.java
index d2824b5..f79d52e 100644
--- a/media/java/android/mtp/MtpObjectInfo.java
+++ b/media/java/android/mtp/MtpObjectInfo.java
@@ -256,7 +256,7 @@
/**
* Builds a new object info instance.
*/
- public class Builder {
+ public static class Builder {
private MtpObjectInfo mObjectInfo;
public Builder() {
diff --git a/media/jni/android_mtp_MtpDevice.cpp b/media/jni/android_mtp_MtpDevice.cpp
index ad804f3..9dd3861 100644
--- a/media/jni/android_mtp_MtpDevice.cpp
+++ b/media/jni/android_mtp_MtpDevice.cpp
@@ -430,12 +430,14 @@
android_mtp_MtpDevice_send_object_info(JNIEnv *env, jobject thiz, jobject info)
{
MtpDevice* device = get_device_from_object(env, thiz);
- if (!device)
+ if (!device) {
return JNI_FALSE;
+ }
// Updating existing objects is not supported.
- if (env->GetIntField(info, field_objectInfo_handle) != -1)
+ if (env->GetIntField(info, field_objectInfo_handle) != -1) {
return JNI_FALSE;
+ }
MtpObjectInfo* object_info = new MtpObjectInfo(-1);
object_info->mStorageID = env->GetIntField(info, field_objectInfo_storageId);
@@ -456,17 +458,21 @@
object_info->mSequenceNumber = env->GetIntField(info, field_objectInfo_sequenceNumber);
jstring name_jstring = (jstring) env->GetObjectField(info, field_objectInfo_name);
- const char* name_string = env->GetStringUTFChars(name_jstring, NULL);
- object_info->mName = strdup(name_string);
- env->ReleaseStringUTFChars(name_jstring, name_string);
+ if (name_jstring != NULL) {
+ const char* name_string = env->GetStringUTFChars(name_jstring, NULL);
+ object_info->mName = strdup(name_string);
+ env->ReleaseStringUTFChars(name_jstring, name_string);
+ }
object_info->mDateCreated = env->GetLongField(info, field_objectInfo_dateCreated) / 1000LL;
object_info->mDateModified = env->GetLongField(info, field_objectInfo_dateModified) / 1000LL;
jstring keywords_jstring = (jstring) env->GetObjectField(info, field_objectInfo_keywords);
- const char* keywords_string = env->GetStringUTFChars(keywords_jstring, NULL);
- object_info->mKeywords = strdup(keywords_string);
- env->ReleaseStringUTFChars(keywords_jstring, keywords_string);
+ if (keywords_jstring != NULL) {
+ const char* keywords_string = env->GetStringUTFChars(keywords_jstring, NULL);
+ object_info->mKeywords = strdup(keywords_string);
+ env->ReleaseStringUTFChars(keywords_jstring, keywords_string);
+ }
int object_handle = device->sendObjectInfo(object_info);
if (object_handle == -1) {
diff --git a/packages/DocumentsUI/res/layout/item_doc_grid.xml b/packages/DocumentsUI/res/layout/item_doc_grid.xml
index 1001e10..71e618b 100644
--- a/packages/DocumentsUI/res/layout/item_doc_grid.xml
+++ b/packages/DocumentsUI/res/layout/item_doc_grid.xml
@@ -14,7 +14,7 @@
limitations under the License.
-->
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<com.android.documentsui.GridItem xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="@dimen/grid_item_height"
android:layout_margin="@dimen/grid_item_margin"
@@ -140,4 +140,4 @@
android:contentDescription="@null"
android:duplicateParentState="true" />
-</FrameLayout>
+</com.android.documentsui.GridItem>
diff --git a/packages/DocumentsUI/res/layout/item_loading_grid.xml b/packages/DocumentsUI/res/layout/item_loading_grid.xml
index 005a111..147dfd4 100644
--- a/packages/DocumentsUI/res/layout/item_loading_grid.xml
+++ b/packages/DocumentsUI/res/layout/item_loading_grid.xml
@@ -14,7 +14,7 @@
limitations under the License.
-->
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<com.android.documentsui.GridItem xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="@dimen/grid_height"
android:orientation="horizontal">
@@ -26,4 +26,4 @@
android:indeterminate="true"
style="?android:attr/progressBarStyle" />
-</FrameLayout>
+</com.android.documentsui.GridItem>
diff --git a/packages/DocumentsUI/res/layout/item_message_grid.xml b/packages/DocumentsUI/res/layout/item_message_grid.xml
index 385563d..45d61a5 100644
--- a/packages/DocumentsUI/res/layout/item_message_grid.xml
+++ b/packages/DocumentsUI/res/layout/item_message_grid.xml
@@ -14,7 +14,7 @@
limitations under the License.
-->
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<com.android.documentsui.GridItem xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="@dimen/grid_height"
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
@@ -48,4 +48,4 @@
</LinearLayout>
-</FrameLayout>
+</com.android.documentsui.GridItem>
diff --git a/packages/DocumentsUI/src/com/android/documentsui/BandSelectMatrix.java b/packages/DocumentsUI/src/com/android/documentsui/BandSelectMatrix.java
new file mode 100644
index 0000000..f259059
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/BandSelectMatrix.java
@@ -0,0 +1,645 @@
+/*
+ * Copyright (C) 2013 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.documentsui;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.google.common.base.Preconditions;
+
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.support.annotation.Nullable;
+import android.support.v7.widget.GridLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.RecyclerView.LayoutManager;
+import android.support.v7.widget.RecyclerView.OnScrollListener;
+import android.util.SparseBooleanArray;
+import android.view.View;
+
+/**
+ * Provides a band selection item model for views within a RecyclerView. This class queries the
+ * RecyclerView to determine where its items are placed; then, once band selection is underway, it
+ * alerts listeners of which items are covered by the selections.
+ */
+public final class BandSelectMatrix extends RecyclerView.OnScrollListener {
+
+ private final RecyclerViewHelper mHelper;
+ private final List<OnSelectionChangedListener> mOnSelectionChangedListeners = new ArrayList<>();
+
+ // Map from the x-value of the left side of an item to an ordered list of metadata of all items
+ // whose x-values are the same. The list is ordered by the y-values of the items in the column.
+ // For example, if the first column of the view starts at an x-value of 5, mColumns.get(5) would
+ // return a list of all items in that column, with the top-most item first in the list and the
+ // bottom-most item last in the list.
+ private final Map<Integer, List<ItemData>> mColumns = new HashMap<>();
+
+ // List of limits along the x-axis. For example, if the view has two columns, this list will
+ // have two elements, each of which lists the lower- and upper-limits of the x-values of the
+ // view items. This list is sorted from furthest left to furthest right.
+ private final List<Limits> mXLimitsList = new ArrayList<>();
+
+ // Like mXLimitsList, but for y-coordinates. Note that this list only contains items which have
+ // been in the viewport. Thus, limits which exist in an area of the view to which the view has
+ // not scrolled are not present in the list.
+ private final List<Limits> mYLimitsList = new ArrayList<>();
+
+ // The adapter positions which have been recorded so far.
+ private final SparseBooleanArray mRecordedPositions = new SparseBooleanArray();
+
+ // Array passed to registered OnSelectionChangedListeners. One array is created and reused
+ // throughout the lifetime of the object.
+ private final SparseBooleanArray mSelectionForListeners = new SparseBooleanArray();
+
+ // The current pointer (in absolute positioning from the top of the view).
+ private Point mPointer = null;
+
+ // The bounds of the band selection.
+ private RelativePoint mRelativeOrigin;
+ private RelativePoint mRelativePointer;
+
+ BandSelectMatrix(RecyclerViewHelper helper) {
+ mHelper = helper;
+ mHelper.addOnScrollListener(this);
+ }
+
+ BandSelectMatrix(RecyclerView rv) {
+ this(new RuntimeRecyclerViewHelper(rv));
+ }
+
+ /**
+ * Stops listening to the view's scrolls. Call this function before discarding a
+ * BandSelecMatrix object to prevent memory leaks.
+ */
+ void stopListening() {
+ mHelper.removeOnScrollListener(this);
+ }
+
+ /**
+ * Start a band select operation at the given point.
+ * @param relativeOrigin The origin of the band select operation, relative to the viewport.
+ * For example, if the view is scrolled to the bottom, the top-left of the viewport would
+ * have a relative origin of (0, 0), even though its absolute point has a higher y-value.
+ */
+ void startSelection(Point relativeOrigin) {
+ Point absoluteOrigin = mHelper.createAbsolutePoint(relativeOrigin);
+ mPointer = new Point(absoluteOrigin.x, absoluteOrigin.y);
+
+ processVisibleChildren();
+ mRelativeOrigin = new RelativePoint(absoluteOrigin);
+ mRelativePointer = new RelativePoint(mPointer);
+ computeCurrentSelection();
+ notifyListeners();
+ }
+
+ /**
+ * Resizes the selection by adjusting the pointer (i.e., the corner of the selection opposite
+ * the origin.
+ * @param relativePointer The pointer (opposite of the origin) of the band select operation,
+ * relative to the viewport. For example, if the view is scrolled to the bottom, the
+ * top-left of the viewport would have a relative origin of (0, 0), even though its absolute
+ * point has a higher y-value.
+ */
+ void resizeSelection(Point relativePointer) {
+ mPointer = mHelper.createAbsolutePoint(relativePointer);
+ handlePointerMoved();
+ }
+
+ @Override
+ public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
+ if (mPointer == null) {
+ return;
+ }
+
+ mPointer.x += dx;
+ mPointer.y += dy;
+ processVisibleChildren();
+ handlePointerMoved();
+ }
+
+ /**
+ * Queries the view for all children and records their location metadata.
+ */
+ private void processVisibleChildren() {
+ for (int i = 0; i < mHelper.getVisibleChildCount(); i++) {
+ int adapterPosition = mHelper.getAdapterPositionAt(i);
+ if (!mRecordedPositions.get(adapterPosition)) {
+ mRecordedPositions.put(adapterPosition, true);
+ captureItemLayoutData(mHelper.getAbsoluteRectForChildViewAt(i), adapterPosition);
+ }
+ }
+ }
+
+ /**
+ * Updates the limits lists and column map with the given item metadata.
+ * @param absoluteChildRect The absolute rectangle for the child view being processed.
+ * @param adapterPosition The position of the child view being processed.
+ */
+ private void captureItemLayoutData(Rect absoluteChildRect, int adapterPosition) {
+ if (mXLimitsList.size() != mHelper.getNumColumns()) {
+ // If not all x-limits have been recorded, record this one.
+ recordLimits(
+ mXLimitsList, new Limits(absoluteChildRect.left, absoluteChildRect.right));
+ }
+
+ if (mYLimitsList.size() != mHelper.getNumRows()) {
+ // If not all y-limits have been recorded, record this one.
+ recordLimits(
+ mYLimitsList, new Limits(absoluteChildRect.top, absoluteChildRect.bottom));
+ }
+
+ List<ItemData> columnList = mColumns.get(absoluteChildRect.left);
+ if (columnList == null) {
+ columnList = new ArrayList<ItemData>();
+ mColumns.put(absoluteChildRect.left, columnList);
+ }
+ recordItemData(
+ columnList, new ItemData(adapterPosition, absoluteChildRect.top));
+ }
+
+ /**
+ * Ensures limits exists within the sorted list limitsList, and adds it to the list if it does
+ * not exist.
+ */
+ private static void recordLimits(List<Limits> limitsList, Limits limits) {
+ int index = Collections.binarySearch(limitsList, limits);
+ if (index < 0) {
+ limitsList.add(~index, limits);
+ }
+ }
+
+ /**
+ * Ensures itemData exists within the sorted list itemDataList, and adds it to the list if it
+ * does not exist.
+ */
+ private static void recordItemData(List<ItemData> itemDataList, ItemData itemData) {
+ int index = Collections.binarySearch(itemDataList, itemData);
+ if (index < 0) {
+ itemDataList.add(~index, itemData);
+ }
+ }
+
+ /**
+ * Handles a moved pointer; this function determines whether the pointer movement resulted in a
+ * selection change and, if it has, notifies listeners of this change.
+ */
+ private void handlePointerMoved() {
+ RelativePoint old = mRelativePointer;
+ mRelativePointer = new RelativePoint(mPointer);
+ if (old != null && mRelativePointer.equals(old)) {
+ return;
+ }
+
+ computeCurrentSelection();
+ notifyListeners();
+ }
+
+ /**
+ * Computes the currently-selected items.
+ */
+ private void computeCurrentSelection() {
+ Rect selectionRect = mRelativePointer.computeBounds(mRelativeOrigin);
+ computePositionsCoveredByRect(selectionRect);
+ }
+
+ /**
+ * Notifies all listeners of a selection change. Note that this function simply passes
+ * mSelectionForListeners, so computeCurrentSelection() should be called before this function.
+ */
+ private void notifyListeners() {
+ for (OnSelectionChangedListener listener : mOnSelectionChangedListeners) {
+ listener.onSelectionChanged(mSelectionForListeners);
+ }
+ }
+
+ /**
+ * @param rect Rectangle including all covered items.
+ */
+ private void computePositionsCoveredByRect(@Nullable Rect rect) {
+ mSelectionForListeners.clear();
+ if (rect == null) {
+ // If there is no bounding rectangle, there are no items selected, so just return early.
+ return;
+ }
+
+ int columnIndex = Collections.binarySearch(mXLimitsList, new Limits(rect.left, rect.left));
+ Preconditions.checkState(columnIndex >= 0);
+
+ for (; columnIndex < mXLimitsList.size() &&
+ mXLimitsList.get(columnIndex).lowerLimit <= rect.right; columnIndex++) {
+ List<ItemData> positions =
+ mColumns.get(mXLimitsList.get(columnIndex).lowerLimit);
+ int rowIndex = Collections.binarySearch(positions, new ItemData(0, rect.top));
+ if (rowIndex < 0) {
+ // If band select occurs after the last item in a row with fewer items than columns,
+ // go to the next column. This situation occurs in the last row of the grid when the
+ // total number of items is not a multiple of the number of columns (e.g., when 10
+ // items exist in a grid with 4 columns).
+ continue;
+ }
+
+ for (; rowIndex < positions.size() &&
+ positions.get(rowIndex).offset <= rect.bottom; rowIndex++) {
+ mSelectionForListeners.append(positions.get(rowIndex).position, true);
+ }
+ }
+ }
+
+ /**
+ * Provides functionality for interfacing with the view. In practice, RecyclerViewMatrixHelper
+ * should be used; this interface exists solely for the purpose of decoupling the view from
+ * this class so that the view can be mocked out for tests.
+ */
+ interface RecyclerViewHelper {
+ public void addOnScrollListener(RecyclerView.OnScrollListener listener);
+ public void removeOnScrollListener(RecyclerView.OnScrollListener listener);
+ public Point createAbsolutePoint(Point relativePoint);
+ public int getVisibleChildCount();
+ public int getTotalChildCount();
+ public int getNumColumns();
+ public int getNumRows();
+ public int getAdapterPositionAt(int index);
+ public Rect getAbsoluteRectForChildViewAt(int index);
+ }
+
+ /**
+ * Concrete MatrixHelper implementation for use within the Files app.
+ */
+ static class RuntimeRecyclerViewHelper implements RecyclerViewHelper {
+ private final RecyclerView mRecyclerView;
+
+ RuntimeRecyclerViewHelper(RecyclerView rv) {
+ mRecyclerView = rv;
+ }
+
+ @Override
+ public int getAdapterPositionAt(int index) {
+ View child = mRecyclerView.getChildAt(index);
+ return mRecyclerView.getChildViewHolder(child).getAdapterPosition();
+ }
+
+ @Override
+ public void addOnScrollListener(OnScrollListener listener) {
+ mRecyclerView.addOnScrollListener(listener);
+ }
+
+ @Override
+ public void removeOnScrollListener(OnScrollListener listener) {
+ mRecyclerView.removeOnScrollListener(listener);
+ }
+
+ @Override
+ public Point createAbsolutePoint(Point relativePoint) {
+ return new Point(relativePoint.x + mRecyclerView.computeHorizontalScrollOffset(),
+ relativePoint.y + mRecyclerView.computeVerticalScrollOffset());
+ }
+
+ @Override
+ public Rect getAbsoluteRectForChildViewAt(int index) {
+ final View child = mRecyclerView.getChildAt(index);
+ final Rect childRect = new Rect();
+ child.getHitRect(childRect);
+ childRect.left += mRecyclerView.computeHorizontalScrollOffset();
+ childRect.right += mRecyclerView.computeHorizontalScrollOffset();
+ childRect.top += mRecyclerView.computeVerticalScrollOffset();
+ childRect.bottom += mRecyclerView.computeVerticalScrollOffset();
+ return childRect;
+ }
+
+ @Override
+ public int getVisibleChildCount() {
+ return mRecyclerView.getChildCount();
+ }
+
+ @Override
+ public int getTotalChildCount() {
+ return mRecyclerView.getAdapter().getItemCount();
+ }
+
+ @Override
+ public int getNumColumns() {
+ LayoutManager layoutManager = mRecyclerView.getLayoutManager();
+ if (layoutManager instanceof GridLayoutManager) {
+ return ((GridLayoutManager) layoutManager).getSpanCount();
+ }
+
+ // Otherwise, it is a list with 1 column.
+ return 1;
+ }
+
+ @Override
+ public int getNumRows() {
+ int numFullColumns = getTotalChildCount() / getNumColumns();
+ boolean hasPartiallyFullColumn = getTotalChildCount() % getNumColumns() != 0;
+ return numFullColumns + (hasPartiallyFullColumn ? 1 : 0);
+ }
+ }
+
+ /**
+ * Listener for changes in which items have been band selected.
+ */
+ interface OnSelectionChangedListener {
+ public void onSelectionChanged(SparseBooleanArray updatedSelection);
+ }
+
+ void addOnSelectionChangedListener(OnSelectionChangedListener listener) {
+ mOnSelectionChangedListeners.add(listener);
+ }
+
+ void removeOnSelectionChangedListener(OnSelectionChangedListener listener) {
+ mOnSelectionChangedListeners.remove(listener);
+ }
+
+ /**
+ * Metadata for an item in the view, consisting of the adapter position and the offset from the
+ * top of the view (in pixels). Stored in the mColumns map to model the item grid.
+ */
+ private static class ItemData implements Comparable<ItemData> {
+ int position;
+ int offset;
+
+ ItemData(int position, int offset) {
+ this.position = position;
+ this.offset = offset;
+ }
+
+ @Override
+ public int compareTo(ItemData other) {
+ // The list of columns is sorted via the offset from the top, so PositionMetadata
+ // objects with lower y-values are befor those with higher y-values.
+ return offset - other.offset;
+ }
+ }
+
+ /**
+ * Limits of a view item. For example, if an item's left side is at x-value 5 and its right side
+ * is at x-value 10, the limits would be from 5 to 10. Used to record the left- and right sides
+ * of item columns and the top- and bottom sides of item rows so that it can be determined
+ * whether the pointer is located within the bounds of an item.
+ */
+ private static class Limits implements Comparable<Limits> {
+ int lowerLimit;
+ int upperLimit;
+
+ Limits(int lowerLimit, int upperLimit) {
+ this.lowerLimit = lowerLimit;
+ this.upperLimit = upperLimit;
+ }
+
+ @Override
+ public int compareTo(Limits other) {
+ return lowerLimit - other.lowerLimit;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (!(other instanceof Limits)) {
+ return false;
+ }
+
+ return ((Limits) other).lowerLimit == lowerLimit &&
+ ((Limits) other).upperLimit == upperLimit;
+ }
+ }
+
+ /**
+ * The location of a coordinate relative to items. This class represents a general area of the
+ * view as it relates to band selection rather than an explicit point. For example, two
+ * different points within an item are considered to have the same "location" because band
+ * selection originating within the item would select the same items no matter which point
+ * was used. Same goes for points between items as well as those at the very beginning or end
+ * of the view.
+ *
+ * Tracking a coordinate (e.g., an x-value) as a CoordinateLocation instead of as an int has the
+ * advantage of tying the value to the Limits of items along that axis. This allows easy
+ * selection of items within those Limits as opposed to a search through every item to see if a
+ * given coordinate value falls within those Limits.
+ */
+ private static class RelativeCoordinate
+ implements Comparable<RelativeCoordinate> {
+ /**
+ * Location describing points after the last known item.
+ */
+ static final int AFTER_LAST_ITEM = 0;
+
+ /**
+ * Location describing points before the first known item.
+ */
+ static final int BEFORE_FIRST_ITEM = 1;
+
+ /**
+ * Location describing points between two items.
+ */
+ static final int BETWEEN_TWO_ITEMS = 2;
+
+ /**
+ * Location describing points within the limits of one item.
+ */
+ static final int WITHIN_LIMITS = 3;
+
+ /**
+ * The type of this coordinate, which is one of AFTER_LAST_ITEM, BEFORE_FIRST_ITEM,
+ * BETWEEN_TWO_ITEMS, or WITHIN_LIMITS.
+ */
+ final int type;
+
+ /**
+ * The limits before the coordinate; only populated when type == WITHIN_LIMITS or type ==
+ * BETWEEN_TWO_ITEMS.
+ */
+ Limits limitsBeforeCoordinate;
+
+ /**
+ * The limits after the coordinate; only populated when type == BETWEEN_TWO_ITEMS.
+ */
+ Limits limitsAfterCoordinate;
+
+ // Limits of the first known item; only populated when type == BEFORE_FIRST_ITEM.
+ Limits mFirstKnownItem;
+ // Limits of the last known item; only populated when type == AFTER_LAST_ITEM.
+ Limits mLastKnownItem;
+
+ /**
+ * @param limitsList The sorted limits list for the coordinate type. If this
+ * CoordinateLocation is an x-value, mXLimitsList should be passed; otherwise,
+ * mYLimitsList should be pased.
+ * @param value The coordinate value.
+ */
+ RelativeCoordinate(List<Limits> limitsList, int value) {
+ Limits dummyLimits = new Limits(value, value);
+ int index = Collections.binarySearch(limitsList, dummyLimits);
+
+ if (index >= 0) {
+ this.type = WITHIN_LIMITS;
+ this.limitsBeforeCoordinate = limitsList.get(index);
+ } else if (~index == 0) {
+ this.type = BEFORE_FIRST_ITEM;
+ this.mFirstKnownItem = limitsList.get(0);
+ } else if (~index == limitsList.size()) {
+ Limits lastLimits = limitsList.get(limitsList.size() - 1);
+ if (lastLimits.lowerLimit <= value && value <= lastLimits.upperLimit) {
+ this.type = WITHIN_LIMITS;
+ this.limitsBeforeCoordinate = lastLimits;
+ } else {
+ this.type = AFTER_LAST_ITEM;
+ this.mLastKnownItem = lastLimits;
+ }
+ } else {
+ Limits limitsBeforeIndex = limitsList.get(~index - 1);
+ if (limitsBeforeIndex.lowerLimit <= value && value <= limitsBeforeIndex.upperLimit) {
+ this.type = WITHIN_LIMITS;
+ this.limitsBeforeCoordinate = limitsList.get(~index - 1);
+ } else {
+ this.type = BETWEEN_TWO_ITEMS;
+ this.limitsBeforeCoordinate = limitsList.get(~index - 1);
+ this.limitsAfterCoordinate = limitsList.get(~index);
+ }
+ }
+ }
+
+ int toComparisonValue() {
+ if (type == BEFORE_FIRST_ITEM) {
+ return mFirstKnownItem.lowerLimit - 1;
+ } else if (type == AFTER_LAST_ITEM) {
+ return mLastKnownItem.upperLimit + 1;
+ } else if (type == BETWEEN_TWO_ITEMS) {
+ return limitsBeforeCoordinate.upperLimit + 1;
+ } else {
+ return limitsBeforeCoordinate.lowerLimit;
+ }
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (!(other instanceof RelativeCoordinate)) {
+ return false;
+ }
+
+ RelativeCoordinate otherCoordinate = (RelativeCoordinate) other;
+ return toComparisonValue() == otherCoordinate.toComparisonValue();
+ }
+
+ @Override
+ public int compareTo(RelativeCoordinate other) {
+ return toComparisonValue() - other.toComparisonValue();
+ }
+ }
+
+ /**
+ * The location of a point relative to the Limits of nearby items; consists of both an x- and
+ * y-RelativeCoordinateLocation.
+ */
+ private class RelativePoint {
+ final RelativeCoordinate xLocation;
+ final RelativeCoordinate yLocation;
+
+ RelativePoint(Point point) {
+ this.xLocation = new RelativeCoordinate(mXLimitsList, point.x);
+ this.yLocation = new RelativeCoordinate(mYLimitsList, point.y);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (!(other instanceof RelativePoint)) {
+ return false;
+ }
+
+ RelativePoint otherPoint = (RelativePoint) other;
+ return xLocation.equals(otherPoint.xLocation) && yLocation.equals(otherPoint.yLocation);
+ }
+
+ /**
+ * Generates a rectangle which contains the items selected by the two points.
+ * @param other The other PointLocation. A rectangle will be formed between "this" and
+ * "other".
+ * @return The rectangle, or null if no items were selected.
+ */
+ Rect computeBounds(RelativePoint other) {
+ if (!areItemsCoveredBySelection(mRelativePointer, mRelativeOrigin)) {
+ return null;
+ }
+
+ RelativeCoordinate minXLocation =
+ xLocation.compareTo(other.xLocation) < 0 ? xLocation : other.xLocation;
+ RelativeCoordinate maxXLocation =
+ minXLocation == xLocation ? other.xLocation : xLocation;
+ RelativeCoordinate minYLocation =
+ yLocation.compareTo(other.yLocation) < 0 ? yLocation : other.yLocation;
+ RelativeCoordinate maxYLocation =
+ minYLocation == yLocation ? other.yLocation : yLocation;
+
+ Rect rect = new Rect();
+ rect.left = getCoordinateValue(minXLocation, mXLimitsList, true);
+ rect.right = getCoordinateValue(maxXLocation, mXLimitsList, false);
+ rect.top = getCoordinateValue(minYLocation, mYLimitsList, true);
+ rect.bottom = getCoordinateValue(maxYLocation, mYLimitsList, false);
+ return rect;
+ }
+
+ int getCoordinateValue(RelativeCoordinate coordinate,
+ List<Limits> limitsList, boolean isStartOfRange) {
+ switch (coordinate.type) {
+ case RelativeCoordinate.BEFORE_FIRST_ITEM:
+ return limitsList.get(0).lowerLimit;
+ case RelativeCoordinate.AFTER_LAST_ITEM:
+ return limitsList.get(limitsList.size() - 1).upperLimit;
+ case RelativeCoordinate.BETWEEN_TWO_ITEMS:
+ if (isStartOfRange) {
+ return coordinate.limitsAfterCoordinate.lowerLimit;
+ } else {
+ return coordinate.limitsBeforeCoordinate.upperLimit;
+ }
+ case RelativeCoordinate.WITHIN_LIMITS:
+ return coordinate.limitsBeforeCoordinate.lowerLimit;
+ }
+
+ throw new RuntimeException("Invalid coordinate value.");
+ }
+ }
+
+ private static boolean areItemsCoveredBySelection(
+ RelativePoint first, RelativePoint second) {
+ return doesCoordinateLocationCoverItems(first.xLocation, second.xLocation) &&
+ doesCoordinateLocationCoverItems(first.yLocation, second.yLocation);
+ }
+
+ private static boolean doesCoordinateLocationCoverItems(
+ RelativeCoordinate pointerCoordinate,
+ RelativeCoordinate originCoordinate) {
+ if (pointerCoordinate.type == RelativeCoordinate.BEFORE_FIRST_ITEM &&
+ originCoordinate.type == RelativeCoordinate.BEFORE_FIRST_ITEM) {
+ return false;
+ }
+
+ if (pointerCoordinate.type == RelativeCoordinate.AFTER_LAST_ITEM &&
+ originCoordinate.type == RelativeCoordinate.AFTER_LAST_ITEM) {
+ return false;
+ }
+
+ if (pointerCoordinate.type == RelativeCoordinate.BETWEEN_TWO_ITEMS &&
+ originCoordinate.type == RelativeCoordinate.BETWEEN_TWO_ITEMS &&
+ pointerCoordinate.limitsBeforeCoordinate.equals(originCoordinate) &&
+ pointerCoordinate.limitsAfterCoordinate.equals(originCoordinate)) {
+ return false;
+ }
+
+ return true;
+ }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java b/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
index 9b8d847..a804e9a 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
@@ -22,7 +22,6 @@
import static com.android.documentsui.DirectoryFragment.ANIM_UP;
import static com.android.internal.util.Preconditions.checkArgument;
-import android.annotation.Nullable;
import android.app.Activity;
import android.app.Fragment;
import android.content.Intent;
@@ -38,6 +37,7 @@
import android.os.Parcelable;
import android.provider.DocumentsContract;
import android.provider.DocumentsContract.Root;
+import android.support.annotation.Nullable;
import android.util.Log;
import android.util.SparseArray;
import android.view.LayoutInflater;
@@ -60,8 +60,6 @@
import com.android.documentsui.model.DurableUtils;
import com.android.documentsui.model.RootInfo;
-import com.google.common.collect.Maps;
-
import libcore.io.IoUtils;
import java.io.FileNotFoundException;
@@ -371,7 +369,7 @@
public String currentSearch;
/** Instance state for every shown directory */
- public HashMap<String, SparseArray<Parcelable>> dirState = Maps.newHashMap();
+ public HashMap<String, SparseArray<Parcelable>> dirState = new HashMap<>();
/** Currently copying file */
public List<DocumentInfo> selectedDocumentsForCopy = new ArrayList<DocumentInfo>();
diff --git a/packages/DocumentsUI/src/com/android/documentsui/CreateDirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/CreateDirectoryFragment.java
index f927595..e408e6e 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/CreateDirectoryFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/CreateDirectoryFragment.java
@@ -16,7 +16,7 @@
package com.android.documentsui;
-import static com.android.documentsui.DocumentsActivity.TAG;
+import static com.android.documentsui.Shared.TAG;
import android.app.AlertDialog;
import android.app.Dialog;
@@ -36,7 +36,6 @@
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
-import android.view.inputmethod.EditorInfo;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
index 5223d76..704e607 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
@@ -24,14 +24,13 @@
import static com.android.documentsui.BaseActivity.State.MODE_LIST;
import static com.android.documentsui.BaseActivity.State.MODE_UNKNOWN;
import static com.android.documentsui.BaseActivity.State.SORT_ORDER_UNKNOWN;
-import static com.android.documentsui.DocumentsActivity.TAG;
+import static com.android.documentsui.Shared.TAG;
import static com.android.documentsui.model.DocumentInfo.getCursorInt;
import static com.android.documentsui.model.DocumentInfo.getCursorLong;
import static com.android.documentsui.model.DocumentInfo.getCursorString;
import static com.android.internal.util.Preconditions.checkNotNull;
import static com.android.internal.util.Preconditions.checkState;
-import android.annotation.NonNull;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.Fragment;
@@ -98,7 +97,7 @@
import com.android.documentsui.model.RootInfo;
import com.android.internal.util.Preconditions;
-import com.google.android.collect.Lists;
+import com.google.common.collect.Lists;
import java.util.ArrayList;
import java.util.Collections;
@@ -235,8 +234,7 @@
public void onLayoutChange(
View v, int left, int top, int right, int bottom, int oldLeft,
int oldTop, int oldRight, int oldBottom) {
- int thumbSize = getResources().getDimensionPixelSize(R.dimen.grid_width);
- mColumnCount = pickColumnCount(thumbSize);
+ mColumnCount = calculateColumnCount();
if (mGridLayout != null) {
mGridLayout.setSpanCount(mColumnCount);
}
@@ -535,8 +533,6 @@
updateLayout(state.derivedMode);
- final int thumbSize = getResources().getDimensionPixelSize(R.dimen.icon_size);
- mThumbSize = new Point(thumbSize, thumbSize);
mRecView.setAdapter(mAdapter);
}
@@ -573,13 +569,15 @@
mThumbSize = new Point(thumbSize, thumbSize);
}
- private int pickColumnCount(final int thumbSize) {
- int itemPadding =
- getResources().getDimensionPixelSize(R.dimen.grid_item_margin);
+ private int calculateColumnCount() {
+ int cellWidth = getResources().getDimensionPixelSize(R.dimen.grid_width);
+ int cellMargin = 2 * getResources().getDimensionPixelSize(R.dimen.grid_item_margin);
int viewPadding = mRecView.getPaddingLeft() + mRecView.getPaddingRight();
+
checkState(mRecView.getWidth() > 0);
int columnCount = Math.max(1,
- (mRecView.getWidth() - viewPadding) / (thumbSize + itemPadding));
+ (mRecView.getWidth() - viewPadding) / (cellWidth + cellMargin));
+
return columnCount;
}
@@ -753,7 +751,7 @@
Intent intent;
// Filter out directories - those can't be shared.
- List<DocumentInfo> docsForSend = Lists.newArrayList();
+ List<DocumentInfo> docsForSend = new ArrayList<>();
for (DocumentInfo doc: docs) {
if (!Document.MIME_TYPE_DIR.equals(doc.mimeType)) {
docsForSend.add(doc);
@@ -774,8 +772,8 @@
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.addCategory(Intent.CATEGORY_DEFAULT);
- final ArrayList<String> mimeTypes = Lists.newArrayList();
- final ArrayList<Uri> uris = Lists.newArrayList();
+ final ArrayList<String> mimeTypes = new ArrayList<>();
+ final ArrayList<Uri> uris = new ArrayList<>();
for (DocumentInfo doc : docsForSend) {
mimeTypes.add(doc.mimeType);
uris.add(doc.derivedUri);
@@ -956,7 +954,7 @@
private final Context mContext;
private final LayoutInflater mInflater;
// TODO: Bring back support for footers.
- private final List<Footer> mFooters = Lists.newArrayList();
+ private final List<Footer> mFooters = new ArrayList<>();
private Cursor mCursor;
private int mCursorCount;
@@ -1330,7 +1328,7 @@
return MimePredicate.mimeMatches(state.acceptMimes, docMimeType);
}
- private @NonNull List<DocumentInfo> getSelectedDocuments() {
+ private List<DocumentInfo> getSelectedDocuments() {
Selection sel = mSelectionManager.getSelection(new Selection());
return getItemsAsDocuments(sel);
}
@@ -1570,6 +1568,7 @@
final Cursor cursor = mAdapter.getItem(position);
checkNotNull(cursor, "Cursor cannot be null.");
final DocumentInfo doc = DocumentInfo.fromDirectoryCursor(cursor);
+
return Lists.newArrayList(doc);
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DirectoryLoader.java b/packages/DocumentsUI/src/com/android/documentsui/DirectoryLoader.java
index a8a61d2..0edb241 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DirectoryLoader.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DirectoryLoader.java
@@ -16,12 +16,12 @@
package com.android.documentsui;
-import static com.android.documentsui.DocumentsActivity.TAG;
import static com.android.documentsui.BaseActivity.State.MODE_UNKNOWN;
import static com.android.documentsui.BaseActivity.State.SORT_ORDER_DISPLAY_NAME;
import static com.android.documentsui.BaseActivity.State.SORT_ORDER_LAST_MODIFIED;
import static com.android.documentsui.BaseActivity.State.SORT_ORDER_SIZE;
import static com.android.documentsui.BaseActivity.State.SORT_ORDER_UNKNOWN;
+import static com.android.documentsui.Shared.TAG;
import static com.android.documentsui.model.DocumentInfo.getCursorInt;
import android.content.AsyncTaskLoader;
@@ -31,8 +31,6 @@
import android.database.Cursor;
import android.net.Uri;
import android.os.CancellationSignal;
-import android.os.Handler;
-import android.os.Looper;
import android.os.OperationCanceledException;
import android.os.RemoteException;
import android.provider.DocumentsContract;
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DocumentClipper.java b/packages/DocumentsUI/src/com/android/documentsui/DocumentClipper.java
index 2370575..6ba07fbb 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DocumentClipper.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DocumentClipper.java
@@ -16,8 +16,6 @@
package com.android.documentsui;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.ContentProviderClient;
@@ -26,15 +24,15 @@
import android.database.Cursor;
import android.net.Uri;
import android.provider.DocumentsContract;
+import android.support.annotation.Nullable;
import android.util.Log;
import com.android.documentsui.model.DocumentInfo;
import com.android.internal.util.Preconditions;
-import com.google.android.collect.Lists;
-
import libcore.io.IoUtils;
+import java.util.ArrayList;
import java.util.List;
/**
@@ -78,7 +76,7 @@
* Returns a list of Documents as decoded from Clipboard primary clipdata.
* This should be run from inside an AsyncTask.
*/
- public @NonNull List<DocumentInfo> getClippedDocuments() {
+ public List<DocumentInfo> getClippedDocuments() {
return getDocumentsFromClipData(mClipboard.getPrimaryClip());
}
@@ -86,9 +84,9 @@
* Returns a list of Documents as decoded in clipData.
* This should be run from inside an AsyncTask.
*/
- public @NonNull List<DocumentInfo> getDocumentsFromClipData(ClipData clipData) {
+ public List<DocumentInfo> getDocumentsFromClipData(ClipData clipData) {
Preconditions.checkNotNull(clipData);
- final List<DocumentInfo> srcDocs = Lists.newArrayList();
+ final List<DocumentInfo> srcDocs = new ArrayList<>();
int count = clipData.getItemCount();
if (count == 0) {
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
index 2de7fc4..2c6bdb3 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
@@ -26,7 +26,6 @@
import static com.android.documentsui.DirectoryFragment.ANIM_DOWN;
import static com.android.documentsui.DirectoryFragment.ANIM_NONE;
import static com.android.documentsui.DirectoryFragment.ANIM_UP;
-import static com.android.internal.util.Preconditions.checkArgument;
import android.app.Activity;
import android.app.Fragment;
@@ -48,9 +47,6 @@
import android.os.Parcelable;
import android.provider.DocumentsContract;
import android.provider.DocumentsContract.Root;
-import android.support.v4.app.ActionBarDrawerToggle;
-import android.support.v4.widget.DrawerLayout;
-import android.support.v4.widget.DrawerLayout.DrawerListener;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
@@ -81,9 +77,7 @@
private Toolbar mRootsToolbar;
- private DrawerLayout mDrawerLayout;
- private ActionBarDrawerToggle mDrawerToggle;
- private View mRootsDrawer;
+ private DrawerController mDrawer;
private DirectoryContainerView mDirectoryContainer;
@@ -105,6 +99,7 @@
final Resources res = getResources();
mShowAsDialog = res.getBoolean(R.bool.show_as_dialog) && mState.action != ACTION_MANAGE &&
mState.action != ACTION_BROWSE;
+
if (!mShowAsDialog) {
setTheme(R.style.DocumentsNonDialogTheme);
}
@@ -117,6 +112,8 @@
final Context context = this;
if (mShowAsDialog) {
+ mDrawer = DrawerController.createDummy();
+
// Strongly define our horizontal dimension; we leave vertical as
// WRAP_CONTENT so that system resizes us when IME is showing.
final WindowManager.LayoutParams a = getWindow().getAttributes();
@@ -128,17 +125,7 @@
getWindow().setAttributes(a);
} else {
- // Non-dialog means we have a drawer
- mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
-
- if (mDrawerLayout != null) {
- mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
- R.drawable.ic_hamburger, R.string.drawer_open, R.string.drawer_close);
-
- mDrawerLayout.setDrawerListener(mDrawerListener);
-
- mRootsDrawer = findViewById(R.id.drawer_roots);
- }
+ mDrawer = DrawerController.create(this);
}
mDirectoryContainer = (DirectoryContainerView) findViewById(R.id.container_directory);
@@ -162,10 +149,9 @@
// Hide roots when we're managing a specific root
if (mState.action == ACTION_MANAGE || mState.action == ACTION_BROWSE) {
- if (mShowAsDialog || mDrawerLayout == null) {
+ mDrawer.lockClosed();
+ if (mShowAsDialog) {
findViewById(R.id.container_roots).setVisibility(View.GONE);
- } else {
- mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
}
}
@@ -341,53 +327,15 @@
}
}
- private DrawerListener mDrawerListener = new DrawerListener() {
- @Override
- public void onDrawerSlide(View drawerView, float slideOffset) {
- mDrawerToggle.onDrawerSlide(drawerView, slideOffset);
- }
-
- @Override
- public void onDrawerOpened(View drawerView) {
- mDrawerToggle.onDrawerOpened(drawerView);
- }
-
- @Override
- public void onDrawerClosed(View drawerView) {
- mDrawerToggle.onDrawerClosed(drawerView);
- }
-
- @Override
- public void onDrawerStateChanged(int newState) {
- mDrawerToggle.onDrawerStateChanged(newState);
- }
- };
-
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
- if (mDrawerToggle != null) {
- mDrawerToggle.syncState();
- }
+ mDrawer.syncState();
updateActionBar();
}
public void setRootsDrawerOpen(boolean open) {
- if (!mShowAsDialog && mDrawerLayout != null) {
- if (open) {
- mDrawerLayout.openDrawer(mRootsDrawer);
- } else {
- mDrawerLayout.closeDrawer(mRootsDrawer);
- }
- }
- }
-
- private boolean isRootsDrawerOpen() {
- if (mShowAsDialog || mDrawerLayout == null) {
- return false;
- } else {
- return mDrawerLayout.isDrawerOpen(mRootsDrawer);
- }
+ mDrawer.setOpen(open);
}
@Override
@@ -408,8 +356,7 @@
}
}
- if (!mShowAsDialog && mDrawerLayout != null &&
- mDrawerLayout.getDrawerLockMode(mRootsDrawer) == DrawerLayout.LOCK_MODE_UNLOCKED) {
+ if (!mShowAsDialog && mDrawer.isUnlocked()) {
mToolbar.setNavigationIcon(R.drawable.ic_hamburger);
mToolbar.setNavigationContentDescription(R.string.drawer_open);
mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
@@ -504,10 +451,7 @@
@Override
public boolean onOptionsItemSelected(MenuItem item) {
- if (mDrawerToggle != null && mDrawerToggle.onOptionsItemSelected(item)) {
- return true;
- }
- return super.onOptionsItemSelected(item);
+ return mDrawer.onOptionsItemSelected(item) || super.onOptionsItemSelected(item);
}
@Override
@@ -526,7 +470,7 @@
if (size > 1) {
mState.stack.pop();
onCurrentDirectoryChanged(ANIM_UP);
- } else if (size == 1 && !isRootsDrawerOpen()) {
+ } else if (size == 1 && !mDrawer.isOpen()) {
// TODO: open root drawer once we can capture back key
super.onBackPressed();
} else {
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DrawerController.java b/packages/DocumentsUI/src/com/android/documentsui/DrawerController.java
new file mode 100644
index 0000000..cf16c3f
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/DrawerController.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui;
+
+import static com.android.internal.util.Preconditions.checkArgument;
+
+import android.app.Activity;
+import android.support.v4.app.ActionBarDrawerToggle;
+import android.support.v4.widget.DrawerLayout;
+import android.support.v4.widget.DrawerLayout.DrawerListener;
+import android.view.MenuItem;
+import android.view.View;
+
+/**
+ * A facade over the various pieces comprising "roots fragment in a Drawer".
+ *
+ * @see DrawerController#create(DrawerLayout)
+ */
+abstract class DrawerController implements DrawerListener {
+
+ abstract void setOpen(boolean open);
+ abstract void lockOpen();
+ abstract void lockClosed();
+ abstract boolean isOpen();
+ abstract boolean isUnlocked();
+ abstract void syncState();
+ abstract boolean onOptionsItemSelected(MenuItem item);
+
+ /**
+ * Returns a controller suitable for {@code Layout}.
+ */
+ static DrawerController create(Activity activity) {
+
+ DrawerLayout layout = (DrawerLayout) activity.findViewById(R.id.drawer_layout);
+
+ if (layout == null) {
+ return new DummyDrawerController();
+ }
+
+ View drawer = activity.findViewById(R.id.drawer_roots);
+ ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
+ activity,
+ layout,
+ R.drawable.ic_hamburger,
+ R.string.drawer_open,
+ R.string.drawer_close);
+
+ return new RuntimeDrawerController(layout, drawer, toggle);
+ }
+
+ /**
+ * Returns a controller suitable for {@code Layout}.
+ */
+ static DrawerController createDummy() {
+ return new DummyDrawerController();
+ }
+
+ /**
+ * Runtime controller that manages a real drawer.
+ */
+ private static final class RuntimeDrawerController extends DrawerController {
+
+ private final ActionBarDrawerToggle mToggle;
+ private DrawerLayout mLayout;
+ private View mDrawer;
+
+ public RuntimeDrawerController(
+ DrawerLayout layout, View drawer, ActionBarDrawerToggle toggle) {
+ checkArgument(layout != null);
+
+ mLayout = layout;
+ mDrawer = drawer;
+ mToggle = toggle;
+
+ mLayout.setDrawerListener(this);
+ }
+
+ @Override
+ void setOpen(boolean open) {
+ if (open) {
+ mLayout.openDrawer(mDrawer);
+ } else {
+ mLayout.closeDrawer(mDrawer);
+ }
+ }
+
+ @Override
+ boolean isOpen() {
+ return mLayout.isDrawerOpen(mDrawer);
+ }
+
+ @Override
+ void syncState() {
+ mToggle.syncState();
+ }
+
+ @Override
+ boolean isUnlocked() {
+ return mLayout.getDrawerLockMode(mDrawer) == DrawerLayout.LOCK_MODE_UNLOCKED;
+ }
+
+ @Override
+ void lockOpen() {
+ mLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN);
+ }
+
+ @Override
+ void lockClosed() {
+ mLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
+ }
+
+ @Override
+ boolean onOptionsItemSelected(MenuItem item) {
+ return false;
+ }
+
+ @Override
+ public void onDrawerSlide(View drawerView, float slideOffset) {
+ mToggle.onDrawerSlide(drawerView, slideOffset);
+ }
+
+ @Override
+ public void onDrawerOpened(View drawerView) {
+ mToggle.onDrawerOpened(drawerView);
+ }
+
+ @Override
+ public void onDrawerClosed(View drawerView) {
+ mToggle.onDrawerClosed(drawerView);
+ }
+
+ @Override
+ public void onDrawerStateChanged(int newState) {
+ mToggle.onDrawerStateChanged(newState);
+ }
+ }
+
+ /*
+ * Dummy controller useful with clients that don't host a real drawer.
+ */
+ private static final class DummyDrawerController extends DrawerController {
+
+ @Override
+ boolean isOpen() {
+ return false;
+ }
+
+ @Override
+ void syncState() {}
+
+ @Override
+ void lockOpen() {}
+
+ @Override
+ void lockClosed() {}
+
+ @Override
+ boolean isUnlocked() {
+ return true;
+ }
+
+ @Override
+ boolean onOptionsItemSelected(MenuItem item) {
+ return false;
+ }
+
+ @Override
+ public void onDrawerSlide(View drawerView, float slideOffset) {}
+
+ @Override
+ public void onDrawerOpened(View drawerView) {}
+
+ @Override
+ public void onDrawerClosed(View drawerView) {}
+
+ @Override
+ public void onDrawerStateChanged(int newState) {}
+
+ @Override
+ void setOpen(boolean open) {}
+ }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/FilteringCursorWrapper.java b/packages/DocumentsUI/src/com/android/documentsui/FilteringCursorWrapper.java
index 1cbc221..17a1161 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/FilteringCursorWrapper.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/FilteringCursorWrapper.java
@@ -16,7 +16,7 @@
package com.android.documentsui;
-import static com.android.documentsui.DocumentsActivity.TAG;
+import static com.android.documentsui.Shared.TAG;
import static com.android.documentsui.model.DocumentInfo.getCursorLong;
import static com.android.documentsui.model.DocumentInfo.getCursorString;
diff --git a/packages/DocumentsUI/src/com/android/documentsui/GridItem.java b/packages/DocumentsUI/src/com/android/documentsui/GridItem.java
new file mode 100644
index 0000000..990dca7
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/GridItem.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.FrameLayout;
+
+/**
+ * A FrameLayout subclass used by DirectoryFragment. Ensures that the resulting grid item is always
+ * square.
+ */
+public class GridItem extends FrameLayout {
+ public GridItem(Context context) {
+ super(context);
+ }
+
+ public GridItem(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public GridItem(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ @Override
+ public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ // Grid layout uses item width to figure out the number of columns, then dynamically fits
+ // rows into the view. The upshot of this is that changing the item width will mess up the
+ // grid layout - so to make the items square, throw out the height and use the width for
+ // both dimensions. The grid layout will correctly adjust the row height.
+ //
+ // Note that this code will need to be changed if the layout manager's orientation is
+ // changed from VERTICAL to HORIZONTAL.
+ super.onMeasure(widthMeasureSpec, widthMeasureSpec);
+ }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/IconUtils.java b/packages/DocumentsUI/src/com/android/documentsui/IconUtils.java
index b43fedf..9959265 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/IconUtils.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/IconUtils.java
@@ -23,13 +23,11 @@
import android.provider.DocumentsContract.Document;
import android.util.TypedValue;
-import com.google.android.collect.Maps;
-
import java.util.HashMap;
public class IconUtils {
- private static HashMap<String, Integer> sMimeIcons = Maps.newHashMap();
+ private static HashMap<String, Integer> sMimeIcons = new HashMap<>();
private static void add(String mimeType, int resId) {
if (sMimeIcons.put(mimeType, resId) != null) {
diff --git a/packages/DocumentsUI/src/com/android/documentsui/MultiSelectManager.java b/packages/DocumentsUI/src/com/android/documentsui/MultiSelectManager.java
index 02edd0c..f87fe4c 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/MultiSelectManager.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/MultiSelectManager.java
@@ -31,7 +31,7 @@
import android.view.MotionEvent;
import android.view.View;
-import com.google.common.annotations.VisibleForTesting;
+import android.support.annotation.VisibleForTesting;
import java.util.ArrayList;
import java.util.List;
diff --git a/packages/DocumentsUI/src/com/android/documentsui/ProviderExecutor.java b/packages/DocumentsUI/src/com/android/documentsui/ProviderExecutor.java
index f94aebd..b0e332f 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/ProviderExecutor.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/ProviderExecutor.java
@@ -20,8 +20,6 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.Preconditions;
-import com.google.android.collect.Lists;
-import com.google.android.collect.Maps;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
@@ -32,7 +30,7 @@
public class ProviderExecutor extends Thread implements Executor {
@GuardedBy("sExecutors")
- private static HashMap<String, ProviderExecutor> sExecutors = Maps.newHashMap();
+ private static HashMap<String, ProviderExecutor> sExecutors = new HashMap<>();
public static ProviderExecutor forAuthority(String authority) {
synchronized (sExecutors) {
@@ -53,7 +51,7 @@
private final LinkedBlockingQueue<Runnable> mQueue = new LinkedBlockingQueue<Runnable>();
- private final ArrayList<WeakReference<Preemptable>> mPreemptable = Lists.newArrayList();
+ private final ArrayList<WeakReference<Preemptable>> mPreemptable = new ArrayList<>();
private void preempt() {
synchronized (mPreemptable) {
diff --git a/packages/DocumentsUI/src/com/android/documentsui/QuickViewIntentBuilder.java b/packages/DocumentsUI/src/com/android/documentsui/QuickViewIntentBuilder.java
index 878c4c2..4685c41 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/QuickViewIntentBuilder.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/QuickViewIntentBuilder.java
@@ -18,7 +18,6 @@
import static com.android.documentsui.model.DocumentInfo.getCursorString;
-import android.annotation.Nullable;
import android.content.ClipData;
import android.content.ClipDescription;
import android.content.ComponentName;
@@ -28,6 +27,7 @@
import android.net.Uri;
import android.provider.DocumentsContract;
import android.provider.DocumentsContract.Document;
+import android.support.annotation.Nullable;
import android.util.Log;
import com.android.documentsui.BaseActivity.DocumentContext;
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RecentLoader.java b/packages/DocumentsUI/src/com/android/documentsui/RecentLoader.java
index f5908c5..1a7095a 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/RecentLoader.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/RecentLoader.java
@@ -16,8 +16,8 @@
package com.android.documentsui;
-import static com.android.documentsui.DocumentsActivity.TAG;
import static com.android.documentsui.BaseActivity.State.SORT_ORDER_LAST_MODIFIED;
+import static com.android.documentsui.Shared.TAG;
import android.app.ActivityManager;
import android.content.AsyncTaskLoader;
@@ -36,14 +36,14 @@
import com.android.documentsui.BaseActivity.State;
import com.android.documentsui.model.RootInfo;
-import com.google.android.collect.Maps;
-import com.google.common.collect.Lists;
+
import com.google.common.util.concurrent.AbstractFuture;
import libcore.io.IoUtils;
import java.io.Closeable;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
@@ -53,7 +53,7 @@
import java.util.concurrent.TimeUnit;
public class RecentLoader extends AsyncTaskLoader<DirectoryResult> {
- private static final boolean LOGD = true;
+ private static final boolean DEBUG = false;
// TODO: clean up cursor ownership so background thread doesn't traverse
// previously returned cursors for filtering/sorting; this currently races
@@ -81,7 +81,7 @@
private final RootsCache mRoots;
private final State mState;
- private final HashMap<RootInfo, RecentTask> mTasks = Maps.newHashMap();
+ private final HashMap<RootInfo, RecentTask> mTasks = new HashMap<>();
private final int mSortOrder = State.SORT_ORDER_LAST_MODIFIED;
@@ -196,7 +196,7 @@
// Collect all finished tasks
boolean allDone = true;
- List<Cursor> cursors = Lists.newArrayList();
+ List<Cursor> cursors = new ArrayList<>();
for (RecentTask task : mTasks.values()) {
if (task.isDone()) {
try {
@@ -221,7 +221,7 @@
}
}
- if (LOGD) {
+ if (DEBUG) {
Log.d(TAG, "Found " + cursors.size() + " of " + mTasks.size() + " recent queries done");
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RecentsCreateFragment.java b/packages/DocumentsUI/src/com/android/documentsui/RecentsCreateFragment.java
index e11d7d9..662822e 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/RecentsCreateFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/RecentsCreateFragment.java
@@ -16,7 +16,7 @@
package com.android.documentsui;
-import static com.android.documentsui.DocumentsActivity.TAG;
+import static com.android.documentsui.Shared.TAG;
import android.app.Fragment;
import android.app.FragmentManager;
@@ -50,7 +50,6 @@
import com.android.documentsui.model.DocumentStack;
import com.android.documentsui.model.DurableUtils;
import com.android.documentsui.model.RootInfo;
-import com.google.android.collect.Lists;
import libcore.io.IoUtils;
@@ -157,7 +156,7 @@
@Override
public List<DocumentStack> loadInBackground(Uri uri, CancellationSignal signal) {
final Collection<RootInfo> matchingRoots = mRoots.getMatchingRootsBlocking(mState);
- final ArrayList<DocumentStack> result = Lists.newArrayList();
+ final ArrayList<DocumentStack> result = new ArrayList<>();
final ContentResolver resolver = getContext().getContentResolver();
final Cursor cursor = resolver.query(
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java b/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java
index fbcb938..05f7d8d 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java
@@ -16,7 +16,7 @@
package com.android.documentsui;
-import static com.android.documentsui.DocumentsActivity.TAG;
+import static com.android.documentsui.Shared.TAG;
import android.content.ContentProviderClient;
import android.content.ContentResolver;
@@ -39,14 +39,14 @@
import com.android.documentsui.BaseActivity.State;
import com.android.documentsui.model.RootInfo;
import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
-import com.google.android.collect.Lists;
-import com.google.android.collect.Sets;
+import android.support.annotation.VisibleForTesting;
+
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import libcore.io.IoUtils;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
@@ -74,10 +74,10 @@
@GuardedBy("mLock")
private Multimap<String, RootInfo> mRoots = ArrayListMultimap.create();
@GuardedBy("mLock")
- private HashSet<String> mStoppedAuthorities = Sets.newHashSet();
+ private HashSet<String> mStoppedAuthorities = new HashSet<>();
@GuardedBy("mObservedAuthorities")
- private final HashSet<String> mObservedAuthorities = Sets.newHashSet();
+ private final HashSet<String> mObservedAuthorities = new HashSet<>();
public RootsCache(Context context) {
mContext = context;
@@ -159,7 +159,7 @@
private final String mFilterPackage;
private final Multimap<String, RootInfo> mTaskRoots = ArrayListMultimap.create();
- private final HashSet<String> mTaskStoppedAuthorities = Sets.newHashSet();
+ private final HashSet<String> mTaskStoppedAuthorities = new HashSet<>();
/**
* Update all roots.
@@ -251,7 +251,7 @@
}
}
- final List<RootInfo> roots = Lists.newArrayList();
+ final List<RootInfo> roots = new ArrayList<>();
final Uri rootsUri = DocumentsContract.buildRootsUri(authority);
ContentProviderClient client = null;
@@ -350,7 +350,7 @@
@VisibleForTesting
static List<RootInfo> getMatchingRoots(Collection<RootInfo> roots, State state) {
- final List<RootInfo> matching = Lists.newArrayList();
+ final List<RootInfo> matching = new ArrayList<>();
for (RootInfo root : roots) {
final boolean supportsCreate = (root.flags & Root.FLAG_SUPPORTS_CREATE) != 0;
final boolean supportsIsChild = (root.flags & Root.FLAG_SUPPORTS_IS_CHILD) != 0;
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java b/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java
index fd67a77..c02184b 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java
@@ -44,8 +44,8 @@
import com.android.documentsui.BaseActivity.State;
import com.android.documentsui.model.DocumentInfo;
import com.android.documentsui.model.RootInfo;
-import com.google.common.collect.Lists;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
@@ -293,8 +293,8 @@
RootItem audio = null;
RootItem downloads = null;
- final List<RootInfo> clouds = Lists.newArrayList();
- final List<RootInfo> locals = Lists.newArrayList();
+ final List<RootInfo> clouds = new ArrayList<>();
+ final List<RootInfo> locals = new ArrayList<>();
for (RootInfo root : roots) {
if (root.isRecents()) {
@@ -338,7 +338,7 @@
final List<ResolveInfo> infos = pm.queryIntentActivities(
includeApps, PackageManager.MATCH_DEFAULT_ONLY);
- final List<AppItem> apps = Lists.newArrayList();
+ final List<AppItem> apps = new ArrayList<>();
// Omit ourselves from the list
for (ResolveInfo info : infos) {
diff --git a/packages/DocumentsUI/src/com/android/documentsui/SectionedListAdapter.java b/packages/DocumentsUI/src/com/android/documentsui/SectionedListAdapter.java
index 088e3fa..ae959f9 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/SectionedListAdapter.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/SectionedListAdapter.java
@@ -22,8 +22,6 @@
import android.widget.BaseAdapter;
import android.widget.ListAdapter;
-import com.google.android.collect.Lists;
-
import java.util.ArrayList;
/**
@@ -31,7 +29,7 @@
* provide a header, and correctly handling item types across child adapters.
*/
public class SectionedListAdapter extends BaseAdapter {
- private ArrayList<SectionAdapter> mSections = Lists.newArrayList();
+ private ArrayList<SectionAdapter> mSections = new ArrayList<>();
public interface SectionAdapter extends ListAdapter {
public View getHeaderView(View convertView, ViewGroup parent);
diff --git a/packages/DocumentsUI/src/com/android/documentsui/Shared.java b/packages/DocumentsUI/src/com/android/documentsui/Shared.java
new file mode 100644
index 0000000..b414ee3
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/Shared.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui;
+
+/**
+ * @hide
+ */
+public final class Shared {
+ public static final String TAG = "Documents";
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/StandaloneActivity.java b/packages/DocumentsUI/src/com/android/documentsui/StandaloneActivity.java
index 1ca277d..7ca3954 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/StandaloneActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/StandaloneActivity.java
@@ -20,7 +20,6 @@
import static com.android.documentsui.DirectoryFragment.ANIM_NONE;
import static com.android.documentsui.DirectoryFragment.ANIM_UP;
-import android.annotation.Nullable;
import android.app.Activity;
import android.app.FragmentManager;
import android.content.ActivityNotFoundException;
@@ -33,6 +32,7 @@
import android.os.Bundle;
import android.provider.DocumentsContract;
import android.provider.DocumentsContract.Root;
+import android.support.annotation.Nullable;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
@@ -70,6 +70,8 @@
private ItemSelectedListener mStackListener;
private BaseAdapter mStackAdapter;
private DocumentClipper mClipper;
+ private DrawerController mDrawer;
+ private boolean mCompactMode;
public StandaloneActivity() {
super(TAG);
@@ -107,6 +109,18 @@
setActionBar(mToolbar);
+
+ // "show as dialog" is true on BIG screens. But we *assume* a big screen
+ // and specialize for smaller screens by moving roots into an auto-hide drawer.
+ // This works in conjunction with the specialized layouts defined for sw720dp.
+ mCompactMode = !getResources().getBoolean(R.bool.show_as_dialog);
+
+ if (mCompactMode) {
+ setTheme(R.style.DocumentsNonDialogTheme);
+ }
+
+ mDrawer = DrawerController.create(this);
+
mClipper = new DocumentClipper(this);
RootsFragment.show(getFragmentManager(), null);
@@ -164,10 +178,23 @@
@Override
public void updateActionBar() {
final RootInfo root = getCurrentRoot();
- mToolbar.setNavigationIcon(
- root != null ? root.loadToolbarIcon(mToolbar.getContext()) : null);
- mToolbar.setNavigationContentDescription(R.string.drawer_open);
- mToolbar.setNavigationOnClickListener(null);
+
+ if (mCompactMode) {
+ mToolbar.setNavigationIcon(R.drawable.ic_hamburger);
+ mToolbar.setNavigationContentDescription(R.string.drawer_open);
+ mToolbar.setNavigationOnClickListener(
+ new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ mDrawer.setOpen(true);
+ }
+ });
+ } else {
+ mToolbar.setNavigationIcon(
+ root != null ? root.loadToolbarIcon(mToolbar.getContext()) : null);
+ mToolbar.setNavigationContentDescription(R.string.drawer_open);
+ mToolbar.setNavigationOnClickListener(null);
+ }
if (mSearchManager.isExpanded()) {
mToolbar.setTitle(null);
@@ -284,6 +311,12 @@
}
@Override
+ void onRootPicked(RootInfo root) {
+ super.onRootPicked(root);
+ mDrawer.setOpen(false);
+ }
+
+ @Override
public void onDocumentsPicked(List<DocumentInfo> docs) {
throw new UnsupportedOperationException();
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/UriDerivativeLoader.java b/packages/DocumentsUI/src/com/android/documentsui/UriDerivativeLoader.java
index 1a5bb0c..7bb662c 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/UriDerivativeLoader.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/UriDerivativeLoader.java
@@ -27,16 +27,16 @@
* changes while started, manages {@link CancellationSignal}, and caches
* returned results.
*/
-public abstract class UriDerivativeLoader<P, R> extends AsyncTaskLoader<R> {
+public abstract class UriDerivativeLoader<Param, Res> extends AsyncTaskLoader<Res> {
final ForceLoadContentObserver mObserver;
- private final P mParam;
+ private final Param mParam;
- private R mResult;
+ private Res mResult;
private CancellationSignal mCancellationSignal;
@Override
- public final R loadInBackground() {
+ public final Res loadInBackground() {
synchronized (this) {
if (isLoadInBackgroundCanceled()) {
throw new OperationCanceledException();
@@ -52,7 +52,7 @@
}
}
- public abstract R loadInBackground(P param, CancellationSignal signal);
+ public abstract Res loadInBackground(Param param, CancellationSignal signal);
@Override
public void cancelLoadInBackground() {
@@ -66,12 +66,12 @@
}
@Override
- public void deliverResult(R result) {
+ public void deliverResult(Res result) {
if (isReset()) {
closeQuietly(result);
return;
}
- R oldResult = mResult;
+ Res oldResult = mResult;
mResult = result;
if (isStarted()) {
@@ -83,7 +83,7 @@
}
}
- public UriDerivativeLoader(Context context, P param) {
+ public UriDerivativeLoader(Context context, Param param) {
super(context);
mObserver = new ForceLoadContentObserver();
mParam = param;
@@ -105,7 +105,7 @@
}
@Override
- public void onCanceled(R result) {
+ public void onCanceled(Res result) {
closeQuietly(result);
}
@@ -122,7 +122,7 @@
getContext().getContentResolver().unregisterContentObserver(mObserver);
}
- private void closeQuietly(R result) {
+ private void closeQuietly(Res result) {
if (result instanceof AutoCloseable) {
try {
((AutoCloseable) result).close();
diff --git a/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java b/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java
index 5d5f2eb..cc981e1e 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java
@@ -24,7 +24,6 @@
import android.os.Parcelable;
import android.provider.DocumentsContract;
import android.provider.DocumentsContract.Document;
-import android.provider.DocumentsContract.Root;
import android.provider.DocumentsProvider;
import android.text.TextUtils;
diff --git a/packages/DocumentsUI/src/com/android/documentsui/model/DurableUtils.java b/packages/DocumentsUI/src/com/android/documentsui/model/DurableUtils.java
index 2a29cbc..e21dd49 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/model/DurableUtils.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/model/DurableUtils.java
@@ -16,7 +16,7 @@
package com.android.documentsui.model;
-import static com.android.documentsui.DocumentsActivity.TAG;
+import static com.android.documentsui.Shared.TAG;
import android.os.BadParcelableException;
import android.os.Parcel;
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/BandSelectMatrixTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/BandSelectMatrixTest.java
new file mode 100644
index 0000000..f15a643
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/BandSelectMatrixTest.java
@@ -0,0 +1,277 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui;
+
+import static org.junit.Assert.*;
+
+import com.android.documentsui.BandSelectMatrix;
+
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.support.v7.widget.RecyclerView.OnScrollListener;
+import android.util.SparseBooleanArray;
+
+import org.junit.After;
+import org.junit.Test;
+
+public class BandSelectMatrixTest {
+
+ private static final int VIEW_PADDING_PX = 5;
+ private static final int CHILD_VIEW_EDGE_PX = 100;
+ private static final int VIEWPORT_HEIGHT = 500;
+
+ private static BandSelectMatrix matrix;
+ private static TestHelper helper;
+ private static SparseBooleanArray lastSelection;
+ private static int viewWidth;
+
+ private static void setUp(int numChildren, int numColumns) {
+ helper = new TestHelper(numChildren, numColumns);
+ viewWidth = VIEW_PADDING_PX + numColumns * (VIEW_PADDING_PX + CHILD_VIEW_EDGE_PX);
+ matrix = new BandSelectMatrix(helper);
+ matrix.addOnSelectionChangedListener(new BandSelectMatrix.OnSelectionChangedListener() {
+
+ @Override
+ public void onSelectionChanged(SparseBooleanArray updatedSelection) {
+ lastSelection = updatedSelection;
+ }
+ });
+ }
+
+ @After
+ public void tearDown() {
+ matrix = null;
+ helper = null;
+ lastSelection = null;
+ }
+
+ @Test
+ public void testSelectionLeftOfItems() {
+ setUp(20, 5);
+ matrix.startSelection(new Point(0, 10));
+ matrix.resizeSelection(new Point(1, 11));
+ assertSelected(new int[0]);
+ }
+
+ @Test
+ public void testSelectionRightOfItems() {
+ setUp(20, 4);
+ matrix.startSelection(new Point(viewWidth - 1, 10));
+ matrix.resizeSelection(new Point(viewWidth - 2, 11));
+ assertSelected(new int[0]);
+ }
+
+ @Test
+ public void testSelectionAboveItems() {
+ setUp(20, 4);
+ matrix.startSelection(new Point(10, 0));
+ matrix.resizeSelection(new Point(11, 1));
+ assertSelected(new int[0]);
+ }
+
+ @Test
+ public void testSelectionBelowItems() {
+ setUp(5, 4);
+ matrix.startSelection(new Point(10, VIEWPORT_HEIGHT - 1));
+ matrix.resizeSelection(new Point(11, VIEWPORT_HEIGHT - 2));
+ assertSelected(new int[0]);
+ }
+
+ @Test
+ public void testVerticalSelectionBetweenItems() {
+ setUp(20, 4);
+ matrix.startSelection(new Point(106, 0));
+ matrix.resizeSelection(new Point(107, 200));
+ assertSelected(new int[0]);
+ }
+
+ @Test
+ public void testHorizontalSelectionBetweenItems() {
+ setUp(20, 4);
+ matrix.startSelection(new Point(0, 105));
+ matrix.resizeSelection(new Point(200, 106));
+ assertSelected(new int[0]);
+ }
+
+ @Test
+ public void testGrowingAndShrinkingSelection() {
+ setUp(20, 4);
+ matrix.startSelection(new Point(0, 0));
+ matrix.resizeSelection(new Point(5, 5));
+ assertSelected(new int[] {0});
+ matrix.resizeSelection(new Point(109, 109));
+ assertSelected(new int[] {0});
+ matrix.resizeSelection(new Point(110, 109));
+ assertSelected(new int[] {0, 1});
+ matrix.resizeSelection(new Point(110, 110));
+ assertSelected(new int[] {0, 1, 4, 5});
+ matrix.resizeSelection(new Point(214, 214));
+ assertSelected(new int[] {0, 1, 4, 5});
+ matrix.resizeSelection(new Point(215, 214));
+ assertSelected(new int[] {0, 1, 2, 4, 5, 6});
+ matrix.resizeSelection(new Point(214, 214));
+ assertSelected(new int[] {0, 1, 4, 5});
+ matrix.resizeSelection(new Point(110, 110));
+ assertSelected(new int[] {0, 1, 4, 5});
+ matrix.resizeSelection(new Point(110, 109));
+ assertSelected(new int[] {0, 1});
+ matrix.resizeSelection(new Point(109, 109));
+ assertSelected(new int[] {0});
+ matrix.resizeSelection(new Point(5, 5));
+ assertSelected(new int[] {0});
+ matrix.resizeSelection(new Point(0, 0));
+ assertSelected(new int[0]);
+ }
+
+ @Test
+ public void testSelectionMovingAroundOrigin() {
+ setUp(16, 4);
+ matrix.startSelection(new Point(210, 210));
+ matrix.resizeSelection(new Point(viewWidth - 1, 0));
+ assertSelected(new int[] {2, 3, 6, 7});
+ matrix.resizeSelection(new Point(0, 0));
+ assertSelected(new int[] {0, 1, 4, 5});
+ matrix.resizeSelection(new Point(0, 420));
+ assertSelected(new int[] {8, 9, 12, 13});
+ matrix.resizeSelection(new Point(viewWidth - 1, 420));
+ assertSelected(new int[] {10, 11, 14, 15});
+ }
+
+ @Test
+ public void testScrollingBandSelect() {
+ setUp(40, 4);
+ matrix.startSelection(new Point(0, 0));
+ matrix.resizeSelection(new Point(100, VIEWPORT_HEIGHT - 1));
+ assertSelected(new int[] {0, 4, 8, 12, 16});
+ scroll(CHILD_VIEW_EDGE_PX);
+ assertSelected(new int[] {0, 4, 8, 12, 16, 20});
+ matrix.resizeSelection(new Point(200, VIEWPORT_HEIGHT - 1));
+ assertSelected(new int[] {0, 1, 4, 5, 8, 9, 12, 13, 16, 17, 20, 21});
+ scroll(CHILD_VIEW_EDGE_PX);
+ assertSelected(new int[] {0, 1, 4, 5, 8, 9, 12, 13, 16, 17, 20, 21, 24, 25});
+ scroll(-2 * CHILD_VIEW_EDGE_PX);
+ assertSelected(new int[] {0, 1, 4, 5, 8, 9, 12, 13, 16, 17});
+ matrix.resizeSelection(new Point(100, VIEWPORT_HEIGHT - 1));
+ assertSelected(new int[] {0, 4, 8, 12, 16});
+ }
+
+ private static void assertSelected(int[] selectedPositions) {
+ assertEquals(selectedPositions.length, lastSelection.size());
+ for (int position : selectedPositions) {
+ assertTrue(lastSelection.get(position));
+ }
+ }
+
+ private static void scroll(int dy) {
+ assertTrue(helper.verticalOffset + VIEWPORT_HEIGHT + dy <= helper.getTotalHeight());
+ helper.verticalOffset += dy;
+ matrix.onScrolled(null, 0, dy);
+ }
+
+ private static final class TestHelper implements BandSelectMatrix.RecyclerViewHelper {
+
+ public int horizontalOffset = 0;
+ public int verticalOffset = 0;
+ private final int mNumColumns;
+ private final int mNumRows;
+ private final int mNumChildren;
+
+ public TestHelper(int numChildren, int numColumns) {
+ mNumChildren = numChildren;
+ mNumColumns = numColumns;
+ mNumRows = (int) Math.ceil((double) numChildren / mNumColumns);
+ }
+
+ private int getTotalHeight() {
+ return CHILD_VIEW_EDGE_PX * mNumRows + VIEW_PADDING_PX * (mNumRows + 1);
+ }
+
+ private int getFirstVisibleRowIndex() {
+ return verticalOffset / (CHILD_VIEW_EDGE_PX + VIEW_PADDING_PX);
+ }
+
+ private int getLastVisibleRowIndex() {
+ int lastVisibleRowUncapped =
+ (VIEWPORT_HEIGHT + verticalOffset - 1) / (CHILD_VIEW_EDGE_PX + VIEW_PADDING_PX);
+ return Math.min(lastVisibleRowUncapped, mNumRows - 1);
+ }
+
+ private int getNumItemsInRow(int index) {
+ assertTrue(index >= 0 && index < mNumRows);
+ if (index == mNumRows - 1 && mNumChildren % mNumColumns != 0) {
+ return mNumChildren % mNumColumns;
+ }
+
+ return mNumColumns;
+ }
+
+ @Override
+ public void addOnScrollListener(OnScrollListener listener) {}
+
+ @Override
+ public void removeOnScrollListener(OnScrollListener listener) {}
+
+ @Override
+ public Point createAbsolutePoint(Point relativePoint) {
+ return new Point(
+ relativePoint.x + horizontalOffset, relativePoint.y + verticalOffset);
+ }
+
+ @Override
+ public int getVisibleChildCount() {
+ int childCount = 0;
+ for (int i = getFirstVisibleRowIndex(); i <= getLastVisibleRowIndex(); i++) {
+ childCount += getNumItemsInRow(i);
+ }
+ return childCount;
+ }
+
+ @Override
+ public int getAdapterPositionAt(int index) {
+ return index + mNumColumns * (getFirstVisibleRowIndex());
+ }
+
+ @Override
+ public Rect getAbsoluteRectForChildViewAt(int index) {
+ int adapterPosition = getAdapterPositionAt(index);
+ int rowIndex = adapterPosition / mNumColumns;
+ int columnIndex = adapterPosition % mNumColumns;
+
+ Rect rect = new Rect();
+ rect.top = VIEW_PADDING_PX + rowIndex * (CHILD_VIEW_EDGE_PX + VIEW_PADDING_PX);
+ rect.bottom = rect.top + CHILD_VIEW_EDGE_PX - 1;
+ rect.left = VIEW_PADDING_PX + columnIndex * (CHILD_VIEW_EDGE_PX + VIEW_PADDING_PX);
+ rect.right = rect.left + CHILD_VIEW_EDGE_PX - 1;
+ return rect;
+ }
+
+ @Override
+ public int getTotalChildCount() {
+ return mNumChildren;
+ }
+
+ @Override
+ public int getNumColumns() {
+ return mNumColumns;
+ }
+
+ @Override
+ public int getNumRows() {
+ return mNumRows;
+ }
+ }
+}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/RootsCacheTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/RootsCacheTest.java
index 8c5bac1..1325706 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/RootsCacheTest.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/RootsCacheTest.java
@@ -21,7 +21,8 @@
import com.android.documentsui.BaseActivity.State;
import com.android.documentsui.model.RootInfo;
-import com.google.android.collect.Lists;
+
+import com.google.common.collect.Lists;
import java.util.List;
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/StubProvider.java b/packages/DocumentsUI/tests/src/com/android/documentsui/StubProvider.java
index c2f1762..6a2e03a 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/StubProvider.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/StubProvider.java
@@ -36,8 +36,6 @@
import android.support.annotation.VisibleForTesting;
import android.util.Log;
-import com.google.android.collect.Maps;
-
import libcore.io.IoUtils;
import java.io.File;
@@ -101,7 +99,7 @@
});
}
// Create new roots.
- mRoots = Maps.newHashMap();
+ mRoots = new HashMap<>();
for (String rootId : rootIds) {
final RootInfo rootInfo = new RootInfo(rootId, getSize(rootId));
mRoots.put(rootId, rootInfo);
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/UnitTests.java b/packages/DocumentsUI/tests/src/com/android/documentsui/UnitTests.java
index 4ffe799..0553270 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/UnitTests.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/UnitTests.java
@@ -22,6 +22,7 @@
@RunWith(Suite.class)
@SuiteClasses({
+ BandSelectMatrixTest.class,
MultiSelectManager_SelectionTest.class,
MultiSelectManagerTest.class
})
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 4eb6f88..ead0307 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -29,36 +29,19 @@
import android.content.IntentFilter;
import android.database.ContentObserver;
import android.graphics.Bitmap;
-
-import static android.os.BatteryManager.BATTERY_STATUS_FULL;
-import static android.os.BatteryManager.BATTERY_STATUS_UNKNOWN;
-import static android.os.BatteryManager.BATTERY_HEALTH_UNKNOWN;
-import static android.os.BatteryManager.EXTRA_STATUS;
-import static android.os.BatteryManager.EXTRA_PLUGGED;
-import static android.os.BatteryManager.EXTRA_LEVEL;
-import static android.os.BatteryManager.EXTRA_HEALTH;
-import static android.os.BatteryManager.EXTRA_MAX_CHARGING_CURRENT;
-
+import android.hardware.fingerprint.FingerprintManager;
+import android.hardware.fingerprint.FingerprintManager.AuthenticationCallback;
+import android.hardware.fingerprint.FingerprintManager.AuthenticationResult;
import android.media.AudioManager;
import android.os.BatteryManager;
import android.os.CancellationSignal;
import android.os.Handler;
import android.os.IRemoteCallback;
import android.os.Message;
-import android.os.PowerManager;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.UserHandle;
import android.provider.Settings;
-
-import com.android.internal.telephony.IccCardConstants;
-import com.android.internal.telephony.IccCardConstants.State;
-import com.android.internal.telephony.PhoneConstants;
-import com.android.internal.telephony.TelephonyIntents;
-
-import android.hardware.fingerprint.FingerprintManager;
-import android.hardware.fingerprint.FingerprintManager.AuthenticationCallback;
-import android.hardware.fingerprint.FingerprintManager.AuthenticationResult;
import android.telephony.ServiceState;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
@@ -71,6 +54,12 @@
import com.google.android.collect.Lists;
+import com.android.internal.telephony.IccCardConstants;
+import com.android.internal.telephony.IccCardConstants.State;
+import com.android.internal.telephony.PhoneConstants;
+import com.android.internal.telephony.TelephonyIntents;
+import com.android.internal.widget.LockPatternUtils;
+
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.lang.ref.WeakReference;
@@ -79,6 +68,15 @@
import java.util.List;
import java.util.Map.Entry;
+import static android.os.BatteryManager.BATTERY_HEALTH_UNKNOWN;
+import static android.os.BatteryManager.BATTERY_STATUS_FULL;
+import static android.os.BatteryManager.BATTERY_STATUS_UNKNOWN;
+import static android.os.BatteryManager.EXTRA_HEALTH;
+import static android.os.BatteryManager.EXTRA_LEVEL;
+import static android.os.BatteryManager.EXTRA_MAX_CHARGING_CURRENT;
+import static android.os.BatteryManager.EXTRA_PLUGGED;
+import static android.os.BatteryManager.EXTRA_STATUS;
+
/**
* Watches for updates that may be interesting to the keyguard, and provides
* the up to date information as well as a registration for callbacks that care
@@ -138,6 +136,24 @@
private static final int MSG_SCREEN_TURNED_ON = 331;
private static final int MSG_SCREEN_TURNED_OFF = 332;
+ /** Fingerprint state: Not listening to fingerprint. */
+ private static final int FINGERPRINT_STATE_STOPPED = 0;
+
+ /** Fingerprint state: Listening. */
+ private static final int FINGERPRINT_STATE_RUNNING = 1;
+
+ /**
+ * Fingerprint state: Cancelling and waiting for the confirmation from FingerprintService to
+ * send us the confirmation that cancellation has happened.
+ */
+ private static final int FINGERPRINT_STATE_CANCELLING = 2;
+
+ /**
+ * Fingerprint state: During cancelling we got another request to start listening, so when we
+ * receive the cancellation done signal, we should start listening again.
+ */
+ private static final int FINGERPRINT_STATE_CANCELLING_RESTARTING = 3;
+
private static KeyguardUpdateMonitor sInstance;
private final Context mContext;
@@ -147,9 +163,14 @@
private int mRingMode;
private int mPhoneState;
private boolean mKeyguardIsVisible;
+
+ /**
+ * If true, fingerprint was already authenticated and we don't need to start listening again
+ * until the Keyguard has been dismissed.
+ */
+ private boolean mFingerprintAlreadyAuthenticated;
private boolean mBouncer;
private boolean mBootCompleted;
- private boolean mUserHasAuthenticatedSinceBoot;
// Device provisioning state
private boolean mDeviceProvisioned;
@@ -161,7 +182,8 @@
private SparseIntArray mFailedAttempts = new SparseIntArray();
/** Tracks whether strong authentication hasn't been used since quite some time per user. */
- private ArraySet<Integer> mStrongAuthTimedOut = new ArraySet<>();
+ private ArraySet<Integer> mStrongAuthNotTimedOut = new ArraySet<>();
+ private final StrongAuthTracker mStrongAuthTracker = new StrongAuthTracker();
private final ArrayList<WeakReference<KeyguardUpdateMonitorCallback>>
mCallbacks = Lists.newArrayList();
@@ -174,8 +196,8 @@
private SubscriptionManager mSubscriptionManager;
private AlarmManager mAlarmManager;
private List<SubscriptionInfo> mSubscriptionInfo;
- private boolean mFingerprintDetectionRunning;
private TrustManager mTrustManager;
+ private int mFingerprintRunningState = FINGERPRINT_STATE_STOPPED;
private final Handler mHandler = new Handler() {
@Override
@@ -269,8 +291,6 @@
private static int sCurrentUser;
- private int mFpWakeMode;
-
public synchronized static void setCurrentUser(int currentUser) {
sCurrentUser = currentUser;
}
@@ -373,6 +393,11 @@
private void onFingerprintAuthenticated(int userId) {
mUserFingerprintAuthenticated.put(userId, true);
+
+ // If fingerprint unlocking is allowed, this event will lead to a Keyguard dismiss or to a
+ // wake-up (if Keyguard is not showing), so we don't need to listen until Keyguard is
+ // fully gone.
+ mFingerprintAlreadyAuthenticated = isUnlockingWithFingerprintAllowed();
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
@@ -418,7 +443,7 @@
}
onFingerprintAuthenticated(userId);
} finally {
- setFingerprintRunningDetectionRunning(false);
+ setFingerprintRunningState(FINGERPRINT_STATE_STOPPED);
}
}
@@ -432,7 +457,13 @@
}
private void handleFingerprintError(int msgId, String errString) {
- setFingerprintRunningDetectionRunning(false);
+ if (msgId == FingerprintManager.FINGERPRINT_ERROR_CANCELED
+ && mFingerprintRunningState == FINGERPRINT_STATE_CANCELLING_RESTARTING) {
+ setFingerprintRunningState(FINGERPRINT_STATE_STOPPED);
+ startListeningForFingerprint();
+ } else {
+ setFingerprintRunningState(FINGERPRINT_STATE_STOPPED);
+ }
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
@@ -441,9 +472,15 @@
}
}
- private void setFingerprintRunningDetectionRunning(boolean running) {
- if (running != mFingerprintDetectionRunning) {
- mFingerprintDetectionRunning = running;
+ private void setFingerprintRunningState(int fingerprintRunningState) {
+ boolean wasRunning = mFingerprintRunningState == FINGERPRINT_STATE_RUNNING;
+ boolean isRunning = fingerprintRunningState == FINGERPRINT_STATE_RUNNING;
+ mFingerprintRunningState = fingerprintRunningState;
+
+ // Clients of KeyguardUpdateMonitor don't care about the internal state about the
+ // asynchronousness of the cancel cycle. So only notify them if the actualy running state
+ // has changed.
+ if (wasRunning != isRunning) {
notifyFingerprintRunningStateChanged();
}
}
@@ -452,7 +489,7 @@
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
- cb.onFingerprintRunningStateChanged(mFingerprintDetectionRunning);
+ cb.onFingerprintRunningStateChanged(isFingerprintDetectionRunning());
}
}
}
@@ -471,7 +508,7 @@
}
public boolean isFingerprintDetectionRunning() {
- return mFingerprintDetectionRunning;
+ return mFingerprintRunningState == FINGERPRINT_STATE_RUNNING;
}
private boolean isTrustDisabled(int userId) {
@@ -503,7 +540,12 @@
}
public boolean isUnlockingWithFingerprintAllowed() {
- return mUserHasAuthenticatedSinceBoot && !hasFingerprintUnlockTimedOut(sCurrentUser);
+ return mStrongAuthTracker.isUnlockingWithFingerprintAllowed()
+ && !hasFingerprintUnlockTimedOut(sCurrentUser);
+ }
+
+ public StrongAuthTracker getStrongAuthTracker() {
+ return mStrongAuthTracker;
}
/**
@@ -511,11 +553,11 @@
* while and thus can't unlock with fingerprint, false otherwise
*/
public boolean hasFingerprintUnlockTimedOut(int userId) {
- return mStrongAuthTimedOut.contains(userId);
+ return !mStrongAuthNotTimedOut.contains(userId);
}
public void reportSuccessfulStrongAuthUnlockAttempt() {
- mStrongAuthTimedOut.remove(sCurrentUser);
+ mStrongAuthNotTimedOut.add(sCurrentUser);
scheduleStrongAuthTimeout();
if (mFpm != null) {
byte[] token = null; /* TODO: pass real auth token once fp HAL supports it */
@@ -530,14 +572,14 @@
PendingIntent sender = PendingIntent.getBroadcast(mContext,
sCurrentUser, intent, PendingIntent.FLAG_CANCEL_CURRENT);
mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, when, sender);
- notifyStrongAuthTimedOutChanged(sCurrentUser);
+ notifyStrongAuthStateChanged(sCurrentUser);
}
- private void notifyStrongAuthTimedOutChanged(int userId) {
+ private void notifyStrongAuthStateChanged(int userId) {
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
- cb.onStrongAuthTimeoutExpiredChanged(userId);
+ cb.onStrongAuthStateChanged(userId);
}
}
}
@@ -632,8 +674,8 @@
public void onReceive(Context context, Intent intent) {
if (ACTION_STRONG_AUTH_TIMEOUT.equals(intent.getAction())) {
int userId = intent.getIntExtra(USER_ID, -1);
- mStrongAuthTimedOut.add(userId);
- notifyStrongAuthTimedOutChanged(userId);
+ mStrongAuthNotTimedOut.remove(userId);
+ notifyStrongAuthStateChanged(userId);
}
}
};
@@ -791,6 +833,25 @@
}
}
+ public class StrongAuthTracker extends LockPatternUtils.StrongAuthTracker {
+
+ public boolean isUnlockingWithFingerprintAllowed() {
+ int userId = getCurrentUser();
+ return isFingerprintAllowedForUser(userId);
+ }
+
+ public boolean hasUserAuthenticatedSinceBoot() {
+ int userId = getCurrentUser();
+ return (getStrongAuthForUser(userId)
+ & STRONG_AUTH_REQUIRED_AFTER_BOOT) == 0;
+ }
+
+ @Override
+ public void onStrongAuthRequiredChanged(int userId) {
+ notifyStrongAuthStateChanged(userId);
+ }
+ }
+
public static KeyguardUpdateMonitor getInstance(Context context) {
if (sInstance == null) {
sInstance = new KeyguardUpdateMonitor(context);
@@ -818,6 +879,7 @@
cb.onFinishedGoingToSleep(arg1);
}
}
+ mFingerprintAlreadyAuthenticated = false;
updateFingerprintListeningState();
}
@@ -936,6 +998,7 @@
PERMISSION_SELF, null /* handler */);
mTrustManager = (TrustManager) context.getSystemService(Context.TRUST_SERVICE);
mTrustManager.registerTrustListener(this);
+ new LockPatternUtils(context).registerStrongAuthTracker(mStrongAuthTracker);
mFpm = (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE);
updateFingerprintListeningState();
@@ -943,29 +1006,33 @@
private void updateFingerprintListeningState() {
boolean shouldListenForFingerprint = shouldListenForFingerprint();
- if (mFingerprintDetectionRunning && !shouldListenForFingerprint) {
+ if (mFingerprintRunningState == FINGERPRINT_STATE_RUNNING && !shouldListenForFingerprint) {
stopListeningForFingerprint();
- } else if (!mFingerprintDetectionRunning && shouldListenForFingerprint) {
+ } else if (mFingerprintRunningState != FINGERPRINT_STATE_RUNNING
+ && shouldListenForFingerprint) {
startListeningForFingerprint();
}
}
private boolean shouldListenForFingerprint() {
- return (mKeyguardIsVisible || !mDeviceInteractive) && !mSwitchingUser;
+ return (mKeyguardIsVisible || !mDeviceInteractive) && !mSwitchingUser
+ && !mFingerprintAlreadyAuthenticated;
}
private void startListeningForFingerprint() {
+ if (mFingerprintRunningState == FINGERPRINT_STATE_CANCELLING) {
+ setFingerprintRunningState(FINGERPRINT_STATE_CANCELLING_RESTARTING);
+ return;
+ }
if (DEBUG) Log.v(TAG, "startListeningForFingerprint()");
int userId = ActivityManager.getCurrentUser();
- if (!mFingerprintDetectionRunning && isUnlockWithFingerprintPossible(userId)) {
- mUserHasAuthenticatedSinceBoot = mTrustManager.hasUserAuthenticatedSinceBoot(
- ActivityManager.getCurrentUser());
+ if (isUnlockWithFingerprintPossible(userId)) {
if (mFingerprintCancelSignal != null) {
mFingerprintCancelSignal.cancel();
}
mFingerprintCancelSignal = new CancellationSignal();
mFpm.authenticate(null, mFingerprintCancelSignal, 0, mAuthenticationCallback, null, userId);
- setFingerprintRunningDetectionRunning(true);
+ setFingerprintRunningState(FINGERPRINT_STATE_RUNNING);
}
}
@@ -976,11 +1043,14 @@
private void stopListeningForFingerprint() {
if (DEBUG) Log.v(TAG, "stopListeningForFingerprint()");
- if (isFingerprintDetectionRunning()) {
+ if (mFingerprintRunningState == FINGERPRINT_STATE_RUNNING) {
mFingerprintCancelSignal.cancel();
mFingerprintCancelSignal = null;
+ setFingerprintRunningState(FINGERPRINT_STATE_CANCELLING);
}
- setFingerprintRunningDetectionRunning(false);
+ if (mFingerprintRunningState == FINGERPRINT_STATE_CANCELLING_RESTARTING) {
+ setFingerprintRunningState(FINGERPRINT_STATE_CANCELLING);
+ }
}
private boolean isDeviceProvisionedInSettingsDb() {
@@ -1249,6 +1319,9 @@
cb.onKeyguardVisibilityChangedRaw(isShowing);
}
}
+ if (!isShowing) {
+ mFingerprintAlreadyAuthenticated = false;
+ }
updateFingerprintListeningState();
}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
index 7ca67b0..15ffe9f 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
@@ -233,5 +233,5 @@
* Called when the state that the user hasn't used strong authentication since quite some time
* has changed.
*/
- public void onStrongAuthTimeoutExpiredChanged(int userId) { }
+ public void onStrongAuthStateChanged(int userId) { }
}
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/DocumentLoader.java b/packages/MtpDocumentsProvider/src/com/android/mtp/DocumentLoader.java
index 2353205..c430def 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/DocumentLoader.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/DocumentLoader.java
@@ -30,6 +30,11 @@
import java.util.Date;
import java.util.LinkedList;
+/**
+ * Loader for MTP document.
+ * At the first request, the loader returns only first NUM_INITIAL_ENTRIES. Then it launches
+ * background thread to load the rest documents and caches its result for next requests.
+ */
class DocumentLoader {
static final int NUM_INITIAL_ENTRIES = 10;
static final int NUM_LOADING_ENTRIES = 20;
@@ -37,7 +42,7 @@
private final MtpManager mMtpManager;
private final ContentResolver mResolver;
- private final LinkedList<LoaderTask> mTasks = new LinkedList<LoaderTask>();
+ private final TaskList mTaskList = new TaskList();
private boolean mHasBackgroundThread = false;
DocumentLoader(MtpManager mtpManager, ContentResolver resolver) {
@@ -56,7 +61,7 @@
synchronized Cursor queryChildDocuments(String[] columnNames, Identifier parent)
throws IOException {
- LoaderTask task = findTask(parent);
+ LoaderTask task = mTaskList.findTask(parent);
if (task == null) {
int parentHandle = parent.mObjectHandle;
// Need to pass the special value MtpManager.OBJECT_HANDLE_ROOT_CHILDREN to
@@ -70,11 +75,12 @@
mMtpManager,
parent.mDeviceId,
task.getUnloadedObjectHandles(NUM_INITIAL_ENTRIES)));
+ } else {
+ // Once remove the existing task in order to add it to the head of the list.
+ mTaskList.remove(task);
}
- // Move this task to the head of the list to prioritize it.
- mTasks.remove(task);
- mTasks.addFirst(task);
+ mTaskList.addFirst(task);
if (!task.completed() && !mHasBackgroundThread) {
mHasBackgroundThread = true;
new BackgroundLoaderThread().start();
@@ -84,41 +90,11 @@
}
synchronized void clearCache(int deviceId) {
- int i = 0;
- while (i < mTasks.size()) {
- if (mTasks.get(i).mIdentifier.mDeviceId == deviceId) {
- mTasks.remove(i);
- } else {
- i++;
- }
- }
+ mTaskList.clearTaskForDevice(deviceId);
}
synchronized void clearCache() {
- int i = 0;
- while (i < mTasks.size()) {
- if (mTasks.get(i).completed()) {
- mTasks.remove(i);
- } else {
- i++;
- }
- }
- }
-
- private LoaderTask findTask(Identifier parent) {
- for (int i = 0; i < mTasks.size(); i++) {
- if (mTasks.get(i).mIdentifier.equals(parent))
- return mTasks.get(i);
- }
- return null;
- }
-
- private LoaderTask findUncompletedTask() {
- for (int i = 0; i < mTasks.size(); i++) {
- if (!mTasks.get(i).completed())
- return mTasks.get(i);
- }
- return null;
+ mTaskList.clearCompletedTask();
}
private class BackgroundLoaderThread extends Thread {
@@ -130,7 +106,7 @@
int deviceId;
int[] handles;
synchronized (DocumentLoader.this) {
- task = findUncompletedTask();
+ task = mTaskList.findRunningTask();
if (task == null) {
mHasBackgroundThread = false;
return;
@@ -156,13 +132,53 @@
task.notify(mResolver);
}
} else {
- mTasks.remove(task);
+ mTaskList.remove(task);
}
}
}
}
}
+ private static class TaskList extends LinkedList<LoaderTask> {
+ LoaderTask findTask(Identifier parent) {
+ for (int i = 0; i < size(); i++) {
+ if (get(i).mIdentifier.equals(parent))
+ return get(i);
+ }
+ return null;
+ }
+
+ LoaderTask findRunningTask() {
+ for (int i = 0; i < size(); i++) {
+ if (!get(i).completed())
+ return get(i);
+ }
+ return null;
+ }
+
+ void clearTaskForDevice(int deviceId) {
+ int i = 0;
+ while (i < size()) {
+ if (get(i).mIdentifier.mDeviceId == deviceId) {
+ remove(i);
+ } else {
+ i++;
+ }
+ }
+ }
+
+ void clearCompletedTask() {
+ int i = 0;
+ while (i < size()) {
+ if (get(i).completed()) {
+ remove(i);
+ } else {
+ i++;
+ }
+ }
+ }
+ }
+
private static class LoaderTask {
final Identifier mIdentifier;
final int[] mObjectHandles;
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocument.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocument.java
index 98775b3..7126694 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocument.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocument.java
@@ -32,6 +32,7 @@
private final Date mDateModified;
private final int mSize;
private final int mThumbSize;
+ private final boolean mReadOnly;
/**
* Constructor for root document.
@@ -40,9 +41,10 @@
this(DUMMY_HANDLE_FOR_ROOT,
0x3001, // Directory.
root.mDescription,
- null, // Unknown,
+ null, // Unknown name.
(int) Math.min(root.mMaxCapacity - root.mFreeSpace, Integer.MAX_VALUE),
- 0);
+ 0, // Total size.
+ true); // Writable.
}
MtpDocument(MtpObjectInfo objectInfo) {
@@ -51,7 +53,8 @@
objectInfo.getName(),
objectInfo.getDateModified() != 0 ? new Date(objectInfo.getDateModified()) : null,
objectInfo.getCompressedSize(),
- objectInfo.getThumbCompressedSize());
+ objectInfo.getThumbCompressedSize(),
+ objectInfo.getProtectionStatus() != 0);
}
MtpDocument(int objectHandle,
@@ -59,13 +62,15 @@
String name,
Date dateModified,
int size,
- int thumbSize) {
+ int thumbSize,
+ boolean readOnly) {
this.mObjectHandle = objectHandle;
this.mFormat = format;
this.mName = name;
this.mDateModified = dateModified;
this.mSize = size;
this.mThumbSize = thumbSize;
+ this.mReadOnly = readOnly;
}
void addToCursor(Identifier rootIdentifier, MatrixCursor.RowBuilder builder) {
@@ -82,7 +87,7 @@
builder.add(Document.COLUMN_DOCUMENT_ID, identifier.toDocumentId());
builder.add(Document.COLUMN_DISPLAY_NAME, mName);
- builder.add(Document.COLUMN_MIME_TYPE, getMimeType());
+ builder.add(Document.COLUMN_MIME_TYPE, formatTypeToMimeType(mFormat));
builder.add(
Document.COLUMN_LAST_MODIFIED,
mDateModified != null ? mDateModified.getTime() : null);
@@ -90,9 +95,9 @@
builder.add(Document.COLUMN_SIZE, mSize);
}
- private String getMimeType() {
+ static String formatTypeToMimeType(int format) {
// TODO: Add complete list of mime types.
- switch (mFormat) {
+ switch (format) {
case 0x3001:
return DocumentsContract.Document.MIME_TYPE_DIR;
case 0x3009:
@@ -100,7 +105,21 @@
case 0x3801:
return "image/jpeg";
default:
- return "";
+ return "application/octet-stream";
+ }
+ }
+
+ static int mimeTypeToFormatType(String mimeType) {
+ // TODO: Add complete list of mime types.
+ switch (mimeType.toLowerCase()) {
+ case Document.MIME_TYPE_DIR:
+ return 0x3001;
+ case "audio/mp3":
+ return 0x3009;
+ case "image/jpeg":
+ return 0x3801;
+ default:
+ return 0x3000; // Undefined object.
}
}
}
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
index 61b9fc5..031cc07 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
@@ -96,7 +96,7 @@
final Identifier rootIdentifier = new Identifier(root.mDeviceId, root.mStorageId);
final MatrixCursor.RowBuilder builder = cursor.newRow();
builder.add(Root.COLUMN_ROOT_ID, rootIdentifier.toRootId());
- builder.add(Root.COLUMN_FLAGS, Root.FLAG_SUPPORTS_IS_CHILD);
+ builder.add(Root.COLUMN_FLAGS, Root.FLAG_SUPPORTS_IS_CHILD | Root.FLAG_SUPPORTS_CREATE);
builder.add(Root.COLUMN_TITLE, root.mDescription);
builder.add(
Root.COLUMN_DOCUMENT_ID,
@@ -214,6 +214,24 @@
mDocumentLoader.clearCache();
}
+ @Override
+ public String createDocument(String parentDocumentId, String mimeType, String displayName)
+ throws FileNotFoundException {
+ try {
+ final Identifier parentId = Identifier.createFromDocumentId(parentDocumentId);
+ final int objectHandle = mMtpManager.createDocument(
+ parentId.mDeviceId, parentId.mStorageId, parentId.mObjectHandle, mimeType,
+ displayName);
+ final String documentId = new Identifier(parentId.mDeviceId, parentId.mStorageId,
+ objectHandle).toDocumentId();
+ notifyChildDocumentsChange(parentDocumentId);
+ return documentId;
+ } catch (IOException error) {
+ Log.e(TAG, error.getMessage());
+ throw new FileNotFoundException(error.getMessage());
+ }
+ }
+
void openDevice(int deviceId) throws IOException {
mMtpManager.openDevice(deviceId);
mRootScanner.scanNow();
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java
index 3afc173..27ba794 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java
@@ -21,7 +21,10 @@
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbManager;
import android.mtp.MtpDevice;
+import android.mtp.MtpObjectInfo;
import android.os.ParcelFileDescriptor;
+import android.provider.DocumentsContract.Document;
+import android.provider.DocumentsContract;
import android.util.SparseArray;
import java.io.FileNotFoundException;
@@ -134,6 +137,22 @@
}
}
+ synchronized int createDocument(int deviceId, int storageId, int parentObjectHandle,
+ String mimeType, String name) throws IOException {
+ final MtpDevice device = getDevice(deviceId);
+ final MtpObjectInfo objectInfo = new MtpObjectInfo.Builder()
+ .setName(name)
+ .setStorageId(storageId)
+ .setParent(parentObjectHandle)
+ .setFormat(MtpDocument.mimeTypeToFormatType(mimeType))
+ .build();
+ final MtpObjectInfo result = device.sendObjectInfo(objectInfo);
+ if (result == null) {
+ throw new IOException("Failed to create a document");
+ }
+ return result.getObjectHandle();
+ }
+
synchronized int getParent(int deviceId, int objectHandle) throws IOException {
final MtpDevice device = getDevice(deviceId);
final int result = (int) device.getParent(objectHandle);
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/DocumentLoaderTest.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/DocumentLoaderTest.java
index 5504147..1e015bd 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/DocumentLoaderTest.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/DocumentLoaderTest.java
@@ -91,7 +91,8 @@
"file" + objectHandle,
new Date(),
1024,
- 0 /* thumbnail size */));
+ 0 /* thumbnail size */,
+ false /* not read only */));
}
manager.setObjectHandles(0, 0, MtpManager.OBJECT_HANDLE_ROOT_CHILDREN, childDocuments);
}
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java
index c1da59f..f06e2ff 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java
@@ -210,7 +210,8 @@
"image.jpg" /* display name */,
new Date(1422716400000L) /* modified date */,
1024 * 1024 * 5 /* file size */,
- 1024 * 50 /* thumbnail size */));
+ 1024 * 50 /* thumbnail size */,
+ true /* read only */));
final Cursor cursor = mProvider.queryDocument("0_1_2", null);
assertEquals(1, cursor.getCount());
@@ -257,7 +258,8 @@
"image.jpg" /* display name */,
new Date(0) /* modified date */,
1024 * 1024 * 5 /* file size */,
- 1024 * 50 /* thumbnail size */));
+ 1024 * 50 /* thumbnail size */,
+ true /* read only */));
final Cursor cursor = mProvider.queryChildDocuments("0_0_0", null, null);
assertEquals(1, cursor.getCount());
@@ -302,7 +304,8 @@
"image.jpg" /* display name */,
new Date(1422716400000L) /* modified date */,
1024 * 1024 * 5 /* file size */,
- 1024 * 50 /* thumbnail size */));
+ 1024 * 50 /* thumbnail size */,
+ false /* not read only */));
mMtpManager.setParent(0, 1, 2);
mProvider.deleteDocument("0_0_1");
assertEquals(1, mResolver.getChangeCount(
diff --git a/packages/SettingsLib/src/com/android/settingslib/TetherUtil.java b/packages/SettingsLib/src/com/android/settingslib/TetherUtil.java
index 096a5c4..f52d755 100644
--- a/packages/SettingsLib/src/com/android/settingslib/TetherUtil.java
+++ b/packages/SettingsLib/src/com/android/settingslib/TetherUtil.java
@@ -54,29 +54,7 @@
public static boolean setWifiTethering(boolean enable, Context context) {
final WifiManager wifiManager =
(WifiManager) context.getSystemService(Context.WIFI_SERVICE);
- final ContentResolver cr = context.getContentResolver();
- /**
- * Disable Wifi if enabling tethering
- */
- int wifiState = wifiManager.getWifiState();
- if (enable && ((wifiState == WifiManager.WIFI_STATE_ENABLING) ||
- (wifiState == WifiManager.WIFI_STATE_ENABLED))) {
- wifiManager.setWifiEnabled(false);
- Settings.Global.putInt(cr, Settings.Global.WIFI_SAVED_STATE, 1);
- }
-
- boolean success = wifiManager.setWifiApEnabled(null, enable);
- /**
- * If needed, restore Wifi on tether disable
- */
- if (!enable) {
- int wifiSavedState = Settings.Global.getInt(cr, Settings.Global.WIFI_SAVED_STATE, 0);
- if (wifiSavedState == 1) {
- wifiManager.setWifiEnabled(true);
- Settings.Global.putInt(cr, Settings.Global.WIFI_SAVED_STATE, 0);
- }
- }
- return success;
+ return wifiManager.setWifiApEnabled(null, enable);
}
public static boolean isWifiTetherEnabled(Context context) {
diff --git a/packages/SystemUI/res/anim/navbar_fade_in.xml b/packages/SystemUI/res/anim/navbar_fade_in.xml
index e3429e6..7051730 100644
--- a/packages/SystemUI/res/anim/navbar_fade_in.xml
+++ b/packages/SystemUI/res/anim/navbar_fade_in.xml
@@ -19,4 +19,5 @@
android:fromAlpha="0.0"
android:toAlpha="1.0"
android:interpolator="@android:interpolator/linear_out_slow_in"
+ android:startDelay="32"
android:duration="200"/>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 918d856..8b3f2d8 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1140,4 +1140,9 @@
<!-- Displayed when user launches an app that was uninstalled [CHAR LIMIT=NONE] -->
<string name="activity_not_found">Application is not installed on your device</string>
+ <!-- Name of setting to show clock seconds [CHAR LIMIT=40] -->
+ <string name="clock_seconds">Show clock seconds</string>
+ <!-- Description of setting to show clock seconds [CHAR LIMIT=NONE] -->
+ <string name="clock_seconds_desc">Show clock seconds in the status bar. May impact battery life.</string>
+
</resources>
diff --git a/packages/SystemUI/res/xml/tuner_prefs.xml b/packages/SystemUI/res/xml/tuner_prefs.xml
index 3a41c3c..beb863c 100644
--- a/packages/SystemUI/res/xml/tuner_prefs.xml
+++ b/packages/SystemUI/res/xml/tuner_prefs.xml
@@ -72,10 +72,16 @@
android:summary="@string/show_battery_percentage_summary"
android:persistent="false" />
+ <com.android.systemui.tuner.TunerSwitch
+ android:key="clock_seconds"
+ android:title="@string/clock_seconds"
+ android:summary="@string/clock_seconds_desc" />
+
<Preference
android:key="demo_mode"
android:title="@string/demo_mode" />
+ <!-- Warning, this goes last. -->
<Preference
android:summary="@string/tuner_persistent_warning"
android:selectable="false" />
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
index 328ee35..36efead 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
@@ -256,6 +256,8 @@
private void continuePulsing(int reason) {
if (mHost.isPulsingBlocked()) {
+ mPulsing = false;
+ mWakeLock.release();
return;
}
mHost.pulseWhileDozing(new DozeHost.PulseCallback() {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index a28e188..12d5f36 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -532,7 +532,7 @@
int currentUser = ActivityManager.getCurrentUser();
if ((mUpdateMonitor.getUserTrustIsManaged(currentUser)
|| mUpdateMonitor.isUnlockWithFingerprintPossible(currentUser))
- && !mTrustManager.hasUserAuthenticatedSinceBoot(currentUser)) {
+ && !mUpdateMonitor.getStrongAuthTracker().hasUserAuthenticatedSinceBoot()) {
return KeyguardSecurityView.PROMPT_REASON_RESTART;
} else if (mUpdateMonitor.isUnlockWithFingerprintPossible(currentUser)
&& mUpdateMonitor.hasFingerprintUnlockTimedOut(currentUser)) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
index 947c19c..00ac5f9 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -16,6 +16,7 @@
package com.android.systemui.recents.views;
+import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.TaskStackBuilder;
import android.content.Context;
@@ -31,6 +32,8 @@
import android.provider.Settings;
import android.util.AttributeSet;
import android.util.Log;
+import android.util.SparseArray;
+import android.view.AppTransitionAnimationSpec;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowInsets;
@@ -60,6 +63,8 @@
private static final String TAG = "RecentsView";
+ private static final boolean ADD_HEADER_BITMAP = true;
+
/** The RecentsView callbacks */
public interface RecentsViewCallbacks {
public void onTaskViewClicked();
@@ -443,62 +448,158 @@
}
}
- private void postDrawHeaderThumbnailTransitionRunnable(final TaskView tv, final int offsetX,
- final int offsetY, final TaskViewTransform transform,
+ private void postDrawHeaderThumbnailTransitionRunnable(final TaskStackView view,
+ final TaskView clickedView, final int offsetX, final int offsetY,
+ final float stackScroll,
final ActivityOptions.OnAnimationStartedListener animStartedListener) {
Runnable r = new Runnable() {
@Override
public void run() {
- // Disable any focused state before we draw the header
- if (tv.isFocusedTask()) {
- tv.unsetFocusedTask();
- }
+ overrideDrawHeaderThumbnailTransition(view, clickedView, offsetX, offsetY,
+ stackScroll, animStartedListener);
- float scale = tv.getScaleX();
- int fromHeaderWidth = (int) (tv.mHeaderView.getMeasuredWidth() * scale);
- int fromHeaderHeight = (int) (tv.mHeaderView.getMeasuredHeight() * scale);
-
- Bitmap b = Bitmap.createBitmap(fromHeaderWidth, fromHeaderHeight,
- Bitmap.Config.ARGB_8888);
- if (Constants.DebugFlags.App.EnableTransitionThumbnailDebugMode) {
- b.eraseColor(0xFFff0000);
- } else {
- Canvas c = new Canvas(b);
- c.scale(tv.getScaleX(), tv.getScaleY());
- tv.mHeaderView.draw(c);
- c.setBitmap(null);
- }
- b = b.createAshmemBitmap();
- int[] pts = new int[2];
- tv.getLocationOnScreen(pts);
- try {
- WindowManagerGlobal.getWindowManagerService()
- .overridePendingAppTransitionAspectScaledThumb(b,
- pts[0] + offsetX,
- pts[1] + offsetY,
- transform.rect.width(),
- transform.rect.height(),
- new IRemoteCallback.Stub() {
- @Override
- public void sendResult(Bundle data)
- throws RemoteException {
- post(new Runnable() {
- @Override
- public void run() {
- if (animStartedListener != null) {
- animStartedListener.onAnimationStarted();
- }
- }
- });
- }
- }, true);
- } catch (RemoteException e) {
- Log.w(TAG, "Error overriding app transition", e);
- }
}
};
+
mCb.runAfterPause(r);
}
+
+ private void overrideDrawHeaderThumbnailTransition(TaskStackView stackView,
+ TaskView clickedTask, int offsetX, int offsetY, float stackScroll,
+ final ActivityOptions.OnAnimationStartedListener animStartedListener) {
+ List<AppTransitionAnimationSpec> specs = getAppTransitionAnimationSpecs(stackView,
+ clickedTask, offsetX, offsetY, stackScroll);
+ if (specs == null) {
+ return;
+ }
+
+ IRemoteCallback.Stub callback = new IRemoteCallback.Stub() {
+ @Override
+ public void sendResult(Bundle data) throws RemoteException {
+ post(new Runnable() {
+ @Override
+ public void run() {
+ if (animStartedListener != null) {
+ animStartedListener.onAnimationStarted();
+ }
+ }
+ });
+ }
+ };
+
+ AppTransitionAnimationSpec[] specsArray =
+ new AppTransitionAnimationSpec[specs.size()];
+ try {
+ WindowManagerGlobal.getWindowManagerService().overridePendingAppTransitionMultiThumb(
+ specs.toArray(specsArray), callback, true /* scaleUp */);
+
+ } catch (RemoteException e) {
+ Log.w(TAG, "Error overriding app transition", e);
+ }
+ }
+
+ private List<AppTransitionAnimationSpec> getAppTransitionAnimationSpecs(TaskStackView stackView,
+ TaskView clickedTask, int offsetX, int offsetY, float stackScroll) {
+ final int targetStackId = clickedTask.getTask().key.stackId;
+ if (targetStackId != ActivityManager.FREEFORM_WORKSPACE_STACK_ID
+ && targetStackId != ActivityManager.FULLSCREEN_WORKSPACE_STACK_ID) {
+ return null;
+ }
+ // If this is a full screen stack, the transition will be towards the single, full screen
+ // task. We only need the transition spec for this task.
+ List<AppTransitionAnimationSpec> specs = new ArrayList<>();
+ if (targetStackId == ActivityManager.FULLSCREEN_WORKSPACE_STACK_ID) {
+ specs.add(createThumbnailHeaderAnimationSpec(
+ stackView, offsetX, offsetY, stackScroll, clickedTask,
+ clickedTask.getTask().key.id, ADD_HEADER_BITMAP));
+ return specs;
+ }
+ // This is a free form stack or full screen stack, so there will be multiple windows
+ // animating from thumbnails. We need transition animation specs for all of them.
+
+ // We will use top and bottom task views as a base for tasks, that aren't visible on the
+ // screen. This is necessary for cascade recents list, where some of the tasks might be
+ // hidden.
+ List<TaskView> taskViews = stackView.getTaskViews();
+ int childCount = taskViews.size();
+ TaskView topChild = taskViews.get(0);
+ TaskView bottomChild = taskViews.get(childCount - 1);
+ SparseArray<TaskView> taskViewsByTaskId = new SparseArray<>();
+ for (int i = 0; i < childCount; i++) {
+ TaskView taskView = taskViews.get(i);
+ taskViewsByTaskId.put(taskView.getTask().key.id, taskView);
+ }
+
+ TaskStack stack = stackView.getStack();
+ // We go through all tasks now and for each generate transition animation spec. If there is
+ // a view associated with a task, we use that view as a base for the animation. If there
+ // isn't, we use bottom or top view, depending on which one would be closer to the task
+ // view if it existed.
+ ArrayList<Task> tasks = stack.getTasks();
+ boolean passedClickedTask = false;
+ for (int i = 0, n = tasks.size(); i < n; i++) {
+ Task task = tasks.get(i);
+ TaskView taskView = taskViewsByTaskId.get(task.key.id);
+ if (taskView != null) {
+ specs.add(createThumbnailHeaderAnimationSpec(stackView, offsetX, offsetY,
+ stackScroll, taskView, taskView.getTask().key.id, ADD_HEADER_BITMAP));
+ if (taskView == clickedTask) {
+ passedClickedTask = true;
+ }
+ } else {
+ taskView = passedClickedTask ? bottomChild : topChild;
+ specs.add(createThumbnailHeaderAnimationSpec(stackView, offsetX, offsetY,
+ stackScroll, taskView, task.key.id, !ADD_HEADER_BITMAP));
+ }
+ }
+
+ return specs;
+ }
+
+ private AppTransitionAnimationSpec createThumbnailHeaderAnimationSpec(TaskStackView stackView,
+ int offsetX, int offsetY, float stackScroll, TaskView tv, int taskId,
+ boolean addHeaderBitmap) {
+ // Disable any focused state before we draw the header
+ // Upfront the processing of the thumbnail
+ if (tv.isFocusedTask()) {
+ tv.unsetFocusedTask();
+ }
+ TaskViewTransform transform = new TaskViewTransform();
+ transform = stackView.getStackAlgorithm().getStackTransform(tv.mTask, stackScroll,
+ transform, null);
+
+ float scale = tv.getScaleX();
+ int fromHeaderWidth = (int) (tv.mHeaderView.getMeasuredWidth() * scale);
+ int fromHeaderHeight = (int) (tv.mHeaderView.getMeasuredHeight() * scale);
+
+ Bitmap b = null;
+ if (addHeaderBitmap) {
+ b = Bitmap.createBitmap(fromHeaderWidth, fromHeaderHeight,
+ Bitmap.Config.ARGB_8888);
+
+ if (Constants.DebugFlags.App.EnableTransitionThumbnailDebugMode) {
+ b.eraseColor(0xFFff0000);
+ } else {
+ Canvas c = new Canvas(b);
+ c.scale(tv.getScaleX(), tv.getScaleY());
+ tv.mHeaderView.draw(c);
+ c.setBitmap(null);
+
+ }
+ b = b.createAshmemBitmap();
+ }
+
+ int[] pts = new int[2];
+ tv.getLocationOnScreen(pts);
+
+ final int left = pts[0] + offsetX;
+ final int top = pts[1] + offsetY;
+ final Rect rect = new Rect(left, top, left + transform.rect.width(),
+ top + transform.rect.height());
+
+ return new AppTransitionAnimationSpec(taskId, b, rect);
+ }
+
/**** TaskStackView.TaskStackCallbacks Implementation ****/
@Override
@@ -521,12 +622,10 @@
// and then offset to the expected transform rect, but bound this to just
// outside the display rect (to ensure we don't animate from too far away)
sourceView = stackView;
- transform = stackView.getStackAlgorithm().getStackTransform(task, stackScroll, transform, null);
offsetX = transform.rect.left;
offsetY = mConfig.displayRect.height();
} else {
sourceView = tv.mThumbnailView;
- transform = stackView.getStackAlgorithm().getStackTransform(task, stackScroll, transform, null);
}
// Compute the thumbnail to scale up from
@@ -553,10 +652,8 @@
}
};
}
- if (tv != null) {
- postDrawHeaderThumbnailTransitionRunnable(tv, offsetX, offsetY, transform,
- animStartedListener);
- }
+ postDrawHeaderThumbnailTransitionRunnable(stackView, tv, offsetX, offsetY, stackScroll,
+ animStartedListener);
if (mConfig.multiStackEnabled) {
opts = ActivityOptions.makeCustomAnimation(sourceView.getContext(),
R.anim.recents_from_unknown_enter,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index a55256d..3a96626 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -135,6 +135,7 @@
protected static final int MSG_CANCEL_PRELOAD_RECENT_APPS = 1023;
protected static final int MSG_SHOW_NEXT_AFFILIATED_TASK = 1024;
protected static final int MSG_SHOW_PREV_AFFILIATED_TASK = 1025;
+ protected static final int MSG_SHOW_KEYBOARD_SHORTCUTS_MENU = 1026;
protected static final boolean ENABLE_HEADS_UP = true;
// scores above this threshold should be displayed in heads up mode.
@@ -1066,6 +1067,13 @@
mHandler.sendEmptyMessage(msg);
}
+ @Override
+ public void showKeyboardShortcutsMenu() {
+ int msg = MSG_SHOW_KEYBOARD_SHORTCUTS_MENU;
+ mHandler.removeMessages(msg);
+ mHandler.sendEmptyMessage(msg);
+ }
+
/** Jumps to the next affiliated task in the group. */
public void showNextAffiliatedTask() {
int msg = MSG_SHOW_NEXT_AFFILIATED_TASK;
@@ -1143,6 +1151,10 @@
}
}
+ protected void showKeyboardShortcuts() {
+ Toast.makeText(mContext, "Show keyboard shortcuts screen", Toast.LENGTH_LONG).show();
+ }
+
protected void cancelPreloadingRecents() {
if (mRecents != null) {
mRecents.cancelPreloadingRecents();
@@ -1253,6 +1265,9 @@
case MSG_SHOW_PREV_AFFILIATED_TASK:
showRecentsPreviousAffiliatedTask();
break;
+ case MSG_SHOW_KEYBOARD_SHORTCUTS_MENU:
+ showKeyboardShortcuts();
+ break;
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index a1b07b5..d0cd6cb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -64,6 +64,7 @@
private static final int MSG_APP_TRANSITION_STARTING = 21 << MSG_SHIFT;
private static final int MSG_ASSIST_DISCLOSURE = 22 << MSG_SHIFT;
private static final int MSG_START_ASSIST = 23 << MSG_SHIFT;
+ private static final int MSG_SHOW_KEYBOARD_SHORTCUTS = 24 << MSG_SHIFT;
public static final int FLAG_EXCLUDE_NONE = 0;
public static final int FLAG_EXCLUDE_SEARCH_PANEL = 1 << 0;
@@ -98,6 +99,7 @@
public void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey);
public void toggleRecentApps();
public void preloadRecentApps();
+ public void showKeyboardShortcutsMenu();
public void cancelPreloadRecentApps();
public void setWindowState(int window, int state);
public void buzzBeepBlinked();
@@ -224,6 +226,14 @@
}
}
+ @Override
+ public void showKeyboardShortcutsMenu() {
+ synchronized (mList) {
+ mHandler.removeMessages(MSG_SHOW_KEYBOARD_SHORTCUTS);
+ mHandler.obtainMessage(MSG_SHOW_KEYBOARD_SHORTCUTS).sendToTarget();
+ }
+ }
+
public void setWindowState(int window, int state) {
synchronized (mList) {
// don't coalesce these
@@ -360,6 +370,9 @@
case MSG_CANCEL_PRELOAD_RECENT_APPS:
mCallbacks.cancelPreloadRecentApps();
break;
+ case MSG_SHOW_KEYBOARD_SHORTCUTS:
+ mCallbacks.showKeyboardShortcutsMenu();
+ break;
case MSG_SET_WINDOW_STATE:
mCallbacks.setWindowState(msg.arg1, msg.arg2);
break;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
index 4d3e57e..3ff69c9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
@@ -104,13 +104,11 @@
* Aborts pulsing immediately.
*/
public void abortPulsing() {
- mHandler.removeCallbacks(mPulseIn);
- abortAnimations();
+ cancelPulsing();
if (mDozing) {
mScrimController.setDozeBehindAlpha(1f);
mScrimController.setDozeInFrontAlpha(1f);
}
- mPulseCallback = null;
}
public void onScreenTurnedOn() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index 4da9acd..579889d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -649,7 +649,7 @@
}
@Override
- public void onStrongAuthTimeoutExpiredChanged(int userId) {
+ public void onStrongAuthStateChanged(int userId) {
mLockIcon.update();
}
};
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
index 676f114..cbd23bb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
@@ -54,7 +54,7 @@
private KeyguardUpdateMonitorCallback mUpdateMonitorCallback =
new KeyguardUpdateMonitorCallback() {
@Override
- public void onStrongAuthTimeoutExpiredChanged(int userId) {
+ public void onStrongAuthStateChanged(int userId) {
mBouncerPromptReason = mCallback.getBouncerPromptReason();
}
};
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarApps.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarApps.java
index d74c5b0..cb5c125 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarApps.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarApps.java
@@ -20,7 +20,6 @@
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityOptions;
-import android.app.AppGlobals;
import android.content.BroadcastReceiver;
import android.content.ClipData;
import android.content.ClipDescription;
@@ -29,13 +28,10 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
-import android.content.pm.ActivityInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
import android.graphics.Rect;
import android.os.Bundle;
-import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.AttributeSet;
@@ -49,6 +45,7 @@
import android.widget.LinearLayout;
import android.widget.Toast;
+import com.android.internal.content.PackageMonitor;
import com.android.systemui.R;
import java.util.List;
@@ -75,6 +72,8 @@
private final PackageManager mPackageManager;
private final UserManager mUserManager;
private final LayoutInflater mLayoutInflater;
+ private final AppPackageMonitor mAppPackageMonitor;
+
// This view has two roles:
// 1) If the drag started outside the pinned apps list, it is a placeholder icon with a null
@@ -106,6 +105,7 @@
mPackageManager = context.getPackageManager();
mUserManager = (UserManager) getContext().getSystemService(Context.USER_SERVICE);
mLayoutInflater = LayoutInflater.from(context);
+ mAppPackageMonitor = new AppPackageMonitor();
// Dragging an icon removes and adds back the dragged icon. Use the layout transitions to
// trigger animation. By default all transitions animate, so turn off the unneeded ones.
@@ -121,6 +121,76 @@
setLayoutTransition(transition);
}
+ // Monitor that catches events like "app uninstalled".
+ private class AppPackageMonitor extends PackageMonitor {
+ @Override
+ public void onPackageRemoved(String packageName, int uid) {
+ postRemoveIfUnlauncheable(packageName, new UserHandle(getChangingUserId()));
+ super.onPackageRemoved(packageName, uid);
+ }
+
+ @Override
+ public void onPackageModified(String packageName) {
+ postRemoveIfUnlauncheable(packageName, new UserHandle(getChangingUserId()));
+ super.onPackageModified(packageName);
+ }
+
+ @Override
+ public void onPackagesAvailable(String[] packages) {
+ if (isReplacing()) {
+ UserHandle user = new UserHandle(getChangingUserId());
+
+ for (String packageName : packages) {
+ postRemoveIfUnlauncheable(packageName, user);
+ }
+ }
+ super.onPackagesAvailable(packages);
+ }
+
+ @Override
+ public void onPackagesUnavailable(String[] packages) {
+ if (!isReplacing()) {
+ UserHandle user = new UserHandle(getChangingUserId());
+
+ for (String packageName : packages) {
+ postRemoveIfUnlauncheable(packageName, user);
+ }
+ }
+ super.onPackagesUnavailable(packages);
+ }
+ }
+
+ private void postRemoveIfUnlauncheable(final String packageName, final UserHandle user) {
+ // This method doesn't necessarily get called in the main thread. Redirect the call into
+ // the main thread.
+ post(new Runnable() {
+ @Override
+ public void run() {
+ if (!isAttachedToWindow()) return;
+ removeIfUnlauncheable(packageName, user);
+ }
+ });
+ }
+
+ private void removeIfUnlauncheable(String packageName, UserHandle user) {
+ long appUserSerialNumber = mUserManager.getSerialNumberForUser(user);
+
+ // Remove icons for all apps that match a package that perhaps became unlauncheable.
+ for(int i = sAppsModel.getAppCount() - 1; i >= 0; --i) {
+ AppInfo appInfo = sAppsModel.getApp(i);
+ if (appInfo.getUserSerialNumber() != appUserSerialNumber) continue;
+
+ ComponentName appComponentName = appInfo.getComponentName();
+ if (!appComponentName.getPackageName().equals(packageName)) continue;
+
+ if (sAppsModel.buildAppLaunchIntent(appComponentName, user) != null) continue;
+
+ removeViewAt(i);
+ sAppsModel.removeApp(i);
+ sAppsModel.savePrefs();
+ }
+ }
+
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
@@ -145,12 +215,15 @@
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_USER_SWITCHED);
mContext.registerReceiver(mBroadcastReceiver, filter);
+
+ mAppPackageMonitor.register(mContext, null, UserHandle.ALL, true);
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
mContext.unregisterReceiver(mBroadcastReceiver);
+ mAppPackageMonitor.unregister();
}
/**
@@ -470,7 +543,6 @@
ComponentName component = appInfo.getComponentName();
long appUserSerialNumber = appInfo.getUserSerialNumber();
-
UserHandle appUser = mUserManager.getUserForSerialNumber(appUserSerialNumber);
if (appUser == null) {
Toast.makeText(getContext(), R.string.activity_not_found, Toast.LENGTH_SHORT).show();
@@ -478,7 +550,12 @@
" because its user doesn't exist.");
return;
}
- int appUserId = appUser.getIdentifier();
+
+ Intent launchIntent = sAppsModel.buildAppLaunchIntent(component, appUser);
+ if (launchIntent == null) {
+ Toast.makeText(getContext(), R.string.activity_not_found, Toast.LENGTH_SHORT).show();
+ return;
+ }
// Play a scale-up animation while launching the activity.
// TODO: Consider playing a different animation, or no animation, if the activity is
@@ -489,54 +566,9 @@
ActivityOptions opts =
ActivityOptions.makeScaleUpAnimation(v, 0, 0, v.getWidth(), v.getHeight());
Bundle optsBundle = opts.toBundle();
-
- // Launch the activity. This code is based on LauncherAppsService.startActivityAsUser code.
- Intent launchIntent = new Intent(Intent.ACTION_MAIN);
- launchIntent.addCategory(Intent.CATEGORY_LAUNCHER);
launchIntent.setSourceBounds(sourceBounds);
- launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- launchIntent.setPackage(component.getPackageName());
- IPackageManager pm = AppGlobals.getPackageManager();
- try {
- ActivityInfo info = pm.getActivityInfo(component, 0, appUserId);
- if (info == null) {
- Toast.makeText(getContext(), R.string.activity_not_found, Toast.LENGTH_SHORT).show();
- Log.e(TAG, "Can't start activity " + component + " because it's not installed.");
- return;
- }
-
- if (!info.exported) {
- Toast.makeText(getContext(), R.string.activity_not_found, Toast.LENGTH_SHORT).show();
- Log.e(TAG, "Can't start activity " + component + " because it doesn't have 'exported' attribute.");
- return;
- }
- } catch (RemoteException e) {
- Toast.makeText(getContext(), R.string.activity_not_found, Toast.LENGTH_SHORT).show();
- Log.e(TAG, "Failed to get activity info for " + component, e);
- return;
- }
-
- // Check that the component actually has Intent.CATEGORY_LAUCNCHER
- // as calling startActivityAsUser ignores the category and just
- // resolves based on the component if present.
- List<ResolveInfo> apps = getContext().getPackageManager().queryIntentActivitiesAsUser(launchIntent,
- 0 /* flags */, appUserId);
- final int size = apps.size();
- for (int i = 0; i < size; ++i) {
- ActivityInfo activityInfo = apps.get(i).activityInfo;
- if (activityInfo.packageName.equals(component.getPackageName()) &&
- activityInfo.name.equals(component.getClassName())) {
- // Found an activity with category launcher that matches
- // this component so ok to launch.
- launchIntent.setComponent(component);
- mContext.startActivityAsUser(launchIntent, optsBundle, appUser);
- return;
- }
- }
-
- Toast.makeText(getContext(), R.string.activity_not_found, Toast.LENGTH_SHORT).show();
- Log.e(TAG, "Attempt to launch activity without category Intent.CATEGORY_LAUNCHER " + component);
+ mContext.startActivityAsUser(launchIntent, optsBundle, appUser);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarAppsModel.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarAppsModel.java
index b8764cf..c4c31fd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarAppsModel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarAppsModel.java
@@ -16,16 +16,23 @@
package com.android.systemui.statusbar.phone;
+import android.app.AppGlobals;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
+import android.content.pm.ActivityInfo;
+import android.content.pm.IPackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.UserInfo;
+import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
+import android.util.Log;
import android.util.Slog;
+import com.android.internal.annotations.VisibleForTesting;
+
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
@@ -94,6 +101,58 @@
}
}
+ @VisibleForTesting
+ protected IPackageManager getPackageManager() {
+ return AppGlobals.getPackageManager();
+ }
+
+ // Returns a launch intent for a given component, or null if the component is unlauncheable.
+ public Intent buildAppLaunchIntent(ComponentName component, UserHandle appUser) {
+ int appUserId = appUser.getIdentifier();
+
+ // This code is based on LauncherAppsService.startActivityAsUser code.
+ Intent launchIntent = new Intent(Intent.ACTION_MAIN);
+ launchIntent.addCategory(Intent.CATEGORY_LAUNCHER);
+ launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ launchIntent.setPackage(component.getPackageName());
+
+ try {
+ ActivityInfo info = getPackageManager().getActivityInfo(component, 0, appUserId);
+ if (info == null) {
+ Log.e(TAG, "Activity " + component + " is not installed.");
+ return null;
+ }
+
+ if (!info.exported) {
+ Log.e(TAG, "Activity " + component + " doesn't have 'exported' attribute.");
+ return null;
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to get activity info for " + component, e);
+ return null;
+ }
+
+ // Check that the component actually has Intent.CATEGORY_LAUNCHER
+ // as calling startActivityAsUser ignores the category and just
+ // resolves based on the component if present.
+ List<ResolveInfo> apps = mContext.getPackageManager().queryIntentActivitiesAsUser(launchIntent,
+ 0 /* flags */, appUserId);
+ final int size = apps.size();
+ for (int i = 0; i < size; ++i) {
+ ActivityInfo activityInfo = apps.get(i).activityInfo;
+ if (activityInfo.packageName.equals(component.getPackageName()) &&
+ activityInfo.name.equals(component.getClassName())) {
+ // Found an activity with category launcher that matches
+ // this component so ok to launch.
+ launchIntent.setComponent(component);
+ return launchIntent;
+ }
+ }
+
+ Log.e(TAG, "Activity doesn't have category Intent.CATEGORY_LAUNCHER " + component);
+ return null;
+ }
+
/**
* Reinitializes the model for a new user.
*/
@@ -199,6 +258,10 @@
/** Loads the list of apps from SharedPreferences. */
private void loadAppsFromPrefs() {
+ UserManager mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+
+ boolean hadUnlauncheableApps = false;
+
int appCount = mPrefs.getInt(userPrefixed(APP_COUNT_PREF), -1);
for (int i = 0; i < appCount; i++) {
String prefValue = mPrefs.getString(prefNameForApp(i), null);
@@ -214,8 +277,15 @@
// Couldn't find the saved state. Just skip this item.
continue;
}
- mApps.add(new AppInfo(componentName, userSerialNumber));
+ UserHandle appUser = mUserManager.getUserForSerialNumber(userSerialNumber);
+ if (appUser != null && buildAppLaunchIntent(componentName, appUser) != null) {
+ mApps.add(new AppInfo(componentName, userSerialNumber));
+ } else {
+ hadUnlauncheableApps = true;
+ }
}
+
+ if (hadUnlauncheableApps) savePrefs();
}
/** Adds the first few apps from the owner profile. Used for demo purposes. */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index 1649acb..7de7a7b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -91,7 +91,8 @@
private OnVerticalChangedListener mOnVerticalChangedListener;
private boolean mIsLayoutRtl;
- private boolean mLayoutTransitionsEnabled;
+ private boolean mLayoutTransitionsEnabled = true;
+ private boolean mWakeAndUnlocking;
private class NavTransitionListener implements TransitionListener {
private boolean mBackTransitioning;
@@ -371,13 +372,19 @@
}
}
- public void setWakeAndUnlocking(boolean wakeAndUnlocking) {
- setUseFadingAnimations(wakeAndUnlocking);
- setLayoutTransitionsEnabled(!wakeAndUnlocking);
+ public void setLayoutTransitionsEnabled(boolean enabled) {
+ mLayoutTransitionsEnabled = enabled;
+ updateLayoutTransitionsEnabled();
}
- private void setLayoutTransitionsEnabled(boolean enabled) {
- mLayoutTransitionsEnabled = enabled;
+ public void setWakeAndUnlocking(boolean wakeAndUnlocking) {
+ setUseFadingAnimations(wakeAndUnlocking);
+ mWakeAndUnlocking = wakeAndUnlocking;
+ updateLayoutTransitionsEnabled();
+ }
+
+ private void updateLayoutTransitionsEnabled() {
+ boolean enabled = !mWakeAndUnlocking && mLayoutTransitionsEnabled;
ViewGroup navButtons = (ViewGroup) mCurrentView.findViewById(R.id.nav_buttons);
LayoutTransition lt = navButtons.getLayoutTransition();
if (lt != null) {
@@ -469,7 +476,7 @@
}
mCurrentView = mRotatedViews[rot];
mCurrentView.setVisibility(View.VISIBLE);
- setLayoutTransitionsEnabled(mLayoutTransitionsEnabled);
+ updateLayoutTransitionsEnabled();
getImeSwitchButton().setOnClickListener(mImeSwitcherClickListener);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index babca34..24ae47d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -2425,4 +2425,9 @@
protected boolean isPanelVisibleBecauseOfHeadsUp() {
return mHeadsUpManager.hasPinnedHeadsUp() || mHeadsUpAnimatingAway;
}
+
+ @Override
+ public boolean hasOverlappingRendering() {
+ return !mDozing;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 4476192..1cdbd97 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -156,6 +156,7 @@
import com.android.systemui.statusbar.policy.ZenModeController;
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout.OnChildLocationsChangedListener;
+import com.android.systemui.statusbar.stack.StackStateAnimator;
import com.android.systemui.statusbar.stack.StackViewState;
import com.android.systemui.volume.VolumeComponent;
@@ -233,7 +234,7 @@
public static final int FADE_KEYGUARD_START_DELAY = 100;
public static final int FADE_KEYGUARD_DURATION = 300;
- public static final int FADE_KEYGUARD_DURATION_PULSING = 120;
+ public static final int FADE_KEYGUARD_DURATION_PULSING = 96;
/** Allow some time inbetween the long press for back and recents. */
private static final int LOCK_TO_APP_GESTURE_TOLERENCE = 200;
@@ -3481,14 +3482,6 @@
.setStartDelay(0)
.setDuration(FADE_KEYGUARD_DURATION_PULSING)
.setInterpolator(ScrimController.KEYGUARD_FADE_OUT_INTERPOLATOR)
- .withLayer()
- .withEndAction(new Runnable() {
- @Override
- public void run() {
- mNotificationPanel.setAlpha(1f);
- hideKeyguard();
- }
- })
.start();
}
@@ -3526,11 +3519,24 @@
setBarState(StatusBarState.SHADE);
if (mLeaveOpenOnKeyguardHide) {
mLeaveOpenOnKeyguardHide = false;
- mNotificationPanel.animateToFullShade(calculateGoingToFullShadeDelay());
+ long delay = calculateGoingToFullShadeDelay();
+ mNotificationPanel.animateToFullShade(delay);
if (mDraggedDownRow != null) {
mDraggedDownRow.setUserLocked(false);
mDraggedDownRow = null;
}
+
+ // Disable layout transitions in navbar for this transition because the load is just
+ // too heavy for the CPU and GPU on any device.
+ if (mNavigationBarView != null) {
+ mNavigationBarView.setLayoutTransitionsEnabled(false);
+ mNavigationBarView.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ mNavigationBarView.setLayoutTransitionsEnabled(true);
+ }
+ }, delay + StackStateAnimator.ANIMATION_DURATION_GO_TO_FULL_SHADE);
+ }
} else {
instantCollapseNotificationPanel();
}
@@ -3542,6 +3548,7 @@
mQSPanel.refreshAllTiles();
}
mHandler.removeMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
+ mNotificationPanel.setAlpha(1f);
return staying;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index 5b009ee..cc6f396 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -22,7 +22,6 @@
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Color;
-import android.util.Log;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.animation.DecelerateInterpolator;
@@ -87,6 +86,7 @@
private float mTopHeadsUpDragAmount;
private View mDraggedHeadsUpView;
private boolean mForceHideScrims;
+ private boolean mSkipFirstFrame;
public ScrimController(ScrimView scrimBehind, ScrimView scrimInFront, View headsUpScrim,
boolean scrimSrcEnabled) {
@@ -134,14 +134,20 @@
scheduleUpdate();
}
- public void animateKeyguardFadingOut(long delay, long duration, Runnable onAnimationFinished) {
+ public void animateKeyguardFadingOut(long delay, long duration, Runnable onAnimationFinished,
+ boolean skipFirstFrame) {
mWakeAndUnlocking = false;
mAnimateKeyguardFadingOut = true;
mDurationOverride = duration;
mAnimationDelay = delay;
mAnimateChange = true;
+ mSkipFirstFrame = skipFirstFrame;
mOnAnimationFinished = onAnimationFinished;
scheduleUpdate();
+
+ // No need to wait for the next frame to be drawn for this case - onPreDraw will execute
+ // the changes we just scheduled.
+ onPreDraw();
}
public void abortKeyguardFadingOut() {
@@ -339,6 +345,9 @@
}
});
anim.start();
+ if (mSkipFirstFrame) {
+ anim.setCurrentPlayTime(16);
+ }
scrim.setTag(TAG_KEY_ANIM, anim);
scrim.setTag(TAG_KEY_ANIM_TARGET, target);
}
@@ -354,6 +363,7 @@
updateScrims();
mDurationOverride = -1;
mAnimationDelay = 0;
+ mSkipFirstFrame = false;
// Make sure that we always call the listener even if we didn't start an animation.
endAnimateKeyguardFadingOut(false /* force */);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 448f16d..59ee5c5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -74,7 +74,6 @@
private boolean mLastOccluded;
private boolean mLastBouncerShowing;
private boolean mLastBouncerDismissible;
- private boolean mLastDeferScrimFadeOut;
private OnDismissAction mAfterKeyguardGoneAction;
private boolean mDeviceWillWakeUp;
private boolean mDeferScrimFadeOut;
@@ -184,7 +183,8 @@
mScreenTurnedOn = true;
if (mDeferScrimFadeOut) {
mDeferScrimFadeOut = false;
- animateScrimControllerKeyguardFadingOut(0, WAKE_AND_UNLOCK_SCRIM_FADEOUT_DURATION_MS);
+ animateScrimControllerKeyguardFadingOut(0, WAKE_AND_UNLOCK_SCRIM_FADEOUT_DURATION_MS,
+ true /* skipFirstFrame */);
updateStates();
}
mPhoneStatusBar.onScreenTurnedOn();
@@ -264,7 +264,8 @@
updateStates();
mScrimController.animateKeyguardFadingOut(
PhoneStatusBar.FADE_KEYGUARD_START_DELAY,
- PhoneStatusBar.FADE_KEYGUARD_DURATION, null);
+ PhoneStatusBar.FADE_KEYGUARD_DURATION, null,
+ false /* skipFirstFrame */);
}
}, new Runnable() {
@Override
@@ -279,10 +280,15 @@
if (mFingerprintUnlockController.getMode()
== FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING) {
mFingerprintUnlockController.startKeyguardFadingAway();
- mPhoneStatusBar.setKeyguardFadingAway(startTime, 0, 250);
+ mPhoneStatusBar.setKeyguardFadingAway(startTime, 0, 240);
mStatusBarWindowManager.setKeyguardFadingAway(true);
mPhoneStatusBar.fadeKeyguardWhilePulsing();
- animateScrimControllerKeyguardFadingOut(0, 250);
+ animateScrimControllerKeyguardFadingOut(0, 240, new Runnable() {
+ @Override
+ public void run() {
+ mPhoneStatusBar.hideKeyguard();
+ }
+ }, false /* skipFirstFrame */);
} else {
mFingerprintUnlockController.startKeyguardFadingAway();
mPhoneStatusBar.setKeyguardFadingAway(startTime, delay, fadeoutDuration);
@@ -297,10 +303,12 @@
// Screen is already on, don't defer with fading out.
animateScrimControllerKeyguardFadingOut(0,
- WAKE_AND_UNLOCK_SCRIM_FADEOUT_DURATION_MS);
+ WAKE_AND_UNLOCK_SCRIM_FADEOUT_DURATION_MS,
+ true /* skipFirstFrame */);
}
} else {
- animateScrimControllerKeyguardFadingOut(delay, fadeoutDuration);
+ animateScrimControllerKeyguardFadingOut(delay, fadeoutDuration,
+ false /* skipFirstFrame */);
}
} else {
mScrimController.animateGoingToFullShade(delay, fadeoutDuration);
@@ -315,11 +323,21 @@
}
}
- private void animateScrimControllerKeyguardFadingOut(long delay, long duration) {
+ private void animateScrimControllerKeyguardFadingOut(long delay, long duration,
+ boolean skipFirstFrame) {
+ animateScrimControllerKeyguardFadingOut(delay, duration, null /* endRunnable */,
+ skipFirstFrame);
+ }
+
+ private void animateScrimControllerKeyguardFadingOut(long delay, long duration,
+ final Runnable endRunnable, boolean skipFirstFrame) {
Trace.asyncTraceBegin(Trace.TRACE_TAG_VIEW, "Fading out", 0);
mScrimController.animateKeyguardFadingOut(delay, duration, new Runnable() {
@Override
public void run() {
+ if (endRunnable != null) {
+ endRunnable.run();
+ }
mStatusBarWindowManager.setKeyguardFadingAway(false);
mPhoneStatusBar.finishKeyguardFadingAway();
mFingerprintUnlockController.finishKeyguardFadingAway();
@@ -327,7 +345,7 @@
ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
Trace.asyncTraceEnd(Trace.TRACE_TAG_VIEW, "Fading out", 0);
}
- });
+ }, skipFirstFrame);
}
private void executeAfterKeyguardGoneAction() {
@@ -401,7 +419,6 @@
boolean occluded = mOccluded;
boolean bouncerShowing = mBouncer.isShowing();
boolean bouncerDismissible = !mBouncer.isFullscreenBouncer();
- boolean deferScrimFadeOut = mDeferScrimFadeOut;
if ((bouncerDismissible || !showing) != (mLastBouncerDismissible || !mLastShowing)
|| mFirstUpdate) {
@@ -412,11 +429,8 @@
}
}
- // Hide navigation bar on Keyguard but not on bouncer and also if we are deferring a scrim
- // fade out, i.e. we are waiting for the screen to have turned on.
- boolean navBarVisible = !deferScrimFadeOut && (!(showing && !occluded) || bouncerShowing);
- boolean lastNavBarVisible = !mLastDeferScrimFadeOut && (!(mLastShowing && !mLastOccluded)
- || mLastBouncerShowing);
+ boolean navBarVisible = (!(showing && !occluded) || bouncerShowing);
+ boolean lastNavBarVisible = (!(mLastShowing && !mLastOccluded) || mLastBouncerShowing);
if (navBarVisible != lastNavBarVisible || mFirstUpdate) {
if (mPhoneStatusBar.getNavigationBarView() != null) {
if (navBarVisible) {
@@ -451,7 +465,6 @@
mFirstUpdate = false;
mLastShowing = showing;
mLastOccluded = occluded;
- mLastDeferScrimFadeOut = deferScrimFadeOut;
mLastBouncerShowing = bouncerShowing;
mLastBouncerDismissible = bouncerDismissible;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java
index 091db76..a91cd51 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java
@@ -145,7 +145,7 @@
}
@Override
- public void onStrongAuthTimeoutExpiredChanged(int userId) {
+ public void onStrongAuthStateChanged(int userId) {
update(false /* updateAlways */);
}
};
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
index 61986ad..896bd62 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
@@ -23,6 +23,8 @@
import android.content.IntentFilter;
import android.content.res.TypedArray;
import android.os.Bundle;
+import android.os.Handler;
+import android.os.SystemClock;
import android.os.UserHandle;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
@@ -30,22 +32,28 @@
import android.text.style.CharacterStyle;
import android.text.style.RelativeSizeSpan;
import android.util.AttributeSet;
+import android.view.Display;
import android.widget.TextView;
import com.android.systemui.DemoMode;
import com.android.systemui.R;
+import com.android.systemui.tuner.TunerService;
+import com.android.systemui.tuner.TunerService.Tunable;
+
+import libcore.icu.LocaleData;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Locale;
import java.util.TimeZone;
-import libcore.icu.LocaleData;
-
/**
* Digital clock for the status bar.
*/
-public class Clock extends TextView implements DemoMode {
+public class Clock extends TextView implements DemoMode, Tunable {
+
+ public static final String CLOCK_SECONDS = "clock_seconds";
+
private boolean mAttached;
private Calendar mCalendar;
private String mClockFormatString;
@@ -57,6 +65,8 @@
private static final int AM_PM_STYLE_GONE = 2;
private final int mAmPmStyle;
+ private boolean mShowSeconds;
+ private Handler mSecondsHandler;
public Clock(Context context) {
this(context, null);
@@ -77,6 +87,7 @@
} finally {
a.recycle();
}
+ TunerService.get(context).addTunable(this, CLOCK_SECONDS);
}
@Override
@@ -105,6 +116,7 @@
// Make sure we update to the current time
updateClock();
+ updateShowSeconds();
}
@Override
@@ -143,6 +155,35 @@
setText(getSmallTime());
}
+ @Override
+ public void onTuningChanged(String key, String newValue) {
+ mShowSeconds = newValue != null && Integer.parseInt(newValue) != 0;
+ updateShowSeconds();
+ }
+
+ private void updateShowSeconds() {
+ if (mShowSeconds) {
+ // Wait until we have a display to start trying to show seconds.
+ if (mSecondsHandler == null && getDisplay() != null) {
+ mSecondsHandler = new Handler();
+ if (getDisplay().getState() == Display.STATE_ON) {
+ mSecondsHandler.postAtTime(mSecondTick,
+ SystemClock.uptimeMillis() / 1000 * 1000 + 1000);
+ }
+ IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
+ filter.addAction(Intent.ACTION_SCREEN_ON);
+ mContext.registerReceiver(mScreenReceiver, filter);
+ }
+ } else {
+ if (mSecondsHandler != null) {
+ mContext.unregisterReceiver(mScreenReceiver);
+ mSecondsHandler.removeCallbacks(mSecondTick);
+ mSecondsHandler = null;
+ updateClock();
+ }
+ }
+ }
+
private final CharSequence getSmallTime() {
Context context = getContext();
boolean is24 = DateFormat.is24HourFormat(context, ActivityManager.getCurrentUser());
@@ -152,7 +193,9 @@
final char MAGIC2 = '\uEF01';
SimpleDateFormat sdf;
- String format = is24 ? d.timeFormat_Hm : d.timeFormat_hm;
+ String format = mShowSeconds
+ ? is24 ? d.timeFormat_Hms : d.timeFormat_hms
+ : is24 ? d.timeFormat_Hm : d.timeFormat_hm;
if (!format.equals(mClockFormatString)) {
/*
* Search for an unquoted "a" in the format string, so we can
@@ -244,5 +287,32 @@
setText(getSmallTime());
}
}
+
+ private final BroadcastReceiver mScreenReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ if (Intent.ACTION_SCREEN_OFF.equals(action)) {
+ if (mSecondsHandler != null) {
+ mSecondsHandler.removeCallbacks(mSecondTick);
+ }
+ } else if (Intent.ACTION_SCREEN_ON.equals(action)) {
+ if (mSecondsHandler != null) {
+ mSecondsHandler.postAtTime(mSecondTick,
+ SystemClock.uptimeMillis() / 1000 * 1000 + 1000);
+ }
+ }
+ }
+ };
+
+ private final Runnable mSecondTick = new Runnable() {
+ @Override
+ public void run() {
+ if (mCalendar != null) {
+ updateClock();
+ }
+ mSecondsHandler.postAtTime(this, SystemClock.uptimeMillis() / 1000 * 1000 + 1000);
+ }
+ };
}
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/StatusBarSwitch.java b/packages/SystemUI/src/com/android/systemui/tuner/StatusBarSwitch.java
index e5b550e..dcb0d8d 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/StatusBarSwitch.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/StatusBarSwitch.java
@@ -38,6 +38,18 @@
}
@Override
+ protected void onAttachedToActivity() {
+ super.onAttachedToActivity();
+ TunerService.get(getContext()).addTunable(this, StatusBarIconController.ICON_BLACKLIST);
+ }
+
+ @Override
+ protected void onDetachedFromActivity() {
+ TunerService.get(getContext()).removeTunable(this);
+ super.onDetachedFromActivity();
+ }
+
+ @Override
public void onTuningChanged(String key, String newValue) {
if (!StatusBarIconController.ICON_BLACKLIST.equals(key)) {
return;
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java
index 71b5de5..96ad756 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java
@@ -15,8 +15,6 @@
*/
package com.android.systemui.tuner;
-import static com.android.systemui.BatteryMeterView.SHOW_PERCENT_SETTING;
-
import android.app.AlertDialog;
import android.app.FragmentTransaction;
import android.content.DialogInterface;
@@ -29,7 +27,6 @@
import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceFragment;
-import android.preference.PreferenceGroup;
import android.preference.SwitchPreference;
import android.provider.Settings;
import android.provider.Settings.System;
@@ -39,8 +36,8 @@
import com.android.internal.logging.MetricsLogger;
import com.android.systemui.R;
-import com.android.systemui.statusbar.phone.StatusBarIconController;
-import com.android.systemui.tuner.TunerService.Tunable;
+
+import static com.android.systemui.BatteryMeterView.SHOW_PERCENT_SETTING;
public class TunerFragment extends PreferenceFragment {
@@ -108,7 +105,6 @@
getContext().getContentResolver().registerContentObserver(
System.getUriFor(SHOW_PERCENT_SETTING), false, mSettingObserver);
- registerPrefs(getPreferenceScreen());
MetricsLogger.visibility(getContext(), MetricsLogger.TUNER, true);
}
@@ -117,36 +113,9 @@
super.onPause();
getContext().getContentResolver().unregisterContentObserver(mSettingObserver);
- unregisterPrefs(getPreferenceScreen());
MetricsLogger.visibility(getContext(), MetricsLogger.TUNER, false);
}
- private void registerPrefs(PreferenceGroup group) {
- TunerService tunerService = TunerService.get(getContext());
- final int N = group.getPreferenceCount();
- for (int i = 0; i < N; i++) {
- Preference pref = group.getPreference(i);
- if (pref instanceof StatusBarSwitch) {
- tunerService.addTunable((Tunable) pref, StatusBarIconController.ICON_BLACKLIST);
- } else if (pref instanceof PreferenceGroup) {
- registerPrefs((PreferenceGroup) pref);
- }
- }
- }
-
- private void unregisterPrefs(PreferenceGroup group) {
- TunerService tunerService = TunerService.get(getContext());
- final int N = group.getPreferenceCount();
- for (int i = 0; i < N; i++) {
- Preference pref = group.getPreference(i);
- if (pref instanceof Tunable) {
- tunerService.removeTunable((Tunable) pref);
- } else if (pref instanceof PreferenceGroup) {
- registerPrefs((PreferenceGroup) pref);
- }
- }
- }
-
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
menu.add(Menu.NONE, MENU_REMOVE, Menu.NONE, R.string.remove_from_settings);
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerSwitch.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerSwitch.java
new file mode 100644
index 0000000..0740e08
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerSwitch.java
@@ -0,0 +1,39 @@
+package com.android.systemui.tuner;
+
+import android.content.Context;
+import android.preference.SwitchPreference;
+import android.provider.Settings;
+import android.util.AttributeSet;
+
+import com.android.systemui.tuner.TunerService.Tunable;
+
+public class TunerSwitch extends SwitchPreference implements Tunable {
+
+ public TunerSwitch(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ protected void onAttachedToActivity() {
+ super.onAttachedToActivity();
+ TunerService.get(getContext()).addTunable(this, getKey());
+ }
+
+ @Override
+ protected void onDetachedFromActivity() {
+ TunerService.get(getContext()).removeTunable(this);
+ super.onDetachedFromActivity();
+ }
+
+ @Override
+ public void onTuningChanged(String key, String newValue) {
+ setChecked(newValue != null && Integer.parseInt(newValue) != 0);
+ }
+
+ @Override
+ protected boolean persistBoolean(boolean value) {
+ Settings.Secure.putString(getContext().getContentResolver(), getKey(), value ? "1" : "0");
+ return true;
+ }
+
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarAppsModelTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarAppsModelTest.java
index 62213ab..4d0e28b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarAppsModelTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarAppsModelTest.java
@@ -16,21 +16,26 @@
package com.android.systemui.statusbar.phone;
+import org.mockito.InOrder;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
+import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
+import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.UserInfo;
+import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
import android.test.AndroidTestCase;
@@ -45,6 +50,7 @@
/** Tests for the data model for the navigation bar app icons. */
public class NavigationBarAppsModelTest extends AndroidTestCase {
private PackageManager mMockPackageManager;
+ private IPackageManager mMockIPackageManager;
private SharedPreferences mMockPrefs;
private SharedPreferences.Editor mMockEdit;
private UserManager mMockUserManager;
@@ -61,6 +67,7 @@
final Context context = mock(Context.class);
mMockPackageManager = mock(PackageManager.class);
+ mMockIPackageManager = mock(IPackageManager.class);
mMockPrefs = mock(SharedPreferences.class);
mMockEdit = mock(SharedPreferences.Editor.class);
mMockUserManager = mock(UserManager.class);
@@ -78,8 +85,71 @@
when(mMockPrefs.edit()).thenReturn(mMockEdit);
when(mMockUserManager.getSerialNumberForUser(new UserHandle(2))).thenReturn(22L);
+ when(mMockUserManager.getUserForSerialNumber(45L)).thenReturn(new UserHandle(4));
+ when(mMockUserManager.getUserForSerialNumber(239L)).thenReturn(new UserHandle(5));
- mModel = new NavigationBarAppsModel(context);
+ mModel = new NavigationBarAppsModel(context) {
+ @Override
+ protected IPackageManager getPackageManager() {
+ return mMockIPackageManager;
+ }
+ };
+ }
+
+ /** Tests buildAppLaunchIntent(). */
+ public void testBuildAppLaunchIntent() {
+ ActivityInfo mockNonExportedActivityInfo = new ActivityInfo();
+ mockNonExportedActivityInfo.exported = false;
+ ActivityInfo mockExportedActivityInfo = new ActivityInfo();
+ mockExportedActivityInfo.exported = true;
+ try {
+ when(mMockIPackageManager.getActivityInfo(
+ new ComponentName("package1", "class1"), 0, 4)).
+ thenReturn(mockNonExportedActivityInfo);
+ when(mMockIPackageManager.getActivityInfo(
+ new ComponentName("package2", "class2"), 0, 5)).
+ thenThrow(new RemoteException());
+ when(mMockIPackageManager.getActivityInfo(
+ new ComponentName("package3", "class3"), 0, 6)).
+ thenReturn(mockExportedActivityInfo);
+ when(mMockIPackageManager.getActivityInfo(
+ new ComponentName("package4", "class4"), 0, 7)).
+ thenReturn(mockExportedActivityInfo);
+ } catch (RemoteException e) {
+ fail("RemoteException can't happen in the test, but it happened.");
+ }
+
+ // Assume some installed activities.
+ ActivityInfo ai0 = new ActivityInfo();
+ ai0.packageName = "package0";
+ ai0.name = "class0";
+ ActivityInfo ai1 = new ActivityInfo();
+ ai1.packageName = "package4";
+ ai1.name = "class4";
+ ResolveInfo ri0 = new ResolveInfo();
+ ri0.activityInfo = ai0;
+ ResolveInfo ri1 = new ResolveInfo();
+ ri1.activityInfo = ai1;
+ when(mMockPackageManager
+ .queryIntentActivitiesAsUser(any(Intent.class), eq(0), any(int.class)))
+ .thenReturn(Arrays.asList(ri0, ri1));
+
+ // Unlauncheable (for various reasons) apps.
+ assertEquals(null, mModel.buildAppLaunchIntent(
+ new ComponentName("package0", "class0"), new UserHandle(3)));
+ assertEquals(null, mModel.buildAppLaunchIntent(
+ new ComponentName("package1", "class1"), new UserHandle(4)));
+ assertEquals(null, mModel.buildAppLaunchIntent(
+ new ComponentName("package2", "class2"), new UserHandle(5)));
+ assertEquals(null, mModel.buildAppLaunchIntent(
+ new ComponentName("package3", "class3"), new UserHandle(6)));
+
+ // A launcheable app.
+ Intent intent = mModel.buildAppLaunchIntent(
+ new ComponentName("package4", "class4"), new UserHandle(7));
+ assertNotNull(intent);
+ assertEquals(new ComponentName("package4", "class4"), intent.getComponent());
+ assertEquals("package4", intent.getPackage());
}
/** Initializes the model from SharedPreferences for a few app activites. */
@@ -93,6 +163,39 @@
when(mMockPrefs.getString("22|app_2", null)).thenReturn("package2/class2");
when(mMockPrefs.getLong("22|app_user_2", -1)).thenReturn(239L);
+ ActivityInfo mockActivityInfo = new ActivityInfo();
+ mockActivityInfo.exported = true;
+ try {
+ when(mMockIPackageManager.getActivityInfo(
+ new ComponentName("package0", "class0"), 0, 5)).thenReturn(mockActivityInfo);
+ when(mMockIPackageManager.getActivityInfo(
+ new ComponentName("package1", "class1"), 0, 4)).thenReturn(mockActivityInfo);
+ when(mMockIPackageManager.getActivityInfo(
+ new ComponentName("package2", "class2"), 0, 5)).thenReturn(mockActivityInfo);
+ } catch (RemoteException e) {
+ fail("RemoteException can't happen in the test, but it happened.");
+ }
+
+ // Assume some installed activities.
+ ActivityInfo ai0 = new ActivityInfo();
+ ai0.packageName = "package0";
+ ai0.name = "class0";
+ ActivityInfo ai1 = new ActivityInfo();
+ ai1.packageName = "package1";
+ ai1.name = "class1";
+ ActivityInfo ai2 = new ActivityInfo();
+ ai2.packageName = "package2";
+ ai2.name = "class2";
+ ResolveInfo ri0 = new ResolveInfo();
+ ri0.activityInfo = ai0;
+ ResolveInfo ri1 = new ResolveInfo();
+ ri1.activityInfo = ai1;
+ ResolveInfo ri2 = new ResolveInfo();
+ ri2.activityInfo = ai2;
+ when(mMockPackageManager
+ .queryIntentActivitiesAsUser(any(Intent.class), eq(0), any(int.class)))
+ .thenReturn(Arrays.asList(ri0, ri1, ri2));
+
mModel.setCurrentUser(2);
}
@@ -133,6 +236,15 @@
assertEquals(22L, mModel.getApp(0).getUserSerialNumber());
assertEquals("package2/class2", mModel.getApp(1).getComponentName().flattenToString());
assertEquals(22L, mModel.getApp(1).getUserSerialNumber());
+ InOrder order = inOrder(mMockEdit);
+ order.verify(mMockEdit).apply();
+ order.verify(mMockEdit).putInt("22|app_count", 2);
+ order.verify(mMockEdit).putString("22|app_0", "package1/class1");
+ order.verify(mMockEdit).putLong("22|app_user_0", 22L);
+ order.verify(mMockEdit).putString("22|app_1", "package2/class2");
+ order.verify(mMockEdit).putLong("22|app_user_1", 22L);
+ order.verify(mMockEdit).apply();
+ verifyNoMoreInteractions(mMockEdit);
}
/** Tests initializing the model if one of the prefs is missing. */
@@ -145,11 +257,72 @@
// But assume one pref is missing.
when(mMockPrefs.getString("22|app_1", null)).thenReturn(null);
+ ActivityInfo mockActivityInfo = new ActivityInfo();
+ mockActivityInfo.exported = true;
+ try {
+ when(mMockIPackageManager.getActivityInfo(
+ new ComponentName("package0", "class0"), 0, 5)).thenReturn(mockActivityInfo);
+ } catch (RemoteException e) {
+ fail("RemoteException can't happen in the test, but it happened.");
+ }
+
+ ActivityInfo ai0 = new ActivityInfo();
+ ai0.packageName = "package0";
+ ai0.name = "class0";
+ ResolveInfo ri0 = new ResolveInfo();
+ ri0.activityInfo = ai0;
+ when(mMockPackageManager
+ .queryIntentActivitiesAsUser(any(Intent.class), eq(0), any(int.class)))
+ .thenReturn(Arrays.asList(ri0));
+
// Initializing the model should load from prefs and skip the missing one.
mModel.setCurrentUser(2);
assertEquals(1, mModel.getAppCount());
assertEquals("package0/class0", mModel.getApp(0).getComponentName().flattenToString());
assertEquals(239L, mModel.getApp(0).getUserSerialNumber());
+ verifyNoMoreInteractions(mMockEdit);
+ }
+
+ /** Tests initializing the model if one of the apps is unlauncheable. */
+ public void testInitializeWithUnlauncheableApp() {
+ // Assume two apps are nominally stored.
+ when(mMockPrefs.getInt("22|app_count", -1)).thenReturn(2);
+ when(mMockPrefs.getString("22|app_0", null)).thenReturn("package0/class0");
+ when(mMockPrefs.getLong("22|app_user_0", -1)).thenReturn(239L);
+ when(mMockPrefs.getString("22|app_1", null)).thenReturn("package1/class1");
+ when(mMockPrefs.getLong("22|app_user_1", -1)).thenReturn(45L);
+
+ ActivityInfo mockActivityInfo = new ActivityInfo();
+ mockActivityInfo.exported = true;
+ try {
+ when(mMockIPackageManager.getActivityInfo(
+ new ComponentName("package0", "class0"), 0, 5)).thenReturn(mockActivityInfo);
+ } catch (RemoteException e) {
+ fail("RemoteException can't happen in the test, but it happened.");
+ }
+
+ ActivityInfo ai0 = new ActivityInfo();
+ ai0.packageName = "package0";
+ ai0.name = "class0";
+ ResolveInfo ri0 = new ResolveInfo();
+ ri0.activityInfo = ai0;
+ when(mMockPackageManager
+ .queryIntentActivitiesAsUser(any(Intent.class), eq(0), any(int.class)))
+ .thenReturn(Arrays.asList(ri0));
+
+ // Initializing the model should load from prefs and skip the unlauncheable one.
+ mModel.setCurrentUser(2);
+ assertEquals(1, mModel.getAppCount());
+ assertEquals("package0/class0", mModel.getApp(0).getComponentName().flattenToString());
+ assertEquals(239L, mModel.getApp(0).getUserSerialNumber());
+
+ // Once an unlauncheable app is detected, the model should save all apps excluding the
+ // unlauncheable one.
+ verify(mMockEdit).putInt("22|app_count", 1);
+ verify(mMockEdit).putString("22|app_0", "package0/class0");
+ verify(mMockEdit).putLong("22|app_user_0", 239L);
+ verify(mMockEdit).apply();
+ verifyNoMoreInteractions(mMockEdit);
}
/** Tests saving the model to SharedPreferences. */
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index 34aeb60..f724749 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -401,21 +401,40 @@
public boolean isSystemRestore;
public String[] filterSet;
- // Restore a single package
+ /**
+ * Restore a single package; no kill after restore
+ */
RestoreParams(IBackupTransport _transport, String _dirName, IRestoreObserver _obs,
- long _token, PackageInfo _pkg, int _pmToken) {
+ long _token, PackageInfo _pkg) {
transport = _transport;
dirName = _dirName;
observer = _obs;
token = _token;
pkgInfo = _pkg;
- pmToken = _pmToken;
+ pmToken = 0;
isSystemRestore = false;
filterSet = null;
}
- // Restore everything possible. This is the form that Setup Wizard or similar
- // restore UXes use.
+ /**
+ * Restore at install: PM token needed, kill after restore
+ */
+ RestoreParams(IBackupTransport _transport, String _dirName, IRestoreObserver _obs,
+ long _token, String _pkgName, int _pmToken) {
+ transport = _transport;
+ dirName = _dirName;
+ observer = _obs;
+ token = _token;
+ pkgInfo = null;
+ pmToken = _pmToken;
+ isSystemRestore = false;
+ filterSet = new String[] { _pkgName };
+ }
+
+ /**
+ * Restore everything possible. This is the form that Setup Wizard or similar
+ * restore UXes use.
+ */
RestoreParams(IBackupTransport _transport, String _dirName, IRestoreObserver _obs,
long _token) {
transport = _transport;
@@ -428,8 +447,10 @@
filterSet = null;
}
- // Restore some set of packages. Leave this one up to the caller to specify
- // whether it's to be considered a system-level restore.
+ /**
+ * Restore some set of packages. Leave this one up to the caller to specify
+ * whether it's to be considered a system-level restore.
+ */
RestoreParams(IBackupTransport _transport, String _dirName, IRestoreObserver _obs,
long _token, String[] _filterSet, boolean _isSystemRestore) {
transport = _transport;
@@ -9137,19 +9158,13 @@
// This can throw and so *must* happen before the wakelock is acquired
String dirName = transport.transportDirName();
- // We can use a synthetic PackageInfo here because:
- // 1. We know it's valid, since the Package Manager supplied the name
- // 2. Only the packageName field will be used by the restore code
- PackageInfo pkg = new PackageInfo();
- pkg.packageName = packageName;
-
mWakelock.acquire();
if (MORE_DEBUG) {
Slog.d(TAG, "Restore at install of " + packageName);
}
Message msg = mBackupHandler.obtainMessage(MSG_RUN_RESTORE);
msg.obj = new RestoreParams(transport, dirName, null,
- restoreSet, pkg, token);
+ restoreSet, packageName, token);
mBackupHandler.sendMessage(msg);
} catch (RemoteException e) {
// Binding to the transport broke; back off and proceed with the installation.
@@ -9528,8 +9543,7 @@
Slog.d(TAG, "restorePackage() : " + packageName);
}
Message msg = mBackupHandler.obtainMessage(MSG_RUN_RESTORE);
- msg.obj = new RestoreParams(mRestoreTransport, dirName,
- observer, token, app, 0);
+ msg.obj = new RestoreParams(mRestoreTransport, dirName, observer, token, app);
mBackupHandler.sendMessage(msg);
} finally {
Binder.restoreCallingIdentity(oldId);
diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java
index 9427b61..7e4bcdc 100644
--- a/services/core/java/com/android/server/LockSettingsService.java
+++ b/services/core/java/com/android/server/LockSettingsService.java
@@ -18,6 +18,7 @@
import android.app.admin.DevicePolicyManager;
import android.app.backup.BackupManager;
+import android.app.trust.IStrongAuthTracker;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
@@ -70,6 +71,7 @@
private final Context mContext;
private final LockSettingsStorage mStorage;
+ private final LockSettingsStrongAuth mStrongAuth = new LockSettingsStrongAuth();
private LockPatternUtils mLockPatternUtils;
private boolean mFirstCallToVold;
@@ -93,6 +95,7 @@
filter.addAction(Intent.ACTION_USER_ADDED);
filter.addAction(Intent.ACTION_USER_STARTING);
filter.addAction(Intent.ACTION_USER_REMOVED);
+ filter.addAction(Intent.ACTION_USER_PRESENT);
mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null, null);
mStorage = new LockSettingsStorage(context, new LockSettingsStorage.Callback() {
@@ -122,6 +125,8 @@
} else if (Intent.ACTION_USER_STARTING.equals(intent.getAction())) {
final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
mStorage.prefetchUser(userHandle);
+ } else if (Intent.ACTION_USER_PRESENT.equals(intent.getAction())) {
+ mStrongAuth.reportUnlock(getSendingUserId());
} else if (Intent.ACTION_USER_REMOVED.equals(intent.getAction())) {
final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
if (userHandle > 0) {
@@ -713,6 +718,7 @@
private void removeUser(int userId) {
mStorage.removeUser(userId);
+ mStrongAuth.removeUser(userId);
final KeyStore ks = KeyStore.getInstance();
ks.onUserRemoved(userId);
@@ -727,6 +733,24 @@
}
}
+ @Override
+ public void registerStrongAuthTracker(IStrongAuthTracker tracker) {
+ checkPasswordReadPermission(UserHandle.USER_ALL);
+ mStrongAuth.registerStrongAuthTracker(tracker);
+ }
+
+ @Override
+ public void unregisterStrongAuthTracker(IStrongAuthTracker tracker) {
+ checkPasswordReadPermission(UserHandle.USER_ALL);
+ mStrongAuth.unregisterStrongAuthTracker(tracker);
+ }
+
+ @Override
+ public void requireStrongAuth(int strongAuthReason, int userId) {
+ checkWritePermission(userId);
+ mStrongAuth.requireStrongAuth(strongAuthReason, userId);
+ }
+
private static final String[] VALID_SETTINGS = new String[] {
LockPatternUtils.LOCKOUT_PERMANENT_KEY,
LockPatternUtils.LOCKOUT_ATTEMPT_DEADLINE,
@@ -797,5 +821,4 @@
Slog.e(TAG, "Unable to acquire GateKeeperService");
return null;
}
-
}
diff --git a/services/core/java/com/android/server/LockSettingsStrongAuth.java b/services/core/java/com/android/server/LockSettingsStrongAuth.java
new file mode 100644
index 0000000..c023f4a
--- /dev/null
+++ b/services/core/java/com/android/server/LockSettingsStrongAuth.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.internal.widget.LockPatternUtils.StrongAuthTracker;
+
+import android.app.trust.IStrongAuthTracker;
+import android.os.DeadObjectException;
+import android.os.Handler;
+import android.os.Message;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.util.Slog;
+import android.util.SparseIntArray;
+
+import java.util.ArrayList;
+
+import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED;
+
+/**
+ * Keeps track of requests for strong authentication.
+ */
+public class LockSettingsStrongAuth {
+
+ private static final String TAG = "LockSettings";
+
+ private static final int MSG_REQUIRE_STRONG_AUTH = 1;
+ private static final int MSG_REGISTER_TRACKER = 2;
+ private static final int MSG_UNREGISTER_TRACKER = 3;
+ private static final int MSG_REMOVE_USER = 4;
+
+ private final ArrayList<IStrongAuthTracker> mStrongAuthTrackers = new ArrayList<>();
+ private final SparseIntArray mStrongAuthForUser = new SparseIntArray();
+
+ private void handleAddStrongAuthTracker(IStrongAuthTracker tracker) {
+ for (int i = 0; i < mStrongAuthTrackers.size(); i++) {
+ if (mStrongAuthTrackers.get(i).asBinder() == tracker.asBinder()) {
+ return;
+ }
+ }
+ mStrongAuthTrackers.add(tracker);
+
+ for (int i = 0; i < mStrongAuthForUser.size(); i++) {
+ int key = mStrongAuthForUser.keyAt(i);
+ int value = mStrongAuthForUser.valueAt(i);
+ try {
+ tracker.onStrongAuthRequiredChanged(value, key);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Exception while adding StrongAuthTracker.", e);
+ }
+ }
+ }
+
+ private void handleRemoveStrongAuthTracker(IStrongAuthTracker tracker) {
+ for (int i = 0; i < mStrongAuthTrackers.size(); i++) {
+ if (mStrongAuthTrackers.get(i).asBinder() == tracker.asBinder()) {
+ mStrongAuthTrackers.remove(i);
+ return;
+ }
+ }
+ }
+
+ private void handleRequireStrongAuth(int strongAuthReason, int userId) {
+ if (userId == UserHandle.USER_ALL) {
+ for (int i = 0; i < mStrongAuthForUser.size(); i++) {
+ int key = mStrongAuthForUser.keyAt(i);
+ handleRequireStrongAuthOneUser(strongAuthReason, key);
+ }
+ } else {
+ handleRequireStrongAuthOneUser(strongAuthReason, userId);
+ }
+ }
+
+ private void handleRequireStrongAuthOneUser(int strongAuthReason, int userId) {
+ int oldValue = mStrongAuthForUser.get(userId, LockPatternUtils.StrongAuthTracker.DEFAULT);
+ int newValue = strongAuthReason == STRONG_AUTH_NOT_REQUIRED
+ ? STRONG_AUTH_NOT_REQUIRED
+ : (oldValue | strongAuthReason);
+ if (oldValue != newValue) {
+ mStrongAuthForUser.put(userId, newValue);
+ notifyStrongAuthTrackers(newValue, userId);
+ }
+ }
+
+ private void handleRemoveUser(int userId) {
+ int index = mStrongAuthForUser.indexOfKey(userId);
+ if (index >= 0) {
+ mStrongAuthForUser.removeAt(index);
+ notifyStrongAuthTrackers(StrongAuthTracker.DEFAULT, userId);
+ }
+ }
+
+ private void notifyStrongAuthTrackers(int strongAuthReason, int userId) {
+ for (int i = 0; i < mStrongAuthTrackers.size(); i++) {
+ try {
+ mStrongAuthTrackers.get(i).onStrongAuthRequiredChanged(strongAuthReason, userId);
+ } catch (DeadObjectException e) {
+ Slog.d(TAG, "Removing dead StrongAuthTracker.");
+ mStrongAuthTrackers.remove(i);
+ i--;
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Exception while notifying StrongAuthTracker.", e);
+ }
+ }
+ }
+
+ public void registerStrongAuthTracker(IStrongAuthTracker tracker) {
+ mHandler.obtainMessage(MSG_REGISTER_TRACKER, tracker).sendToTarget();
+ }
+
+ public void unregisterStrongAuthTracker(IStrongAuthTracker tracker) {
+ mHandler.obtainMessage(MSG_UNREGISTER_TRACKER, tracker).sendToTarget();
+ }
+
+ public void removeUser(int userId) {
+ mHandler.obtainMessage(MSG_REMOVE_USER, userId, 0).sendToTarget();
+ }
+
+ public void requireStrongAuth(int strongAuthReason, int userId) {
+ if (userId == UserHandle.USER_ALL || userId >= UserHandle.USER_OWNER) {
+ mHandler.obtainMessage(MSG_REQUIRE_STRONG_AUTH, strongAuthReason,
+ userId).sendToTarget();
+ } else {
+ throw new IllegalArgumentException(
+ "userId must be an explicit user id or USER_ALL");
+ }
+ }
+
+ public void reportUnlock(int userId) {
+ requireStrongAuth(STRONG_AUTH_NOT_REQUIRED, userId);
+ }
+
+ private final Handler mHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_REGISTER_TRACKER:
+ handleAddStrongAuthTracker((IStrongAuthTracker) msg.obj);
+ break;
+ case MSG_UNREGISTER_TRACKER:
+ handleRemoveStrongAuthTracker((IStrongAuthTracker) msg.obj);
+ break;
+ case MSG_REQUIRE_STRONG_AUTH:
+ handleRequireStrongAuth(msg.arg1, msg.arg2);
+ break;
+ case MSG_REMOVE_USER:
+ handleRemoveUser(msg.arg1);
+ break;
+ }
+ }
+ };
+}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index b6cd477..007b14b 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -21,6 +21,7 @@
import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
import static android.app.ActivityManager.DOCKED_STACK_ID;
import static android.app.ActivityManager.HOME_STACK_ID;
+import static android.app.ActivityManager.INVALID_STACK_ID;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static com.android.internal.util.XmlUtils.readBooleanAttribute;
import static com.android.internal.util.XmlUtils.readIntAttribute;
@@ -9005,8 +9006,7 @@
synchronized (this) {
ActivityStack stack = ActivityRecord.getStackLocked(token);
if (stack == null) {
- throw new IllegalArgumentException(
- "getActivityStackId: No stack for token=" + token);
+ return INVALID_STACK_ID;
}
return stack.mStackId;
}
@@ -9028,7 +9028,7 @@
}
if (DEBUG_STACK) Slog.d(TAG_STACK, "moveActivityToStack: moving r=" + r
+ " to stackId=" + stackId);
- mStackSupervisor.moveTaskToStackLocked(r.task.taskId, stackId, ON_TOP, FORCE_FOCUS);
+ mStackSupervisor.moveTaskToStackLocked(r.task.taskId, stackId, ON_TOP, !FORCE_FOCUS);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -10906,7 +10906,7 @@
synchronized (this) {
buildAssistBundleLocked(pae, pae.result);
mPendingAssistExtras.remove(pae);
- mHandler.removeCallbacks(pae);
+ mUiHandler.removeCallbacks(pae);
}
return pae.extras;
}
@@ -10994,7 +10994,7 @@
activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
requestType);
mPendingAssistExtras.add(pae);
- mHandler.postDelayed(pae, timeout);
+ mUiHandler.postDelayed(pae, timeout);
} catch (RemoteException e) {
Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
return null;
@@ -11051,7 +11051,7 @@
synchronized (this) {
buildAssistBundleLocked(pae, extras);
boolean exists = mPendingAssistExtras.remove(pae);
- mHandler.removeCallbacks(pae);
+ mUiHandler.removeCallbacks(pae);
if (!exists) {
// Timed out.
return;
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 356565f..fcd596f 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -248,6 +248,8 @@
/** Run all ActivityStacks through this */
final ActivityStackSupervisor mStackSupervisor;
+ private final LaunchingTaskPositioner mTaskPositioner;
+
static final int PAUSE_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 1;
static final int DESTROY_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 2;
static final int LAUNCH_TICK_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 3;
@@ -363,6 +365,33 @@
mStackId = activityContainer.mStackId;
mCurrentUser = mService.mCurrentUserId;
mRecentTasks = recentTasks;
+ mTaskPositioner = mStackId == FREEFORM_WORKSPACE_STACK_ID
+ ? new LaunchingTaskPositioner() : null;
+ }
+
+ void attachDisplay(ActivityStackSupervisor.ActivityDisplay activityDisplay, boolean onTop) {
+ mDisplayId = activityDisplay.mDisplayId;
+ mStacks = activityDisplay.mStacks;
+ mBounds = mWindowManager.attachStack(mStackId, activityDisplay.mDisplayId, onTop);
+ mFullscreen = mBounds == null;
+ if (mTaskPositioner != null) {
+ mTaskPositioner.setDisplay(activityDisplay.mDisplay);
+ mTaskPositioner.configure(mBounds);
+ }
+ }
+
+ void detachDisplay() {
+ mDisplayId = Display.INVALID_DISPLAY;
+ mStacks = null;
+ if (mTaskPositioner != null) {
+ mTaskPositioner.reset();
+ }
+ mWindowManager.detachStack(mStackId);
+ }
+
+ void setBounds(Rect bounds) {
+ mBounds = mFullscreen ? null : new Rect(bounds);
+ mTaskPositioner.configure(bounds);
}
boolean okToShowLocked(ActivityRecord r) {
@@ -2223,7 +2252,7 @@
+ task, new RuntimeException("here").fillInStackTrace());
task.addActivityToTop(r);
r.putInHistory();
- addAppToken(r, task);
+ addConfigOverride(r, task);
if (VALIDATE_TOKENS) {
validateAppTokensLocked();
}
@@ -2283,7 +2312,7 @@
: AppTransition.TRANSIT_ACTIVITY_OPEN, keepCurTransition);
mNoAnimActivities.remove(r);
}
- addAppToken(r, task);
+ addConfigOverride(r, task);
boolean doShow = true;
if (newTask) {
// Even though this activity is starting fresh, we still need
@@ -2332,7 +2361,7 @@
} else {
// If this is the first activity, don't do any fancy animations,
// because there is nothing for it to animate on top of.
- addAppToken(r, task);
+ addConfigOverride(r, task);
ActivityOptions.abort(options);
options = null;
}
@@ -4513,6 +4542,9 @@
boolean toTop) {
TaskRecord task = new TaskRecord(mService, taskId, info, intent, voiceSession,
voiceInteractor);
+ if (mTaskPositioner != null) {
+ mTaskPositioner.updateDefaultBounds(task, mTaskHistory);
+ }
addTask(task, toTop, false);
return task;
}
@@ -4548,7 +4580,7 @@
}
}
- void addAppToken(ActivityRecord r, TaskRecord task) {
+ void addConfigOverride(ActivityRecord r, TaskRecord task) {
final Rect bounds = task.getLaunchBounds();
final Configuration config =
mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken,
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 12b848b..c86056b 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -2977,7 +2977,7 @@
}
}
- stack.mBounds = stack.mFullscreen ? null : new Rect(bounds);
+ stack.setBounds(bounds);
if (r != null) {
final boolean updated = stack.ensureActivityConfigurationLocked(r, 0);
@@ -3017,7 +3017,6 @@
// Place the task in the right stack if it isn't there already based on the requested
// bounds.
int stackId = task.stack.mStackId;
- final boolean wasFrontStack = isFrontStack(task.stack);
if (bounds == null && stackId != FULLSCREEN_WORKSPACE_STACK_ID) {
stackId = FULLSCREEN_WORKSPACE_STACK_ID;
} else if (bounds != null
@@ -3027,12 +3026,7 @@
if (stackId != task.stack.mStackId) {
final String reason = "resizeTask";
final ActivityStack stack =
- moveTaskToStackUncheckedLocked(task, stackId, ON_TOP, reason);
- if (wasFrontStack) {
- // Since the stack was previously in front,
- // move the stack in which we are placing the task to the front.
- stack.moveToFront(reason);
- }
+ moveTaskToStackUncheckedLocked(task, stackId, ON_TOP, !FORCE_FOCUS, reason);
}
final Configuration overrideConfig = mWindowManager.resizeTask(task.taskId, bounds);
@@ -3112,7 +3106,7 @@
"Added restored task=" + task + " to stack=" + stack);
final ArrayList<ActivityRecord> activities = task.mActivities;
for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
- stack.addAppToken(activities.get(activityNdx), task);
+ stack.addConfigOverride(activities.get(activityNdx), task);
}
return true;
}
@@ -3126,17 +3120,36 @@
* @param task Task to move.
* @param stackId Id of stack to move task to.
* @param toTop True if the task should be placed at the top of the stack.
+ * @param forceFocus if focus should be moved to the new stack
* @param reason Reason the task is been moved.
* @return The stack the task was moved to.
*/
private ActivityStack moveTaskToStackUncheckedLocked(
- TaskRecord task, int stackId, boolean toTop, String reason) {
+ TaskRecord task, int stackId, boolean toTop, boolean forceFocus, String reason) {
+ final ActivityRecord r = task.getTopActivity();
+ final boolean wasFocused = isFrontStack(task.stack) && (topRunningActivityLocked() == r);
+ final boolean wasResumed = wasFocused && (task.stack.mResumedActivity == r);
+
final ActivityStack stack = getStack(stackId, CREATE_IF_NEEDED, toTop);
mWindowManager.moveTaskToStack(task.taskId, stack.mStackId, toTop);
if (task.stack != null) {
task.stack.removeTask(task, reason, MOVING);
}
stack.addTask(task, toTop, MOVING);
+
+ // If the task had focus before (or we're requested to move focus),
+ // move focus to the new stack.
+ if (forceFocus || wasFocused) {
+ // If the task owns the last resumed activity, transfer that together,
+ // so that we don't resume the same activity again in the new stack.
+ // Apps may depend on onResume()/onPause() being called in pairs.
+ if (wasResumed) {
+ stack.mResumedActivity = r;
+ }
+ // move the stack in which we are placing the task to the front.
+ stack.moveToFront(reason);
+ }
+
return stack;
}
@@ -3147,10 +3160,8 @@
return;
}
final String reason = "moveTaskToStack";
- final ActivityRecord top = task.topRunningActivityLocked(null);
- final boolean adjustFocus = forceFocus || mService.mFocusedActivity == top;
final ActivityStack stack =
- moveTaskToStackUncheckedLocked(task, stackId, toTop, reason);
+ moveTaskToStackUncheckedLocked(task, stackId, toTop, forceFocus, reason);
// Make sure the task has the appropriate bounds/size for the stack it is in.
if (stackId == FULLSCREEN_WORKSPACE_STACK_ID && task.mBounds != null) {
@@ -3162,14 +3173,6 @@
resizeTaskLocked(task, stack.mBounds);
}
- if (top != null && adjustFocus) {
- if (mService.mFocusedActivity != top) {
- mService.setFocusedActivityLocked(top, reason);
- } else {
- setFocusedStack(top, reason);
- }
- }
-
// The task might have already been running and its visibility needs to be synchronized with
// the visibility of the stack / windows.
ensureActivitiesVisibleLocked(null, 0);
@@ -4387,13 +4390,8 @@
if (DEBUG_STACK) Slog.d(TAG_STACK, "attachToDisplayLocked: " + this
+ " to display=" + activityDisplay + " onTop=" + onTop);
mActivityDisplay = activityDisplay;
- mStack.mDisplayId = activityDisplay.mDisplayId;
- mStack.mStacks = activityDisplay.mStacks;
-
+ mStack.attachDisplay(activityDisplay, onTop);
activityDisplay.attachActivities(mStack, onTop);
- mStack.mBounds =
- mWindowManager.attachStack(mStackId, activityDisplay.mDisplayId, onTop);
- mStack.mFullscreen = mStack.mBounds == null;
}
@Override
@@ -4465,9 +4463,7 @@
if (mActivityDisplay != null) {
mActivityDisplay.detachActivitiesLocked(mStack);
mActivityDisplay = null;
- mStack.mDisplayId = -1;
- mStack.mStacks = null;
- mWindowManager.detachStack(mStackId);
+ mStack.detachDisplay();
}
}
diff --git a/services/core/java/com/android/server/am/LaunchingTaskPositioner.java b/services/core/java/com/android/server/am/LaunchingTaskPositioner.java
new file mode 100644
index 0000000..3005c86
--- /dev/null
+++ b/services/core/java/com/android/server/am/LaunchingTaskPositioner.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.am;
+
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.view.Display;
+
+import java.util.ArrayList;
+
+/**
+ * Determines where a launching task should be positioned and sized on the display.
+ */
+class LaunchingTaskPositioner {
+ // Determines how close window frames/corners have to be to call them colliding.
+ private static final int BOUNDS_CONFLICT_MIN_DISTANCE = 4;
+
+ // Task will receive dimensions based on available dimensions divided by this.
+ private static final int WINDOW_SIZE_DENOMINATOR = 2;
+
+ // Task will receive margins based on available dimensions divided by this.
+ private static final int MARGIN_SIZE_DENOMINATOR = 4;
+
+ // If task bounds collide with some other, we will step and try again until we find a good
+ // position. The step will be determined by using dimensions and dividing it by this.
+ private static final int STEP_DENOMINATOR = 16;
+
+ // We always want to step by at least this.
+ private static final int MINIMAL_STEP = 1;
+
+ private boolean mDefaultStartBoundsConfigurationSet = false;
+ private final Rect mAvailableRect = new Rect();
+ private int mDefaultFreeformStartX;
+ private int mDefaultFreeformStartY;
+ private int mDefaultFreeformWidth;
+ private int mDefaultFreeformHeight;
+ private int mDefaultFreeformStepHorizontal;
+ private int mDefaultFreeformStepVertical;
+ private int mDisplayWidth;
+ private int mDisplayHeight;
+
+ void setDisplay(Display display) {
+ Point size = new Point();
+ display.getSize(size);
+ mDisplayWidth = size.x;
+ mDisplayHeight = size.y;
+ }
+
+ void configure(Rect stackBounds) {
+ if (stackBounds == null) {
+ mAvailableRect.set(0, 0, mDisplayWidth, mDisplayHeight);
+ } else {
+ mAvailableRect.set(stackBounds);
+ }
+ int width = mAvailableRect.width();
+ int height = mAvailableRect.height();
+ mDefaultFreeformStartX = mAvailableRect.left + width / MARGIN_SIZE_DENOMINATOR;
+ mDefaultFreeformStartY = mAvailableRect.top + height / MARGIN_SIZE_DENOMINATOR;
+ mDefaultFreeformWidth = width / WINDOW_SIZE_DENOMINATOR;
+ mDefaultFreeformHeight = height / WINDOW_SIZE_DENOMINATOR;
+ mDefaultFreeformStepHorizontal = Math.max(width / STEP_DENOMINATOR, MINIMAL_STEP);
+ mDefaultFreeformStepVertical = Math.max(height / STEP_DENOMINATOR, MINIMAL_STEP);
+ mDefaultStartBoundsConfigurationSet = true;
+ }
+
+ /**
+ * Tries to set task's bound in a way that it won't collide with any other task. By colliding
+ * we mean that two tasks have left-top corner very close to each other, so one might get
+ * obfuscated by the other one.
+ *
+ * @param task Task for which we want to find bounds that won't collide with other.
+ * @param tasks Existing tasks with which we don't want to collide.
+ */
+ void updateDefaultBounds(TaskRecord task, ArrayList<TaskRecord> tasks) {
+ if (!mDefaultStartBoundsConfigurationSet) {
+ return;
+ }
+ int startX = mDefaultFreeformStartX;
+ int startY = mDefaultFreeformStartY;
+ final int right = mAvailableRect.right;
+ final int bottom = mAvailableRect.bottom;
+ boolean restarted = false;
+ while (boundsConflict(startX, startY, tasks)) {
+ // Unfortunately there is already a task at that spot, so we need to look for some
+ // other place.
+ startX += mDefaultFreeformStepHorizontal;
+ startY += mDefaultFreeformStepVertical;
+ if (startX + mDefaultFreeformWidth > right
+ || startY + mDefaultFreeformHeight > bottom) {
+ // We don't want the task to go outside of the display, because it won't look
+ // nice. Let's restart from the top instead, because there should be some space
+ // there.
+ startX = mAvailableRect.left;
+ startY = mAvailableRect.top;
+ restarted = true;
+ }
+ if (restarted
+ && (startX > mDefaultFreeformStartX || startY > mDefaultFreeformStartY)) {
+ // If we restarted and crossed the initial position, let's not struggle anymore.
+ // The user already must have ton of tasks visible, we can just smack the new
+ // one in the center.
+ startX = mDefaultFreeformStartX;
+ startY = mDefaultFreeformStartY;
+ break;
+ }
+ }
+ task.setInitialBounds(startX, startY, startX + mDefaultFreeformWidth,
+ startY + mDefaultFreeformHeight);
+ }
+
+ private boolean boundsConflict(int startX, int startY, ArrayList<TaskRecord> tasks) {
+ for (int i = tasks.size() - 1; i >= 0; i--) {
+ TaskRecord task = tasks.get(i);
+ if (!task.mActivities.isEmpty()) {
+ Rect bounds = task.mBounds;
+ if (bounds != null && (Math.abs(bounds.left - startX) < BOUNDS_CONFLICT_MIN_DISTANCE
+ || Math.abs(bounds.top - startY) < BOUNDS_CONFLICT_MIN_DISTANCE)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ void reset() {
+ mDefaultStartBoundsConfigurationSet = false;
+ }
+}
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index ed935a1..ff412d1 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -1217,6 +1217,14 @@
return mLastNonFullscreenBounds;
}
+ void setInitialBounds(int left, int top, int right, int bottom) {
+ if (mBounds == null) {
+ mBounds = new Rect();
+ }
+ mBounds.set(left, top, right, bottom);
+ mLastNonFullscreenBounds = mBounds;
+ }
+
void dump(PrintWriter pw, String prefix) {
pw.print(prefix); pw.print("userId="); pw.print(userId);
pw.print(" effectiveUid="); UserHandle.formatUid(pw, effectiveUid);
diff --git a/services/core/java/com/android/server/notification/ConditionProviders.java b/services/core/java/com/android/server/notification/ConditionProviders.java
index 40956c1..19d8538 100644
--- a/services/core/java/com/android/server/notification/ConditionProviders.java
+++ b/services/core/java/com/android/server/notification/ConditionProviders.java
@@ -67,7 +67,7 @@
public void addSystemProvider(SystemConditionProviderService service) {
mSystemConditionProviders.add(service);
service.attachBase(mContext);
- registerService(service.asInterface(), service.getComponent(), UserHandle.USER_OWNER);
+ registerService(service.asInterface(), service.getComponent(), UserHandle.USER_SYSTEM);
}
public Iterable<SystemConditionProviderService> getSystemProviders() {
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 4351798..0c884f15 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -716,7 +716,7 @@
final IPackageManager pm = AppGlobals.getPackageManager();
final int enabled = pm.getApplicationEnabledSetting(pkgName,
changeUserId != UserHandle.USER_ALL ? changeUserId :
- UserHandle.USER_OWNER);
+ UserHandle.USER_SYSTEM);
if (enabled == PackageManager.COMPONENT_ENABLED_STATE_ENABLED
|| enabled == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
cancelNotifications = false;
@@ -1420,7 +1420,7 @@
if (!r.isSeen()) {
if (DBG) Slog.d(TAG, "Marking notification as seen " + keys[i]);
mAppUsageStats.reportEvent(r.sbn.getPackageName(),
- userId == UserHandle.USER_ALL ? UserHandle.USER_OWNER
+ userId == UserHandle.USER_ALL ? UserHandle.USER_SYSTEM
: userId,
UsageEvents.Event.USER_INTERACTION);
r.setSeen();
@@ -1701,7 +1701,8 @@
@Override
public byte[] getBackupPayload(int user) {
if (DBG) Slog.d(TAG, "getBackupPayload u=" + user);
- if (user != UserHandle.USER_OWNER) {
+ //TODO: http://b/22388012
+ if (user != UserHandle.USER_SYSTEM) {
Slog.w(TAG, "getBackupPayload: cannot backup policy for user " + user);
return null;
}
@@ -1723,7 +1724,8 @@
Slog.w(TAG, "applyRestore: no payload to restore for user " + user);
return;
}
- if (user != UserHandle.USER_OWNER) {
+ //TODO: http://b/22388012
+ if (user != UserHandle.USER_SYSTEM) {
Slog.w(TAG, "applyRestore: cannot restore policy for user " + user);
return;
}
diff --git a/services/core/java/com/android/server/notification/RankingHelper.java b/services/core/java/com/android/server/notification/RankingHelper.java
index a089518..66381f5 100644
--- a/services/core/java/com/android/server/notification/RankingHelper.java
+++ b/services/core/java/com/android/server/notification/RankingHelper.java
@@ -148,7 +148,8 @@
if (!TextUtils.isEmpty(name)) {
if (forRestore) {
try {
- uid = pm.getPackageUid(name, UserHandle.USER_OWNER);
+ //TODO: http://b/22388012
+ uid = pm.getPackageUid(name, UserHandle.USER_SYSTEM);
} catch (NameNotFoundException e) {
// noop
}
@@ -213,7 +214,8 @@
final int N = mRecords.size();
for (int i = 0; i < N; i++) {
final Record r = mRecords.valueAt(i);
- if (forBackup && UserHandle.getUserId(r.uid) != UserHandle.USER_OWNER) {
+ //TODO: http://b/22388012
+ if (forBackup && UserHandle.getUserId(r.uid) != UserHandle.USER_SYSTEM) {
continue;
}
out.startTag(null, TAG_PACKAGE);
@@ -437,7 +439,8 @@
final Record r = mRestoredWithoutUids.get(pkg);
if (r != null) {
try {
- r.uid = pm.getPackageUid(r.pkg, UserHandle.USER_OWNER);
+ //TODO: http://b/22388012
+ r.uid = pm.getPackageUid(r.pkg, UserHandle.USER_SYSTEM);
mRestoredWithoutUids.remove(pkg);
mRecords.put(recordKey(r.pkg, r.uid), r);
updated = true;
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 57d7758..edd274b 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -85,7 +85,7 @@
private final Metrics mMetrics = new Metrics();
private int mZenMode;
- private int mUser = UserHandle.USER_OWNER;
+ private int mUser = UserHandle.USER_SYSTEM;
private ZenModeConfig mConfig;
private AudioManagerInternal mAudioManager;
private boolean mEffectsSuppressed;
@@ -99,7 +99,7 @@
appendDefaultScheduleRules(mDefaultConfig);
appendDefaultEventRules(mDefaultConfig);
mConfig = mDefaultConfig;
- mConfigs.put(UserHandle.USER_OWNER, mConfig);
+ mConfigs.put(UserHandle.USER_SYSTEM, mConfig);
mSettingsObserver = new SettingsObserver(mHandler);
mSettingsObserver.observe();
mFiltering = new ZenModeFiltering(mContext);
@@ -152,7 +152,7 @@
}
public void onUserSwitched(int user) {
- if (mUser == user || user < UserHandle.USER_OWNER) return;
+ if (mUser == user || user < UserHandle.USER_SYSTEM) return;
mUser = user;
if (DEBUG) Log.d(TAG, "onUserSwitched u=" + user);
ZenModeConfig config = mConfigs.get(user);
@@ -165,7 +165,7 @@
}
public void onUserRemoved(int user) {
- if (user < UserHandle.USER_OWNER) return;
+ if (user < UserHandle.USER_SYSTEM) return;
if (DEBUG) Log.d(TAG, "onUserRemoved u=" + user);
mConfigs.remove(user);
}
@@ -265,7 +265,8 @@
final ZenModeConfig config = ZenModeConfig.readXml(parser, mConfigMigration);
if (config != null) {
if (forRestore) {
- if (config.user != UserHandle.USER_OWNER) {
+ //TODO: http://b/22388012
+ if (config.user != UserHandle.USER_SYSTEM) {
return;
}
config.manualRule = null; // don't restore the manual rule
@@ -285,7 +286,8 @@
public void writeXml(XmlSerializer out, boolean forBackup) throws IOException {
final int N = mConfigs.size();
for (int i = 0; i < N; i++) {
- if (forBackup && mConfigs.keyAt(i) != UserHandle.USER_OWNER) {
+ //TODO: http://b/22388012
+ if (forBackup && mConfigs.keyAt(i) != UserHandle.USER_SYSTEM) {
continue;
}
mConfigs.valueAt(i).writeXml(out);
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 153bd3b..a559116 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -71,7 +71,7 @@
import static android.system.OsConstants.O_CREAT;
import static android.system.OsConstants.O_RDWR;
import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
-import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_USER_OWNER;
+import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT;
import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME;
import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
import static com.android.internal.util.ArrayUtils.appendInt;
@@ -4949,18 +4949,25 @@
private ResolveInfo createForwardingResolveInfo(IntentFilter filter,
int sourceUserId, int targetUserId) {
ResolveInfo forwardingResolveInfo = new ResolveInfo();
+ long ident = Binder.clearCallingIdentity();
+ boolean targetIsProfile;
+ try {
+ targetIsProfile = sUserManager.getUserInfo(targetUserId).isManagedProfile();
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
String className;
- if (targetUserId == UserHandle.USER_OWNER) {
- className = FORWARD_INTENT_TO_USER_OWNER;
- } else {
+ if (targetIsProfile) {
className = FORWARD_INTENT_TO_MANAGED_PROFILE;
+ } else {
+ className = FORWARD_INTENT_TO_PARENT;
}
ComponentName forwardingActivityComponentName = new ComponentName(
mAndroidApplication.packageName, className);
ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0,
sourceUserId);
- if (targetUserId == UserHandle.USER_OWNER) {
- forwardingActivityInfo.showUserIcon = UserHandle.USER_OWNER;
+ if (!targetIsProfile) {
+ forwardingActivityInfo.showUserIcon = targetUserId;
forwardingResolveInfo.noResourceId = true;
}
forwardingResolveInfo.activityInfo = forwardingActivityInfo;
@@ -6112,7 +6119,7 @@
}
// Give priority to system apps that listen for pre boot complete.
Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
- ArraySet<String> pkgNames = getPackageNamesForIntent(intent);
+ ArraySet<String> pkgNames = getPackageNamesForIntent(intent, UserHandle.USER_SYSTEM);
for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
PackageParser.Package pkg = it.next();
if (pkgNames.contains(pkg.packageName)) {
@@ -6147,7 +6154,7 @@
}
// Give priority to apps that listen for boot complete.
intent = new Intent(Intent.ACTION_BOOT_COMPLETED);
- pkgNames = getPackageNamesForIntent(intent);
+ pkgNames = getPackageNamesForIntent(intent, UserHandle.USER_SYSTEM);
for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
PackageParser.Package pkg = it.next();
if (pkgNames.contains(pkg.packageName)) {
@@ -6218,11 +6225,11 @@
}
}
- private ArraySet<String> getPackageNamesForIntent(Intent intent) {
+ private ArraySet<String> getPackageNamesForIntent(Intent intent, int userId) {
List<ResolveInfo> ris = null;
try {
ris = AppGlobals.getPackageManager().queryIntentReceivers(
- intent, null, 0, UserHandle.USER_OWNER);
+ intent, null, 0, userId);
} catch (RemoteException e) {
}
ArraySet<String> pkgNames = new ArraySet<String>();
@@ -11845,8 +11852,9 @@
String pkgName = pkg.packageName;
if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
+ // TODO: b/23350563
final boolean dataDirExists = Environment
- .getDataUserPackageDirectory(volumeUuid, UserHandle.USER_OWNER, pkgName).exists();
+ .getDataUserPackageDirectory(volumeUuid, UserHandle.USER_SYSTEM, pkgName).exists();
synchronized(mPackages) {
if (mSettings.mRenamedPackages.containsKey(pkgName)) {
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 08f0f09..4bfcb90 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -133,7 +133,7 @@
private static final long EPOCH_PLUS_30_YEARS = 30L * 365 * 24 * 60 * 60 * 1000L; // ms
- // Maximum number of managed profiles permitted is 1. This cannot be increased
+ // Maximum number of managed profiles permitted per user is 1. This cannot be increased
// without first making sure that the rest of the framework is prepared for it.
private static final int MAX_MANAGED_PROFILES = 1;
@@ -419,9 +419,10 @@
return ui;
}
+ /** Called by PackageManagerService */
public boolean exists(int userId) {
synchronized (mPackagesLock) {
- return ArrayUtils.contains(mUserIds, userId);
+ return mUsers.get(userId) != null;
}
}
@@ -626,7 +627,7 @@
}
@Override
- public boolean canAddMoreManagedProfiles() {
+ public boolean canAddMoreManagedProfiles(int userId) {
checkManageUsersPermission("check if more managed profiles can be added.");
if (ActivityManager.isLowRamDeviceStatic()) {
return false;
@@ -635,10 +636,14 @@
PackageManager.FEATURE_MANAGED_USERS)) {
return false;
}
+ // Limit number of managed profiles that can be created
+ int managedProfilesCount = getProfiles(userId, true).size() - 1;
+ if (managedProfilesCount >= MAX_MANAGED_PROFILES) {
+ return false;
+ }
synchronized(mPackagesLock) {
- // Limit number of managed profiles that can be created
- if (numberOfUsersOfTypeLocked(UserInfo.FLAG_MANAGED_PROFILE, true)
- >= MAX_MANAGED_PROFILES) {
+ UserInfo userInfo = getUserInfoLocked(userId);
+ if (!userInfo.canHaveProfile()) {
return false;
}
int usersCount = getAliveUsersExcludingGuestsCountLocked();
@@ -1237,10 +1242,6 @@
@Override
public UserInfo createProfileForUser(String name, int flags, int userId) {
checkManageUsersPermission("Only the system can create users");
- if (userId != UserHandle.USER_OWNER) {
- Slog.w(LOG_TAG, "Only user owner can have profiles");
- return null;
- }
return createUserInternal(name, flags, userId);
}
@@ -1272,7 +1273,8 @@
parent = getUserInfoLocked(parentId);
if (parent == null) return null;
}
- if (isManagedProfile && !canAddMoreManagedProfiles()) {
+ if (isManagedProfile && !canAddMoreManagedProfiles(parentId)) {
+ Log.e(LOG_TAG, "Cannot add more managed profiles for user " + parentId);
return null;
}
if (!isGuest && !isManagedProfile && isUserLimitReachedLocked()) {
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 45bbf37..e0da33f 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -2835,6 +2835,12 @@
}
}
}
+ } else if (keyCode == KeyEvent.KEYCODE_SLASH && event.isMetaPressed()) {
+ if (down) {
+ if (repeatCount == 0) {
+ showKeyboardShortcutsMenu();
+ }
+ }
} else if (keyCode == KeyEvent.KEYCODE_ASSIST) {
if (down) {
if (repeatCount == 0) {
@@ -3255,6 +3261,17 @@
}
}
+ private void showKeyboardShortcutsMenu() {
+ try {
+ IStatusBarService statusbar = getStatusBarService();
+ if (statusbar != null) {
+ statusbar.showKeyboardShortcutsMenu();
+ }
+ } catch (RemoteException e) {
+ Slog.e(TAG, "RemoteException when showing keyboard shortcuts menu", e);
+ }
+ }
+
private void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHome) {
mPreloadedRecentApps = false; // preloading no longer needs to be canceled
try {
@@ -6113,6 +6130,7 @@
}
startedWakingUp();
screenTurningOn(null);
+ screenTurnedOn();
}
ProgressDialog mBootMsgDialog = null;
diff --git a/services/core/java/com/android/server/policy/StatusBarController.java b/services/core/java/com/android/server/policy/StatusBarController.java
index d1b50da..da23f45 100644
--- a/services/core/java/com/android/server/policy/StatusBarController.java
+++ b/services/core/java/com/android/server/policy/StatusBarController.java
@@ -122,7 +122,7 @@
*
* @return the desired start time of the status bar transition, in uptime millis
*/
- private long calculateStatusBarTransitionStartTime(Animation openAnimation,
+ private static long calculateStatusBarTransitionStartTime(Animation openAnimation,
Animation closeAnimation) {
if (openAnimation != null && closeAnimation != null) {
TranslateAnimation openTranslateAnimation = findTranslateAnimation(openAnimation);
@@ -151,7 +151,7 @@
*
* @return the found animation, {@code null} otherwise
*/
- private TranslateAnimation findTranslateAnimation(Animation animation) {
+ private static TranslateAnimation findTranslateAnimation(Animation animation) {
if (animation instanceof TranslateAnimation) {
return (TranslateAnimation) animation;
} else if (animation instanceof AnimationSet) {
@@ -170,7 +170,7 @@
* Binary searches for a {@code t} such that there exists a {@code -0.01 < eps < 0.01} for which
* {@code interpolator(t + eps) > 0.99}.
*/
- private float findAlmostThereFraction(Interpolator interpolator) {
+ private static float findAlmostThereFraction(Interpolator interpolator) {
float val = 0.5f;
float adj = 0.25f;
while (adj >= 0.01f) {
diff --git a/services/core/java/com/android/server/policy/WindowOrientationListener.java b/services/core/java/com/android/server/policy/WindowOrientationListener.java
index c71b48f..8b3c036 100644
--- a/services/core/java/com/android/server/policy/WindowOrientationListener.java
+++ b/services/core/java/com/android/server/policy/WindowOrientationListener.java
@@ -24,10 +24,12 @@
import android.os.Handler;
import android.os.SystemClock;
import android.os.SystemProperties;
+import android.text.TextUtils;
import android.util.Slog;
import java.io.PrintWriter;
import java.util.Arrays;
+import java.util.List;
/**
* A special helper class used by the WindowManager
@@ -52,8 +54,9 @@
private SensorManager mSensorManager;
private boolean mEnabled;
private int mRate;
+ private String mSensorType;
private Sensor mSensor;
- private SensorEventListenerImpl mSensorEventListener;
+ private OrientationJudge mOrientationJudge;
private int mCurrentRotation = -1;
private final Object mLock = new Object();
@@ -67,7 +70,7 @@
public WindowOrientationListener(Context context, Handler handler) {
this(context, handler, SensorManager.SENSOR_DELAY_UI);
}
-
+
/**
* Creates a new WindowOrientationListener.
*
@@ -84,11 +87,31 @@
mHandler = handler;
mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
mRate = rate;
- mSensor = mSensorManager.getDefaultSensor(USE_GRAVITY_SENSOR
- ? Sensor.TYPE_GRAVITY : Sensor.TYPE_ACCELEROMETER);
- if (mSensor != null) {
- // Create listener only if sensors do exist
- mSensorEventListener = new SensorEventListenerImpl(context);
+
+ mSensorType = context.getResources().getString(
+ com.android.internal.R.string.config_orientationSensorType);
+ if (!TextUtils.isEmpty(mSensorType)) {
+ List<Sensor> sensors = mSensorManager.getSensorList(Sensor.TYPE_ALL);
+ final int N = sensors.size();
+ for (int i = 0; i < N; i++) {
+ Sensor sensor = sensors.get(i);
+ if (mSensorType.equals(sensor.getStringType())) {
+ mSensor = sensor;
+ break;
+ }
+ }
+ if (mSensor != null) {
+ mOrientationJudge = new OrientationSensorJudge();
+ }
+ }
+
+ if (mOrientationJudge == null) {
+ mSensor = mSensorManager.getDefaultSensor(USE_GRAVITY_SENSOR
+ ? Sensor.TYPE_GRAVITY : Sensor.TYPE_ACCELEROMETER);
+ if (mSensor != null) {
+ // Create listener only if sensors do exist
+ mOrientationJudge = new AccelSensorJudge(context);
+ }
}
}
@@ -106,8 +129,8 @@
if (LOG) {
Slog.d(TAG, "WindowOrientationListener enabled");
}
- mSensorEventListener.resetLocked();
- mSensorManager.registerListener(mSensorEventListener, mSensor, mRate, mHandler);
+ mOrientationJudge.resetLocked();
+ mSensorManager.registerListener(mOrientationJudge, mSensor, mRate, mHandler);
mEnabled = true;
}
}
@@ -126,7 +149,7 @@
if (LOG) {
Slog.d(TAG, "WindowOrientationListener disabled");
}
- mSensorManager.unregisterListener(mSensorEventListener);
+ mSensorManager.unregisterListener(mOrientationJudge);
mEnabled = false;
}
}
@@ -134,8 +157,8 @@
public void onTouchStart() {
synchronized (mLock) {
- if (mSensorEventListener != null) {
- mSensorEventListener.onTouchStartLocked();
+ if (mOrientationJudge != null) {
+ mOrientationJudge.onTouchStartLocked();
}
}
}
@@ -144,8 +167,8 @@
long whenElapsedNanos = SystemClock.elapsedRealtimeNanos();
synchronized (mLock) {
- if (mSensorEventListener != null) {
- mSensorEventListener.onTouchEndLocked(whenElapsedNanos);
+ if (mOrientationJudge != null) {
+ mOrientationJudge.onTouchEndLocked(whenElapsedNanos);
}
}
}
@@ -172,7 +195,7 @@
public int getProposedRotation() {
synchronized (mLock) {
if (mEnabled) {
- return mSensorEventListener.getProposedRotationLocked();
+ return mOrientationJudge.getProposedRotationLocked();
}
return -1;
}
@@ -205,15 +228,77 @@
prefix += " ";
pw.println(prefix + "mEnabled=" + mEnabled);
pw.println(prefix + "mCurrentRotation=" + mCurrentRotation);
+ pw.println(prefix + "mSensorType=" + mSensorType);
pw.println(prefix + "mSensor=" + mSensor);
pw.println(prefix + "mRate=" + mRate);
- if (mSensorEventListener != null) {
- mSensorEventListener.dumpLocked(pw, prefix);
+ if (mOrientationJudge != null) {
+ mOrientationJudge.dumpLocked(pw, prefix);
}
}
}
+ abstract class OrientationJudge implements SensorEventListener {
+ // Number of nanoseconds per millisecond.
+ protected static final long NANOS_PER_MS = 1000000;
+
+ // Number of milliseconds per nano second.
+ protected static final float MILLIS_PER_NANO = 0.000001f;
+
+ // The minimum amount of time that must have elapsed since the screen was last touched
+ // before the proposed rotation can change.
+ protected static final long PROPOSAL_MIN_TIME_SINCE_TOUCH_END_NANOS =
+ 500 * NANOS_PER_MS;
+
+ /**
+ * Gets the proposed rotation.
+ *
+ * This method only returns a rotation if the orientation listener is certain
+ * of its proposal. If the rotation is indeterminate, returns -1.
+ *
+ * Should only be called when holding WindowOrientationListener lock.
+ *
+ * @return The proposed rotation, or -1 if unknown.
+ */
+ public abstract int getProposedRotationLocked();
+
+ /**
+ * Notifies the orientation judge that the screen is being touched.
+ *
+ * Should only be called when holding WindowOrientationListener lock.
+ */
+ public abstract void onTouchStartLocked();
+
+ /**
+ * Notifies the orientation judge that the screen is no longer being touched.
+ *
+ * Should only be called when holding WindowOrientationListener lock.
+ *
+ * @param whenElapsedNanos Given in the elapsed realtime nanos time base.
+ */
+ public abstract void onTouchEndLocked(long whenElapsedNanos);
+
+ /**
+ * Resets the state of the judge.
+ *
+ * Should only be called when holding WindowOrientationListener lock.
+ */
+ public abstract void resetLocked();
+
+ /**
+ * Dumps internal state of the orientation judge.
+ *
+ * Should only be called when holding WindowOrientationListener lock.
+ */
+ public abstract void dumpLocked(PrintWriter pw, String prefix);
+
+ @Override
+ public abstract void onAccuracyChanged(Sensor sensor, int accuracy);
+
+ @Override
+ public abstract void onSensorChanged(SensorEvent event);
+ }
+
/**
* This class filters the raw accelerometer data and tries to detect actual changes in
* orientation. This is a very ill-defined problem so there are a lot of tweakable parameters,
@@ -252,13 +337,10 @@
* See http://en.wikipedia.org/wiki/Low-pass_filter#Discrete-time_realization for
* signal processing background.
*/
- final class SensorEventListenerImpl implements SensorEventListener {
+ final class AccelSensorJudge extends OrientationJudge {
// We work with all angles in degrees in this class.
private static final float RADIANS_TO_DEGREES = (float) (180 / Math.PI);
- // Number of nanoseconds per millisecond.
- private static final long NANOS_PER_MS = 1000000;
-
// Indices into SensorEvent.values for the accelerometer sensor.
private static final int ACCELEROMETER_DATA_X = 0;
private static final int ACCELEROMETER_DATA_Y = 1;
@@ -286,11 +368,6 @@
private static final long PROPOSAL_MIN_TIME_SINCE_ACCELERATION_ENDED_NANOS =
500 * NANOS_PER_MS;
- // The minimum amount of time that must have elapsed since the screen was last touched
- // before the proposed rotation can change.
- private static final long PROPOSAL_MIN_TIME_SINCE_TOUCH_END_NANOS =
- 500 * NANOS_PER_MS;
-
// If the tilt angle remains greater than the specified angle for a minimum of
// the specified time, then the device is deemed to be lying flat
// (just chillin' on a table).
@@ -434,7 +511,7 @@
private long[] mTiltHistoryTimestampNanos = new long[TILT_HISTORY_SIZE];
private int mTiltHistoryIndex;
- public SensorEventListenerImpl(Context context) {
+ public AccelSensorJudge(Context context) {
// Load tilt tolerance configuration.
int[] tiltTolerance = context.getResources().getIntArray(
com.android.internal.R.array.config_autoRotationTiltTolerance);
@@ -455,11 +532,15 @@
}
}
+ @Override
public int getProposedRotationLocked() {
return mProposedRotation;
}
+ @Override
public void dumpLocked(PrintWriter pw, String prefix) {
+ pw.println(prefix + "AccelSensorJudge");
+ prefix += " ";
pw.println(prefix + "mProposedRotation=" + mProposedRotation);
pw.println(prefix + "mPredictedRotation=" + mPredictedRotation);
pw.println(prefix + "mLastFilteredX=" + mLastFilteredX);
@@ -689,6 +770,33 @@
}
}
+ @Override
+ public void onTouchStartLocked() {
+ mTouched = true;
+ }
+
+ @Override
+ public void onTouchEndLocked(long whenElapsedNanos) {
+ mTouched = false;
+ mTouchEndedTimestampNanos = whenElapsedNanos;
+ }
+
+ @Override
+ public void resetLocked() {
+ mLastFilteredTimestampNanos = Long.MIN_VALUE;
+ mProposedRotation = -1;
+ mFlatTimestampNanos = Long.MIN_VALUE;
+ mFlat = false;
+ mSwingTimestampNanos = Long.MIN_VALUE;
+ mSwinging = false;
+ mAccelerationTimestampNanos = Long.MIN_VALUE;
+ mAccelerating = false;
+ mOverhead = false;
+ clearPredictedRotationLocked();
+ clearTiltHistoryLocked();
+ }
+
+
/**
* Returns true if the tilt angle is acceptable for a given predicted rotation.
*/
@@ -787,20 +895,6 @@
return true;
}
- private void resetLocked() {
- mLastFilteredTimestampNanos = Long.MIN_VALUE;
- mProposedRotation = -1;
- mFlatTimestampNanos = Long.MIN_VALUE;
- mFlat = false;
- mSwingTimestampNanos = Long.MIN_VALUE;
- mSwinging = false;
- mAccelerationTimestampNanos = Long.MIN_VALUE;
- mAccelerating = false;
- mOverhead = false;
- clearPredictedRotationLocked();
- clearTiltHistoryLocked();
- }
-
private void clearPredictedRotationLocked() {
mPredictedRotation = -1;
mPredictedRotationTimestampNanos = Long.MIN_VALUE;
@@ -869,14 +963,138 @@
private float remainingMS(long now, long until) {
return now >= until ? 0 : (until - now) * 0.000001f;
}
+ }
- private void onTouchStartLocked() {
- mTouched = true;
+ final class OrientationSensorJudge extends OrientationJudge {
+ private boolean mTouching;
+ private long mTouchEndedTimestampNanos = Long.MIN_VALUE;
+ private int mProposedRotation = -1;
+ private int mDesiredRotation = -1;
+ private boolean mRotationEvaluationScheduled;
+
+ @Override
+ public int getProposedRotationLocked() {
+ return mProposedRotation;
}
- private void onTouchEndLocked(long whenElapsedNanos) {
- mTouched = false;
+ @Override
+ public void onTouchStartLocked() {
+ mTouching = true;
+ }
+
+ @Override
+ public void onTouchEndLocked(long whenElapsedNanos) {
+ mTouching = false;
mTouchEndedTimestampNanos = whenElapsedNanos;
+ if (mDesiredRotation != mProposedRotation) {
+ final long now = SystemClock.elapsedRealtimeNanos();
+ scheduleRotationEvaluationIfNecessaryLocked(now);
+ }
}
+
+
+ @Override
+ public void onSensorChanged(SensorEvent event) {
+ synchronized (mLock) {
+ mDesiredRotation = (int) event.values[0];
+ evaluateRotationChangeLocked();
+ }
+ }
+
+ @Override
+ public void onAccuracyChanged(Sensor sensor, int accuracy) { }
+
+ @Override
+ public void dumpLocked(PrintWriter pw, String prefix) {
+ pw.println(prefix + "OrientationSensorJudge");
+ prefix += " ";
+ pw.println(prefix + "mDesiredRotation=" + mDesiredRotation);
+ pw.println(prefix + "mProposedRotation=" + mProposedRotation);
+ pw.println(prefix + "mTouching=" + mTouching);
+ pw.println(prefix + "mTouchEndedTimestampNanos=" + mTouchEndedTimestampNanos);
+ }
+
+ @Override
+ public void resetLocked() {
+ mProposedRotation = -1;
+ mDesiredRotation = -1;
+ mTouching = false;
+ mTouchEndedTimestampNanos = Long.MIN_VALUE;
+ unscheduleRotationEvaluationLocked();
+ }
+
+ public void evaluateRotationChangeLocked() {
+ unscheduleRotationEvaluationLocked();
+ if (mDesiredRotation == mProposedRotation) {
+ return;
+ }
+ final long now = SystemClock.elapsedRealtimeNanos();
+ if (isDesiredRotationAcceptableLocked(now)) {
+ mProposedRotation = mDesiredRotation;
+ onProposedRotationChanged(mProposedRotation);
+ } else {
+ scheduleRotationEvaluationIfNecessaryLocked(now);
+ }
+ }
+
+ private boolean isDesiredRotationAcceptableLocked(long now) {
+ if (mTouching) {
+ return false;
+ }
+ if (now < mTouchEndedTimestampNanos + PROPOSAL_MIN_TIME_SINCE_TOUCH_END_NANOS) {
+ return false;
+ }
+ return true;
+ }
+
+ private void scheduleRotationEvaluationIfNecessaryLocked(long now) {
+ if (mRotationEvaluationScheduled || mDesiredRotation == mProposedRotation) {
+ if (LOG) {
+ Slog.d(TAG, "scheduleRotationEvaluationLocked: " +
+ "ignoring, an evaluation is already scheduled or is unnecessary.");
+ }
+ return;
+ }
+ if (mTouching) {
+ if (LOG) {
+ Slog.d(TAG, "scheduleRotationEvaluationLocked: " +
+ "ignoring, user is still touching the screen.");
+ }
+ return;
+ }
+ long timeOfNextPossibleRotationNanos =
+ mTouchEndedTimestampNanos + PROPOSAL_MIN_TIME_SINCE_TOUCH_END_NANOS;
+ if (now >= timeOfNextPossibleRotationNanos) {
+ if (LOG) {
+ Slog.d(TAG, "scheduleRotationEvaluationLocked: " +
+ "ignoring, already past the next possible time of rotation.");
+ }
+ return;
+ }
+ // Use a delay instead of an absolute time since handlers are in uptime millis and we
+ // use elapsed realtime.
+ final long delayMs =
+ (long) Math.ceil((timeOfNextPossibleRotationNanos - now) * MILLIS_PER_NANO);
+ mHandler.postDelayed(mRotationEvaluator, delayMs);
+ mRotationEvaluationScheduled = true;
+ }
+
+ private void unscheduleRotationEvaluationLocked() {
+ if (!mRotationEvaluationScheduled) {
+ return;
+ }
+ mHandler.removeCallbacks(mRotationEvaluator);
+ mRotationEvaluationScheduled = false;
+ }
+
+ private Runnable mRotationEvaluator = new Runnable() {
+ @Override
+ public void run() {
+ synchronized (mLock) {
+ mRotationEvaluationScheduled = false;
+ evaluateRotationChangeLocked();
+ }
+ }
+ };
}
}
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
index 5d52307..6b45941 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
@@ -32,6 +32,14 @@
private static final String TAG = "KeyguardServiceDelegate";
private static final boolean DEBUG = true;
+ private static final int SCREEN_STATE_OFF = 0;
+ private static final int SCREEN_STATE_TURNING_ON = 1;
+ private static final int SCREEN_STATE_ON = 2;
+
+ private static final int INTERACTIVE_STATE_SLEEP = 0;
+ private static final int INTERACTIVE_STATE_AWAKE = 1;
+ private static final int INTERACTIVE_STATE_GOING_TO_SLEEP = 2;
+
protected KeyguardServiceWrapper mKeyguardService;
private final Context mContext;
private final View mScrim; // shown if keyguard crashes
@@ -61,6 +69,8 @@
public int offReason;
public int currentUser;
public boolean bootCompleted;
+ public int screenState;
+ public int interactiveState;
};
public interface DrawnListener {
@@ -144,10 +154,17 @@
// If the system is ready, it means keyguard crashed and restarted.
mKeyguardService.onSystemReady();
// This is used to hide the scrim once keyguard displays.
- mKeyguardService.onStartedWakingUp();
- mKeyguardService.onScreenTurningOn(
- new KeyguardShowDelegate(mDrawnListenerWhenConnect));
- mKeyguardService.onScreenTurnedOn();
+ if (mKeyguardState.interactiveState == INTERACTIVE_STATE_AWAKE) {
+ mKeyguardService.onStartedWakingUp();
+ }
+ if (mKeyguardState.screenState == SCREEN_STATE_ON
+ || mKeyguardState.screenState == SCREEN_STATE_TURNING_ON) {
+ mKeyguardService.onScreenTurningOn(
+ new KeyguardShowDelegate(mDrawnListenerWhenConnect));
+ }
+ if (mKeyguardState.screenState == SCREEN_STATE_ON) {
+ mKeyguardService.onScreenTurnedOn();
+ }
mDrawnListenerWhenConnect = null;
}
if (mKeyguardState.bootCompleted) {
@@ -231,6 +248,7 @@
if (DEBUG) Log.v(TAG, "onStartedWakingUp()");
mKeyguardService.onStartedWakingUp();
}
+ mKeyguardState.interactiveState = INTERACTIVE_STATE_AWAKE;
}
public void onScreenTurnedOff() {
@@ -238,6 +256,7 @@
if (DEBUG) Log.v(TAG, "onScreenTurnedOff()");
mKeyguardService.onScreenTurnedOff();
}
+ mKeyguardState.screenState = SCREEN_STATE_OFF;
}
public void onScreenTurningOn(final DrawnListener drawnListener) {
@@ -252,6 +271,7 @@
mDrawnListenerWhenConnect = drawnListener;
showScrim();
}
+ mKeyguardState.screenState = SCREEN_STATE_TURNING_ON;
}
public void onScreenTurnedOn() {
@@ -259,6 +279,7 @@
if (DEBUG) Log.v(TAG, "onScreenTurnedOn()");
mKeyguardService.onScreenTurnedOn();
}
+ mKeyguardState.screenState = SCREEN_STATE_ON;
}
public void onStartedGoingToSleep(int why) {
@@ -266,12 +287,14 @@
mKeyguardService.onStartedGoingToSleep(why);
}
mKeyguardState.offReason = why;
+ mKeyguardState.interactiveState = INTERACTIVE_STATE_GOING_TO_SLEEP;
}
public void onFinishedGoingToSleep(int why) {
if (mKeyguardService != null) {
mKeyguardService.onFinishedGoingToSleep(why);
}
+ mKeyguardState.interactiveState = INTERACTIVE_STATE_SLEEP;
}
public void setKeyguardEnabled(boolean enabled) {
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 2a817ea..8663254 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -494,6 +494,15 @@
}
@Override
+ public void showKeyboardShortcutsMenu() {
+ if (mBar != null) {
+ try {
+ mBar.showKeyboardShortcutsMenu();
+ } catch (RemoteException ex) {}
+ }
+ }
+
+ @Override
public void setCurrentUser(int newUserId) {
if (SPEW) Slog.d(TAG, "Setting current user to user " + newUserId);
mCurrentUserId = newUserId;
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index b9e8851..f9d29ac 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -19,6 +19,7 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.content.PackageMonitor;
import com.android.internal.widget.LockPatternUtils;
+import com.android.internal.widget.LockPatternUtils.StrongAuthTracker;
import com.android.server.SystemService;
import org.xmlpull.v1.XmlPullParser;
@@ -59,6 +60,7 @@
import android.util.Log;
import android.util.Slog;
import android.util.SparseBooleanArray;
+import android.util.SparseIntArray;
import android.util.Xml;
import android.view.IWindowManager;
import android.view.WindowManagerGlobal;
@@ -96,16 +98,15 @@
private static final int MSG_UNREGISTER_LISTENER = 2;
private static final int MSG_DISPATCH_UNLOCK_ATTEMPT = 3;
private static final int MSG_ENABLED_AGENTS_CHANGED = 4;
- private static final int MSG_REQUIRE_CREDENTIAL_ENTRY = 5;
private static final int MSG_KEYGUARD_SHOWING_CHANGED = 6;
private static final int MSG_START_USER = 7;
private static final int MSG_CLEANUP_USER = 8;
private static final int MSG_SWITCH_USER = 9;
- private final ArraySet<AgentInfo> mActiveAgents = new ArraySet<AgentInfo>();
- private final ArrayList<ITrustListener> mTrustListeners = new ArrayList<ITrustListener>();
+ private final ArraySet<AgentInfo> mActiveAgents = new ArraySet<>();
+ private final ArrayList<ITrustListener> mTrustListeners = new ArrayList<>();
private final Receiver mReceiver = new Receiver();
- private final SparseBooleanArray mUserHasAuthenticated = new SparseBooleanArray();
+
/* package */ final TrustArchive mArchive = new TrustArchive();
private final Context mContext;
private final LockPatternUtils mLockPatternUtils;
@@ -118,9 +119,6 @@
@GuardedBy("mDeviceLockedForUser")
private final SparseBooleanArray mDeviceLockedForUser = new SparseBooleanArray();
- @GuardedBy("mUserHasAuthenticatedSinceBoot")
- private final SparseBooleanArray mUserHasAuthenticatedSinceBoot = new SparseBooleanArray();
-
private boolean mTrustAgentsCanRun = false;
private int mCurrentUser = UserHandle.USER_SYSTEM;
@@ -146,6 +144,7 @@
if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
mPackageMonitor.register(mContext, mHandler.getLooper(), UserHandle.ALL, true);
mReceiver.register(mContext);
+ mLockPatternUtils.registerStrongAuthTracker(mStrongAuthTracker);
} else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
mTrustAgentsCanRun = true;
refreshAgentList(UserHandle.USER_ALL);
@@ -230,7 +229,7 @@
if (!userInfo.supportsSwitchToByUser()) continue;
if (!mActivityManager.isUserRunning(userInfo.id)) continue;
if (!lockPatternUtils.isSecure(userInfo.id)) continue;
- if (!getUserHasAuthenticated(userInfo.id)) continue;
+ if (!mStrongAuthTracker.isTrustAllowedForUser(userInfo.id)) continue;
DevicePolicyManager dpm = lockPatternUtils.getDevicePolicyManager();
int disabledFeatures = dpm.getKeyguardDisabledFeatures(null, userInfo.id);
final boolean disableTrustAgents =
@@ -509,7 +508,7 @@
// Agent dispatch and aggregation
private boolean aggregateIsTrusted(int userId) {
- if (!getUserHasAuthenticated(userId)) {
+ if (!mStrongAuthTracker.isTrustAllowedForUser(userId)) {
return false;
}
for (int i = 0; i < mActiveAgents.size(); i++) {
@@ -524,7 +523,7 @@
}
private boolean aggregateIsTrustManaged(int userId) {
- if (!getUserHasAuthenticated(userId)) {
+ if (!mStrongAuthTracker.isTrustAllowedForUser(userId)) {
return false;
}
for (int i = 0; i < mActiveAgents.size(); i++) {
@@ -545,54 +544,6 @@
info.agent.onUnlockAttempt(successful);
}
}
-
- if (successful) {
- updateUserHasAuthenticated(userId);
- }
- }
-
- private void updateUserHasAuthenticated(int userId) {
- boolean changed = setUserHasAuthenticated(userId);
- if (changed) {
- refreshAgentList(userId);
- }
- }
-
- private boolean getUserHasAuthenticated(int userId) {
- return mUserHasAuthenticated.get(userId);
- }
-
- /**
- * @return whether the value has changed
- */
- private boolean setUserHasAuthenticated(int userId) {
- if (!mUserHasAuthenticated.get(userId)) {
- mUserHasAuthenticated.put(userId, true);
- synchronized (mUserHasAuthenticatedSinceBoot) {
- mUserHasAuthenticatedSinceBoot.put(userId, true);
- }
- return true;
- }
- return false;
- }
-
- private void clearUserHasAuthenticated(int userId) {
- if (userId == UserHandle.USER_ALL) {
- mUserHasAuthenticated.clear();
- } else {
- mUserHasAuthenticated.put(userId, false);
- }
- }
-
- private boolean getUserHasAuthenticatedSinceBoot(int userId) {
- synchronized (mUserHasAuthenticatedSinceBoot) {
- return mUserHasAuthenticatedSinceBoot.get(userId);
- }
- }
-
- private void requireCredentialEntry(int userId) {
- clearUserHasAuthenticated(userId);
- refreshAgentList(userId);
}
// Listeners
@@ -681,17 +632,6 @@
}
@Override
- public void reportRequireCredentialEntry(int userId) throws RemoteException {
- enforceReportPermission();
- if (userId == UserHandle.USER_ALL || userId >= UserHandle.USER_SYSTEM) {
- mHandler.obtainMessage(MSG_REQUIRE_CREDENTIAL_ENTRY, userId, 0).sendToTarget();
- } else {
- throw new IllegalArgumentException(
- "userId must be an explicit user id or USER_ALL");
- }
- }
-
- @Override
public void reportKeyguardShowingChanged() throws RemoteException {
enforceReportPermission();
// coalesce refresh messages.
@@ -734,18 +674,6 @@
}
}
- @Override
- public boolean hasUserAuthenticatedSinceBoot(int userId) throws RemoteException {
- mContext.enforceCallingOrSelfPermission(
- Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE, null);
- long token = Binder.clearCallingIdentity();
- try {
- return getUserHasAuthenticatedSinceBoot(userId);
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
private void enforceReportPermission() {
mContext.enforceCallingOrSelfPermission(
Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE, "reporting trust events");
@@ -794,9 +722,8 @@
fout.print(": trusted=" + dumpBool(aggregateIsTrusted(user.id)));
fout.print(", trustManaged=" + dumpBool(aggregateIsTrustManaged(user.id)));
fout.print(", deviceLocked=" + dumpBool(isDeviceLockedInner(user.id)));
- fout.print(", hasAuthenticated=" + dumpBool(getUserHasAuthenticated(user.id)));
- fout.print(", hasAuthenticatedSinceBoot="
- + dumpBool(getUserHasAuthenticatedSinceBoot(user.id)));
+ fout.print(", strongAuthRequired=" + dumpHex(
+ mStrongAuthTracker.getStrongAuthForUser(user.id)));
fout.println();
fout.println(" Enabled agents:");
boolean duplicateSimpleNames = false;
@@ -831,6 +758,10 @@
private String dumpBool(boolean b) {
return b ? "1" : "0";
}
+
+ private String dumpHex(int i) {
+ return "0x" + Integer.toHexString(i);
+ }
};
private int resolveProfileParent(int userId) {
@@ -864,9 +795,6 @@
// This is also called when the security mode of a user changes.
refreshDeviceLockedForUser(UserHandle.USER_ALL);
break;
- case MSG_REQUIRE_CREDENTIAL_ENTRY:
- requireCredentialEntry(msg.arg1);
- break;
case MSG_KEYGUARD_SHOWING_CHANGED:
refreshDeviceLockedForUser(mCurrentUser);
break;
@@ -900,6 +828,13 @@
}
};
+ private final StrongAuthTracker mStrongAuthTracker = new StrongAuthTracker() {
+ @Override
+ public void onStrongAuthRequiredChanged(int userId) {
+ refreshAgentList(userId);
+ }
+ };
+
private class Receiver extends BroadcastReceiver {
@Override
@@ -908,8 +843,6 @@
if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(action)) {
refreshAgentList(getSendingUserId());
updateDevicePolicyFeatures();
- } else if (Intent.ACTION_USER_PRESENT.equals(action)) {
- updateUserHasAuthenticated(getSendingUserId());
} else if (Intent.ACTION_USER_ADDED.equals(action)) {
int userId = getUserId(intent);
if (userId > 0) {
@@ -918,7 +851,6 @@
} else if (Intent.ACTION_USER_REMOVED.equals(action)) {
int userId = getUserId(intent);
if (userId > 0) {
- mUserHasAuthenticated.delete(userId);
synchronized (mUserIsTrusted) {
mUserIsTrusted.delete(userId);
}
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index dfdb29c..d1145d0 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -26,6 +26,8 @@
import android.os.IBinder;
import android.os.IRemoteCallback;
import android.util.Slog;
+import android.util.SparseArray;
+import android.view.AppTransitionAnimationSpec;
import android.view.WindowManager;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
@@ -153,22 +155,25 @@
private static final int THUMBNAIL_TRANSITION_EXIT_SCALE_DOWN = 3;
private String mNextAppTransitionPackage;
- private Bitmap mNextAppTransitionThumbnail;
// Used for thumbnail transitions. True if we're scaling up, false if scaling down
private boolean mNextAppTransitionScaleUp;
private IRemoteCallback mNextAppTransitionCallback;
private int mNextAppTransitionEnter;
private int mNextAppTransitionExit;
private int mNextAppTransitionInPlace;
- private int mNextAppTransitionStartX;
- private int mNextAppTransitionStartY;
- private int mNextAppTransitionStartWidth;
- private int mNextAppTransitionStartHeight;
+
+ // Keyed by task id.
+ private final SparseArray<AppTransitionAnimationSpec> mNextAppTransitionAnimationsSpecs
+ = new SparseArray<>();
+ private AppTransitionAnimationSpec mDefaultNextAppTransitionAnimationSpec;
+
private Rect mNextAppTransitionInsets = new Rect();
private Rect mTmpFromClipRect = new Rect();
private Rect mTmpToClipRect = new Rect();
+ private final Rect mTmpStartRect = new Rect();
+
private final static int APP_STATE_IDLE = 0;
private final static int APP_STATE_READY = 1;
private final static int APP_STATE_RUNNING = 2;
@@ -276,8 +281,9 @@
mAppTransitionState = APP_STATE_TIMEOUT;
}
- Bitmap getNextAppTransitionThumbnail() {
- return mNextAppTransitionThumbnail;
+ Bitmap getAppTransitionThumbnailHeader(int taskId) {
+ AppTransitionAnimationSpec spec = mNextAppTransitionAnimationsSpecs.get(taskId);
+ return spec != null ? spec.bitmap : null;
}
/** Returns whether the next thumbnail transition is aspect scaled up. */
@@ -291,14 +297,6 @@
return mNextAppTransitionScaleUp;
}
- int getStartingX() {
- return mNextAppTransitionStartX;
- }
-
- int getStartingY() {
- return mNextAppTransitionStartY;
- }
-
boolean prepare() {
if (!isRunning()) {
mAppTransitionState = APP_STATE_IDLE;
@@ -321,7 +319,7 @@
void clear() {
mNextAppTransitionType = NEXT_TRANSIT_TYPE_NONE;
mNextAppTransitionPackage = null;
- mNextAppTransitionThumbnail = null;
+ mNextAppTransitionAnimationsSpecs.clear();
}
void freeze() {
@@ -459,16 +457,17 @@
return -startPos / denom;
}
- private Animation createScaleUpAnimationLocked(int transit, boolean enter,
- int appWidth, int appHeight) {
+ private Animation createScaleUpAnimationLocked(
+ int transit, boolean enter, int appWidth, int appHeight) {
Animation a = null;
+ getDefaultNextAppTransitionStartRect(mTmpStartRect);
if (enter) {
// Entering app zooms out from the center of the initial rect.
- float scaleW = mNextAppTransitionStartWidth / (float) appWidth;
- float scaleH = mNextAppTransitionStartHeight / (float) appHeight;
+ float scaleW = mTmpStartRect.width() / (float) appWidth;
+ float scaleH = mTmpStartRect.height() / (float) appHeight;
Animation scale = new ScaleAnimation(scaleW, 1, scaleH, 1,
- computePivot(mNextAppTransitionStartX, scaleW),
- computePivot(mNextAppTransitionStartY, scaleH));
+ computePivot(mTmpStartRect.left, scaleW),
+ computePivot(mTmpStartRect.right, scaleH));
scale.setInterpolator(mDecelerateInterpolator);
Animation alpha = new AlphaAnimation(0, 1);
@@ -512,6 +511,32 @@
return a;
}
+ private void getDefaultNextAppTransitionStartRect(Rect rect) {
+ if (mDefaultNextAppTransitionAnimationSpec == null ||
+ mDefaultNextAppTransitionAnimationSpec.rect == null) {
+ Slog.wtf(TAG, "Starting rect for app requested, but none available", new Throwable());
+ rect.setEmpty();
+ } else {
+ rect.set(mDefaultNextAppTransitionAnimationSpec.rect);
+ }
+ }
+
+ void getNextAppTransitionStartRect(int taskId, Rect rect) {
+ AppTransitionAnimationSpec spec = mNextAppTransitionAnimationsSpecs.get(taskId);
+ if (spec == null || spec.rect == null) {
+ Slog.wtf(TAG, "Starting rect for task: " + taskId + " requested, but not available",
+ new Throwable());
+ rect.setEmpty();
+ } else {
+ rect.set(spec.rect);
+ }
+ }
+
+ private void putDefaultNextAppTransitionCoordinates(int left, int top, int width, int height) {
+ mDefaultNextAppTransitionAnimationSpec = new AppTransitionAnimationSpec(-1 /* taskId */,
+ null /* bitmap */, new Rect(left, top, left + width, top + height));
+ }
+
private Animation createClipRevealAnimationLocked(int transit, boolean enter, Rect appFrame) {
final Animation anim;
if (enter) {
@@ -519,28 +544,27 @@
final int appWidth = appFrame.width();
final int appHeight = appFrame.height();
+ getDefaultNextAppTransitionStartRect(mTmpStartRect);
float t = 0f;
if (appHeight > 0) {
- t = (float) mNextAppTransitionStartY / appHeight;
+ t = (float) mTmpStartRect.left / appHeight;
}
int translationY = mClipRevealTranslationY
+ (int)(appHeight / 7f * t);
- int centerX = mNextAppTransitionStartX + mNextAppTransitionStartWidth / 2;
- int centerY = mNextAppTransitionStartY + mNextAppTransitionStartHeight / 2;
+ int centerX = mTmpStartRect.centerX();
+ int centerY = mTmpStartRect.centerY();
+ int halfWidth = mTmpStartRect.width() / 2;
+ int halfHeight = mTmpStartRect.height() / 2;
// Clip third of the from size of launch icon, expand to full width/height
Animation clipAnimLR = new ClipRectLRAnimation(
- centerX - mNextAppTransitionStartWidth / 2,
- centerX + mNextAppTransitionStartWidth / 2,
- 0, appWidth);
+ centerX - halfWidth, centerX + halfWidth, 0, appWidth);
clipAnimLR.setInterpolator(mClipHorizontalInterpolator);
clipAnimLR.setDuration((long) (DEFAULT_APP_TRANSITION_DURATION / 2.5f));
- Animation clipAnimTB = new ClipRectTBAnimation(
- centerY - mNextAppTransitionStartHeight / 2 - translationY,
- centerY + mNextAppTransitionStartHeight / 2 - translationY,
- 0, appHeight);
+ Animation clipAnimTB = new ClipRectTBAnimation(centerY - halfHeight - translationY,
+ centerY + halfHeight/ 2 - translationY, 0, appHeight);
clipAnimTB.setInterpolator(mTouchResponseInterpolator);
clipAnimTB.setDuration(DEFAULT_APP_TRANSITION_DURATION);
@@ -649,31 +673,32 @@
/**
* This animation runs for the thumbnail that gets cross faded with the enter/exit activity
- * when a thumbnail is specified with the activity options.
+ * when a thumbnail is specified with the pending animation override.
*/
- Animation createThumbnailAspectScaleAnimationLocked(Rect appRect) {
+ Animation createThumbnailAspectScaleAnimationLocked(Rect appRect, Bitmap thumbnailHeader,
+ final int taskId) {
Animation a;
- final int thumbWidthI = mNextAppTransitionThumbnail.getWidth();
+ final int thumbWidthI = thumbnailHeader.getWidth();
final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1;
- final int thumbHeightI = mNextAppTransitionThumbnail.getHeight();
+ final int thumbHeightI = thumbnailHeader.getHeight();
final float thumbHeight = thumbHeightI > 0 ? thumbHeightI : 1;
final int appWidth = appRect.width();
float scaleW = appWidth / thumbWidth;
float unscaledHeight = thumbHeight * scaleW;
- float unscaledStartY = mNextAppTransitionStartY - (unscaledHeight - thumbHeight) / 2f;
+ getNextAppTransitionStartRect(taskId, mTmpStartRect);
+ float unscaledStartY = mTmpStartRect.top - (unscaledHeight - thumbHeight) / 2f;
if (mNextAppTransitionScaleUp) {
// Animation up from the thumbnail to the full screen
Animation scale = new ScaleAnimation(1f, scaleW, 1f, scaleW,
- mNextAppTransitionStartX + (thumbWidth / 2f),
- mNextAppTransitionStartY + (thumbHeight / 2f));
+ mTmpStartRect.left + (thumbWidth / 2f), mTmpStartRect.top + (thumbHeight / 2f));
scale.setInterpolator(mTouchResponseInterpolator);
scale.setDuration(THUMBNAIL_APP_TRANSITION_DURATION);
Animation alpha = new AlphaAnimation(1, 0);
alpha.setInterpolator(mThumbnailFadeOutInterpolator);
alpha.setDuration(THUMBNAIL_APP_TRANSITION_ALPHA_DURATION);
final float toX = appRect.left + appRect.width() / 2 -
- (mNextAppTransitionStartX + thumbWidth / 2);
+ (mTmpStartRect.left + thumbWidth / 2);
final float toY = appRect.top + mNextAppTransitionInsets.top + -unscaledStartY;
Animation translate = new TranslateAnimation(0, toX, 0, toY);
translate.setInterpolator(mTouchResponseInterpolator);
@@ -688,8 +713,7 @@
} else {
// Animation down from the full screen to the thumbnail
Animation scale = new ScaleAnimation(scaleW, 1f, scaleW, 1f,
- mNextAppTransitionStartX + (thumbWidth / 2f),
- mNextAppTransitionStartY + (thumbHeight / 2f));
+ mTmpStartRect.left + (thumbWidth / 2f), mTmpStartRect.top + (thumbHeight / 2f));
scale.setInterpolator(mTouchResponseInterpolator);
scale.setDuration(THUMBNAIL_APP_TRANSITION_DURATION);
Animation alpha = new AlphaAnimation(0f, 1f);
@@ -718,11 +742,13 @@
*/
Animation createAspectScaledThumbnailEnterExitAnimationLocked(int thumbTransitState,
int appWidth, int appHeight, int orientation, int transit, Rect containingFrame,
- Rect contentInsets, @Nullable Rect surfaceInsets, boolean resizedWindow) {
+ Rect contentInsets, @Nullable Rect surfaceInsets, boolean resizedWindow,
+ int taskId) {
Animation a;
- final int thumbWidthI = mNextAppTransitionStartWidth;
+ getDefaultNextAppTransitionStartRect(mTmpStartRect);
+ final int thumbWidthI = mTmpStartRect.width();
final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1;
- final int thumbHeightI = mNextAppTransitionStartHeight;
+ final int thumbHeightI = mTmpStartRect.height();
final float thumbHeight = thumbHeightI > 0 ? thumbHeightI : 1;
// Used for the ENTER_SCALE_UP and EXIT_SCALE_DOWN transitions
@@ -733,7 +759,7 @@
case THUMBNAIL_TRANSITION_ENTER_SCALE_UP: {
if (resizedWindow) {
a = createAspectScaledThumbnailEnterNonFullscreenAnimationLocked(
- containingFrame, surfaceInsets);
+ containingFrame, surfaceInsets, taskId);
} else {
// App window scaling up to become full screen
if (orientation == Configuration.ORIENTATION_PORTRAIT) {
@@ -759,8 +785,8 @@
mNextAppTransitionInsets.set(contentInsets);
Animation scaleAnim = new ScaleAnimation(scale, 1, scale, 1,
- computePivot(mNextAppTransitionStartX, scale),
- computePivot(mNextAppTransitionStartY, scale));
+ computePivot(mTmpStartRect.left, scale),
+ computePivot(mTmpStartRect.top, scale));
Animation clipAnim = new ClipRectAnimation(mTmpFromClipRect, mTmpToClipRect);
Animation translateAnim = new TranslateAnimation(0, 0, -scaledTopDecor, 0);
@@ -819,8 +845,8 @@
mNextAppTransitionInsets.set(contentInsets);
Animation scaleAnim = new ScaleAnimation(1, scale, 1, scale,
- computePivot(mNextAppTransitionStartX, scale),
- computePivot(mNextAppTransitionStartY, scale));
+ computePivot(mTmpStartRect.left, scale),
+ computePivot(mTmpStartRect.top, scale));
Animation clipAnim = new ClipRectAnimation(mTmpFromClipRect, mTmpToClipRect);
Animation translateAnim = new TranslateAnimation(0, 0, 0, -scaledTopDecor);
@@ -844,11 +870,12 @@
}
private Animation createAspectScaledThumbnailEnterNonFullscreenAnimationLocked(
- Rect containingFrame, @Nullable Rect surfaceInsets) {
+ Rect containingFrame, @Nullable Rect surfaceInsets, int taskId) {
+ getNextAppTransitionStartRect(taskId, mTmpStartRect);
float width = containingFrame.width();
float height = containingFrame.height();
- float scaleWidth = mNextAppTransitionStartWidth / width;
- float scaleHeight = mNextAppTransitionStartHeight / height;
+ float scaleWidth = mTmpStartRect.width() / width;
+ float scaleHeight = mTmpStartRect.height() / height;
AnimationSet set = new AnimationSet(true);
int surfaceInsetsHorizontal = surfaceInsets == null
? 0 : surfaceInsets.left + surfaceInsets.right;
@@ -858,9 +885,9 @@
// we need to account for surface insets that will be used to enlarge the surface.
ScaleAnimation scale = new ScaleAnimation(scaleWidth, 1, scaleHeight, 1,
(width + surfaceInsetsHorizontal) / 2, (height + surfaceInsetsVertical) / 2);
- int fromX = mNextAppTransitionStartX + mNextAppTransitionStartWidth / 2
+ int fromX = mTmpStartRect.left + mTmpStartRect.width() / 2
- (containingFrame.left + containingFrame.width() / 2);
- int fromY = mNextAppTransitionStartY + mNextAppTransitionStartHeight / 2
+ int fromY = mTmpStartRect.top + mTmpStartRect.height() / 2
- (containingFrame.top + containingFrame.height() / 2);
TranslateAnimation translation = new TranslateAnimation(fromX, 0, fromY, 0);
set.addAnimation(scale);
@@ -870,13 +897,15 @@
/**
* This animation runs for the thumbnail that gets cross faded with the enter/exit activity
- * when a thumbnail is specified with the activity options.
+ * when a thumbnail is specified with the pending animation override.
*/
- Animation createThumbnailScaleAnimationLocked(int appWidth, int appHeight, int transit) {
+ Animation createThumbnailScaleAnimationLocked(int appWidth, int appHeight, int transit,
+ Bitmap thumbnailHeader) {
Animation a;
- final int thumbWidthI = mNextAppTransitionThumbnail.getWidth();
+ getDefaultNextAppTransitionStartRect(mTmpStartRect);
+ final int thumbWidthI = thumbnailHeader.getWidth();
final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1;
- final int thumbHeightI = mNextAppTransitionThumbnail.getHeight();
+ final int thumbHeightI = thumbnailHeader.getHeight();
final float thumbHeight = thumbHeightI > 0 ? thumbHeightI : 1;
if (mNextAppTransitionScaleUp) {
@@ -884,8 +913,8 @@
float scaleW = appWidth / thumbWidth;
float scaleH = appHeight / thumbHeight;
Animation scale = new ScaleAnimation(1, scaleW, 1, scaleH,
- computePivot(mNextAppTransitionStartX, 1 / scaleW),
- computePivot(mNextAppTransitionStartY, 1 / scaleH));
+ computePivot(mTmpStartRect.left, 1 / scaleW),
+ computePivot(mTmpStartRect.top, 1 / scaleH));
scale.setInterpolator(mDecelerateInterpolator);
Animation alpha = new AlphaAnimation(1, 0);
@@ -901,8 +930,8 @@
float scaleW = appWidth / thumbWidth;
float scaleH = appHeight / thumbHeight;
a = new ScaleAnimation(scaleW, 1, scaleH, 1,
- computePivot(mNextAppTransitionStartX, 1 / scaleW),
- computePivot(mNextAppTransitionStartY, 1 / scaleH));
+ computePivot(mTmpStartRect.left, 1 / scaleW),
+ computePivot(mTmpStartRect.top, 1 / scaleH));
}
return prepareThumbnailAnimation(a, appWidth, appHeight, transit);
@@ -913,11 +942,13 @@
* leaving, and the activity that is entering.
*/
Animation createThumbnailEnterExitAnimationLocked(int thumbTransitState, int appWidth,
- int appHeight, int transit) {
+ int appHeight, int transit, int taskId) {
+ Bitmap thumbnailHeader = getAppTransitionThumbnailHeader(taskId);
Animation a;
- final int thumbWidthI = mNextAppTransitionThumbnail.getWidth();
+ getDefaultNextAppTransitionStartRect(mTmpStartRect);
+ final int thumbWidthI = thumbnailHeader != null ? thumbnailHeader.getWidth() : appWidth;
final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1;
- final int thumbHeightI = mNextAppTransitionThumbnail.getHeight();
+ final int thumbHeightI = thumbnailHeader != null ? thumbnailHeader.getHeight() : appHeight;
final float thumbHeight = thumbHeightI > 0 ? thumbHeightI : 1;
switch (thumbTransitState) {
@@ -926,8 +957,8 @@
float scaleW = thumbWidth / appWidth;
float scaleH = thumbHeight / appHeight;
a = new ScaleAnimation(scaleW, 1, scaleH, 1,
- computePivot(mNextAppTransitionStartX, scaleW),
- computePivot(mNextAppTransitionStartY, scaleH));
+ computePivot(mTmpStartRect.left, scaleW),
+ computePivot(mTmpStartRect.top, scaleH));
break;
}
case THUMBNAIL_TRANSITION_EXIT_SCALE_UP: {
@@ -954,8 +985,8 @@
float scaleW = thumbWidth / appWidth;
float scaleH = thumbHeight / appHeight;
Animation scale = new ScaleAnimation(1, scaleW, 1, scaleH,
- computePivot(mNextAppTransitionStartX, scaleW),
- computePivot(mNextAppTransitionStartY, scaleH));
+ computePivot(mTmpStartRect.left, scaleW),
+ computePivot(mTmpStartRect.top, scaleH));
Animation alpha = new AlphaAnimation(1, 0);
@@ -987,7 +1018,7 @@
Animation loadAnimation(WindowManager.LayoutParams lp, int transit, boolean enter,
int appWidth, int appHeight, int orientation, Rect containingFrame, Rect contentInsets,
@Nullable Rect surfaceInsets, Rect appFrame, boolean isVoiceInteraction,
- boolean resizedWindow) {
+ boolean resizedWindow, int taskId) {
Animation a;
if (isVoiceInteraction && (transit == TRANSIT_ACTIVITY_OPEN
|| transit == TRANSIT_TASK_OPEN
@@ -1042,7 +1073,7 @@
mNextAppTransitionScaleUp =
(mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP);
a = createThumbnailEnterExitAnimationLocked(getThumbnailTransitionState(enter),
- appWidth, appHeight, transit);
+ appWidth, appHeight, transit, taskId);
if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) {
String animName = mNextAppTransitionScaleUp ?
"ANIM_THUMBNAIL_SCALE_UP" : "ANIM_THUMBNAIL_SCALE_DOWN";
@@ -1057,7 +1088,7 @@
(mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP);
a = createAspectScaledThumbnailEnterExitAnimationLocked(
getThumbnailTransitionState(enter), appWidth, appHeight, orientation, transit,
- containingFrame, contentInsets, surfaceInsets, resizedWindow);
+ containingFrame, contentInsets, surfaceInsets, resizedWindow, taskId);
if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) {
String animName = mNextAppTransitionScaleUp ?
"ANIM_THUMBNAIL_ASPECT_SCALE_UP" : "ANIM_THUMBNAIL_ASPECT_SCALE_DOWN";
@@ -1147,7 +1178,7 @@
if (isTransitionSet()) {
mNextAppTransitionType = NEXT_TRANSIT_TYPE_CUSTOM;
mNextAppTransitionPackage = packageName;
- mNextAppTransitionThumbnail = null;
+ mNextAppTransitionAnimationsSpecs.clear();
mNextAppTransitionEnter = enterAnim;
mNextAppTransitionExit = exitAnim;
postAnimationCallback();
@@ -1158,15 +1189,13 @@
}
void overridePendingAppTransitionScaleUp(int startX, int startY, int startWidth,
- int startHeight) {
+ int startHeight) {
if (isTransitionSet()) {
mNextAppTransitionType = NEXT_TRANSIT_TYPE_SCALE_UP;
mNextAppTransitionPackage = null;
- mNextAppTransitionThumbnail = null;
- mNextAppTransitionStartX = startX;
- mNextAppTransitionStartY = startY;
- mNextAppTransitionStartWidth = startWidth;
- mNextAppTransitionStartHeight = startHeight;
+ mNextAppTransitionAnimationsSpecs.clear();
+ putDefaultNextAppTransitionCoordinates(startX, startY, startX + startWidth,
+ startY + startHeight);
postAnimationCallback();
mNextAppTransitionCallback = null;
}
@@ -1176,10 +1205,7 @@
int startWidth, int startHeight) {
if (isTransitionSet()) {
mNextAppTransitionType = NEXT_TRANSIT_TYPE_CLIP_REVEAL;
- mNextAppTransitionStartX = startX;
- mNextAppTransitionStartY = startY;
- mNextAppTransitionStartWidth = startWidth;
- mNextAppTransitionStartHeight = startHeight;
+ putDefaultNextAppTransitionCoordinates(startX, startY, startWidth, startHeight);
postAnimationCallback();
mNextAppTransitionCallback = null;
}
@@ -1191,10 +1217,9 @@
mNextAppTransitionType = scaleUp ? NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP
: NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN;
mNextAppTransitionPackage = null;
- mNextAppTransitionThumbnail = srcThumb;
+ mNextAppTransitionAnimationsSpecs.clear();
mNextAppTransitionScaleUp = scaleUp;
- mNextAppTransitionStartX = startX;
- mNextAppTransitionStartY = startY;
+ putDefaultNextAppTransitionCoordinates(startX, startY, 0 ,0);
postAnimationCallback();
mNextAppTransitionCallback = startedCallback;
} else {
@@ -1208,12 +1233,9 @@
mNextAppTransitionType = scaleUp ? NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP
: NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN;
mNextAppTransitionPackage = null;
- mNextAppTransitionThumbnail = srcThumb;
+ mNextAppTransitionAnimationsSpecs.clear();
mNextAppTransitionScaleUp = scaleUp;
- mNextAppTransitionStartX = startX;
- mNextAppTransitionStartY = startY;
- mNextAppTransitionStartWidth = targetWidth;
- mNextAppTransitionStartHeight = targetHeight;
+ putDefaultNextAppTransitionCoordinates(startX, startY, targetWidth, targetHeight);
postAnimationCallback();
mNextAppTransitionCallback = startedCallback;
} else {
@@ -1221,6 +1243,27 @@
}
}
+ public void overridePendingAppTransitionMultiThumb(AppTransitionAnimationSpec[] specs,
+ IRemoteCallback callback, boolean scaleUp) {
+ if (isTransitionSet()) {
+ mNextAppTransitionType = scaleUp ? NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP
+ : NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN;
+ mNextAppTransitionPackage = null;
+ mNextAppTransitionAnimationsSpecs.clear();
+ mNextAppTransitionScaleUp = scaleUp;
+ for (int i = 0; i < specs.length; i++) {
+ AppTransitionAnimationSpec spec = specs[i];
+ if (spec != null) {
+ mNextAppTransitionAnimationsSpecs.put(spec.taskId, spec);
+ }
+ }
+ postAnimationCallback();
+ mNextAppTransitionCallback = callback;
+ } else {
+ postAnimationCallback();
+ }
+ }
+
void overrideInPlaceAppTransition(String packageName, int anim) {
if (isTransitionSet()) {
mNextAppTransitionType = NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE;
@@ -1350,33 +1393,30 @@
pw.print(prefix); pw.print("mNextAppTransitionInPlace=0x");
pw.print(Integer.toHexString(mNextAppTransitionInPlace));
break;
- case NEXT_TRANSIT_TYPE_SCALE_UP:
+ case NEXT_TRANSIT_TYPE_SCALE_UP: {
+ getDefaultNextAppTransitionStartRect(mTmpStartRect);
pw.print(prefix); pw.print("mNextAppTransitionStartX=");
- pw.print(mNextAppTransitionStartX);
+ pw.print(mTmpStartRect.left);
pw.print(" mNextAppTransitionStartY=");
- pw.println(mNextAppTransitionStartY);
+ pw.println(mTmpStartRect.top);
pw.print(prefix); pw.print("mNextAppTransitionStartWidth=");
- pw.print(mNextAppTransitionStartWidth);
+ pw.print(mTmpStartRect.width());
pw.print(" mNextAppTransitionStartHeight=");
- pw.println(mNextAppTransitionStartHeight);
+ pw.println(mTmpStartRect.height());
break;
+ }
case NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP:
case NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN:
case NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP:
- case NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN:
- pw.print(prefix); pw.print("mNextAppTransitionThumbnail=");
- pw.print(mNextAppTransitionThumbnail);
- pw.print(" mNextAppTransitionStartX=");
- pw.print(mNextAppTransitionStartX);
- pw.print(" mNextAppTransitionStartY=");
- pw.println(mNextAppTransitionStartY);
- pw.print(prefix); pw.print("mNextAppTransitionStartWidth=");
- pw.print(mNextAppTransitionStartWidth);
- pw.print(" mNextAppTransitionStartHeight=");
- pw.println(mNextAppTransitionStartHeight);
+ case NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN: {
+ pw.print(prefix); pw.print("mDefaultNextAppTransitionAnimationSpec=");
+ pw.println(mDefaultNextAppTransitionAnimationSpec);
+ pw.print(prefix); pw.print("mNextAppTransitionAnimationsSpecs=");
+ pw.println(mNextAppTransitionAnimationsSpecs);
pw.print(prefix); pw.print("mNextAppTransitionScaleUp=");
pw.println(mNextAppTransitionScaleUp);
break;
+ }
}
if (mNextAppTransitionCallback != null) {
pw.print(prefix); pw.print("mNextAppTransitionCallback=");
diff --git a/services/core/java/com/android/server/wm/AppWindowAnimator.java b/services/core/java/com/android/server/wm/AppWindowAnimator.java
index df7b23d..2828cd0 100644
--- a/services/core/java/com/android/server/wm/AppWindowAnimator.java
+++ b/services/core/java/com/android/server/wm/AppWindowAnimator.java
@@ -193,6 +193,7 @@
final int windowCount = mAppToken.allAppWindows.size();
final int adj = animLayerAdjustment;
thumbnailLayer = -1;
+ final WallpaperController wallpaperController = mService.mWallpaperControllerLocked;
for (int i = 0; i < windowCount; i++) {
final WindowState w = mAppToken.allAppWindows.get(i);
final WindowStateAnimator winAnimator = w.mWinAnimator;
@@ -204,9 +205,7 @@
if (w == mService.mInputMethodTarget && !mService.mInputMethodTargetWaitingAnim) {
mService.setInputMethodAnimLayerAdjustment(adj);
}
- if (w == mService.mWallpaperTarget && mService.mLowerWallpaperTarget == null) {
- mService.setWallpaperAnimLayerAdjustmentLocked(adj);
- }
+ wallpaperController.setAnimLayerAdjustment(w, adj);
}
}
diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java
index 222945c..e87dcde 100644
--- a/services/core/java/com/android/server/wm/DragState.java
+++ b/services/core/java/com/android/server/wm/DragState.java
@@ -16,6 +16,7 @@
package com.android.server.wm;
+import static com.android.server.wm.WindowState.BOUNDS_FOR_TOUCH;
import com.android.server.input.InputApplicationHandle;
import com.android.server.input.InputWindowHandle;
import com.android.server.wm.WindowManagerService.DragInputEventReceiver;
@@ -413,7 +414,7 @@
continue;
}
- child.getTaskBounds(mTmpRect);
+ child.getTaskBounds(mTmpRect, !BOUNDS_FOR_TOUCH);
if (!mTmpRect.contains(x, y)) {
// outside of this window's activity stack == don't tell about drags
continue;
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index 21e92c9..b3244ff 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -16,6 +16,7 @@
package com.android.server.wm;
+import static com.android.server.wm.WindowState.BOUNDS_FOR_TOUCH;
import android.app.ActivityManagerNative;
import android.graphics.Rect;
import android.os.RemoteException;
@@ -177,7 +178,7 @@
if (modal && child.mAppToken != null) {
// Limit the outer touch to the activity stack region.
flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
- child.getTaskBounds(mTmpRect);
+ child.getTaskBounds(mTmpRect, BOUNDS_FOR_TOUCH);
inputWindowHandle.touchableRegion.set(mTmpRect);
} else {
// Not modal or full screen modal
@@ -260,6 +261,7 @@
// Add all windows on the default display.
final int numDisplays = mService.mDisplayContents.size();
+ final WallpaperController wallpaperController = mService.mWallpaperControllerLocked;
for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
WindowList windows = mService.mDisplayContents.valueAt(displayNdx).getWindowList();
for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
@@ -287,7 +289,7 @@
!= 0) {
disableWallpaperTouchEvents = true;
}
- final boolean hasWallpaper = (child == mService.mWallpaperTarget)
+ final boolean hasWallpaper = wallpaperController.isWallpaperTarget(child)
&& (privateFlags & WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD) == 0
&& !disableWallpaperTouchEvents;
final boolean onDefaultDisplay = (child.getDisplayId() == Display.DEFAULT_DISPLAY);
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index 75bb10a..12f61f9 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -403,7 +403,7 @@
synchronized(mService.mWindowMap) {
long ident = Binder.clearCallingIdentity();
try {
- mService.setWindowWallpaperPositionLocked(
+ mService.mWallpaperControllerLocked.setWindowWallpaperPosition(
mService.windowForClientLocked(this, window, true),
x, y, xStep, yStep);
} finally {
@@ -413,14 +413,16 @@
}
public void wallpaperOffsetsComplete(IBinder window) {
- mService.wallpaperOffsetsComplete(window);
+ synchronized (mService.mWindowMap) {
+ mService.mWallpaperControllerLocked.wallpaperOffsetsComplete(window);
+ }
}
public void setWallpaperDisplayOffset(IBinder window, int x, int y) {
synchronized(mService.mWindowMap) {
long ident = Binder.clearCallingIdentity();
try {
- mService.setWindowWallpaperDisplayOffsetLocked(
+ mService.mWallpaperControllerLocked.setWindowWallpaperDisplayOffset(
mService.windowForClientLocked(this, window, true), x, y);
} finally {
Binder.restoreCallingIdentity(ident);
@@ -433,7 +435,7 @@
synchronized(mService.mWindowMap) {
long ident = Binder.clearCallingIdentity();
try {
- return mService.sendWindowWallpaperCommandLocked(
+ return mService.mWallpaperControllerLocked.sendWindowWallpaperCommand(
mService.windowForClientLocked(this, window, true),
action, x, y, z, extras, sync);
} finally {
@@ -443,7 +445,9 @@
}
public void wallpaperCommandComplete(IBinder window, Bundle result) {
- mService.wallpaperCommandComplete(window, result);
+ synchronized (mService.mWindowMap) {
+ mService.mWallpaperControllerLocked.wallpaperCommandComplete(window);
+ }
}
public void onRectangleOnScreenRequested(IBinder token, Rect rectangle) {
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
new file mode 100644
index 0000000..d0962f4
--- /dev/null
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -0,0 +1,916 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import static android.app.ActivityManager.FREEFORM_WORKSPACE_STACK_ID;
+import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
+import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_SCRIM;
+import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
+import static com.android.server.wm.WindowManagerService.DEBUG_ADD_REMOVE;
+import static com.android.server.wm.WindowManagerService.DEBUG_APP_TRANSITIONS;
+import static com.android.server.wm.WindowManagerService.DEBUG_LAYERS;
+import static com.android.server.wm.WindowManagerService.DEBUG_WINDOW_MOVEMENT;
+import static com.android.server.wm.WindowManagerService.DEBUG_VISIBILITY;
+import static com.android.server.wm.WindowManagerService.DEBUG_WALLPAPER;
+import static com.android.server.wm.WindowManagerService.DEBUG_WALLPAPER_LIGHT;
+import static com.android.server.wm.WindowManagerService.H.WALLPAPER_DRAW_PENDING_TIMEOUT;
+import static com.android.server.wm.WindowManagerService.TYPE_LAYER_MULTIPLIER;
+import static com.android.server.wm.WindowManagerService.TYPE_LAYER_OFFSET;
+
+import android.os.Bundle;
+import android.os.Debug;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.util.Slog;
+import android.view.DisplayInfo;
+import android.view.WindowManager;
+import android.view.WindowManagerPolicy;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+
+/**
+ * Controls wallpaper windows visibility, ordering, and so on.
+ * NOTE: All methods in this class must be called with the window manager service lock held.
+ */
+class WallpaperController {
+ private static final String TAG = com.android.server.wm.WindowManagerService.TAG;
+ final private WindowManagerService mService;
+
+ private final ArrayList<WindowToken> mWallpaperTokens = new ArrayList<>();
+
+ // If non-null, this is the currently visible window that is associated
+ // with the wallpaper.
+ private WindowState mWallpaperTarget = null;
+ // If non-null, we are in the middle of animating from one wallpaper target
+ // to another, and this is the lower one in Z-order.
+ private WindowState mLowerWallpaperTarget = null;
+ // If non-null, we are in the middle of animating from one wallpaper target
+ // to another, and this is the higher one in Z-order.
+ private WindowState mUpperWallpaperTarget = null;
+
+ private int mWallpaperAnimLayerAdjustment;
+
+ private float mLastWallpaperX = -1;
+ private float mLastWallpaperY = -1;
+ private float mLastWallpaperXStep = -1;
+ private float mLastWallpaperYStep = -1;
+ private int mLastWallpaperDisplayOffsetX = Integer.MIN_VALUE;
+ private int mLastWallpaperDisplayOffsetY = Integer.MIN_VALUE;
+
+ // This is set when we are waiting for a wallpaper to tell us it is done
+ // changing its scroll position.
+ WindowState mWaitingOnWallpaper;
+
+ // The last time we had a timeout when waiting for a wallpaper.
+ private long mLastWallpaperTimeoutTime;
+ // We give a wallpaper up to 150ms to finish scrolling.
+ private static final long WALLPAPER_TIMEOUT = 150;
+ // Time we wait after a timeout before trying to wait again.
+ private static final long WALLPAPER_TIMEOUT_RECOVERY = 10000;
+
+ // Set to the wallpaper window we would like to hide once the transition animations are done.
+ // This is useful in cases where we don't want the wallpaper to be hidden when the close app
+ // is a wallpaper target and is done animating out, but the opening app isn't a wallpaper
+ // target and isn't done animating in.
+ private WindowState mDeferredHideWallpaper = null;
+
+ // We give a wallpaper up to 500ms to finish drawing before playing app transitions.
+ private static final long WALLPAPER_DRAW_PENDING_TIMEOUT_DURATION = 500;
+ private static final int WALLPAPER_DRAW_NORMAL = 0;
+ private static final int WALLPAPER_DRAW_PENDING = 1;
+ private static final int WALLPAPER_DRAW_TIMEOUT = 2;
+ private int mWallpaperDrawState = WALLPAPER_DRAW_NORMAL;
+
+ private final FindWallpaperTargetResult mFindResults = new FindWallpaperTargetResult();
+
+ public WallpaperController(WindowManagerService service) {
+ mService = service;
+ }
+
+ WindowState getWallpaperTarget() {
+ return mWallpaperTarget;
+ }
+
+ WindowState getLowerWallpaperTarget() {
+ return mLowerWallpaperTarget;
+ }
+
+ WindowState getUpperWallpaperTarget() {
+ return mUpperWallpaperTarget;
+ }
+
+ boolean isWallpaperTarget(WindowState win) {
+ return win == mWallpaperTarget;
+ }
+
+ boolean isBelowWallpaperTarget(WindowState win) {
+ return mWallpaperTarget != null && mWallpaperTarget.mLayer >= win.mBaseLayer;
+ }
+
+ boolean isWallpaperVisible() {
+ return isWallpaperVisible(mWallpaperTarget);
+ }
+
+ private boolean isWallpaperVisible(WindowState wallpaperTarget) {
+ if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper vis: target " + wallpaperTarget + ", obscured="
+ + (wallpaperTarget != null ? Boolean.toString(wallpaperTarget.mObscured) : "??")
+ + " anim=" + ((wallpaperTarget != null && wallpaperTarget.mAppToken != null)
+ ? wallpaperTarget.mAppToken.mAppAnimator.animation : null)
+ + " upper=" + mUpperWallpaperTarget
+ + " lower=" + mLowerWallpaperTarget);
+ return (wallpaperTarget != null
+ && (!wallpaperTarget.mObscured || (wallpaperTarget.mAppToken != null
+ && wallpaperTarget.mAppToken.mAppAnimator.animation != null)))
+ || mUpperWallpaperTarget != null
+ || mLowerWallpaperTarget != null;
+ }
+
+ boolean isWallpaperTargetAnimating() {
+ return mWallpaperTarget != null && mWallpaperTarget.mWinAnimator.isAnimating()
+ && !mWallpaperTarget.mWinAnimator.isDummyAnimation();
+ }
+
+ void updateWallpaperVisibility() {
+ final boolean visible = isWallpaperVisible(mWallpaperTarget);
+ final DisplayContent displayContent = mWallpaperTarget.getDisplayContent();
+ if (displayContent == null) {
+ return;
+ }
+ final DisplayInfo displayInfo = displayContent.getDisplayInfo();
+ final int dw = displayInfo.logicalWidth;
+ final int dh = displayInfo.logicalHeight;
+
+ for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) {
+ WindowToken token = mWallpaperTokens.get(curTokenNdx);
+ if (token.hidden == visible) {
+ token.hidden = !visible;
+ // Need to do a layout to ensure the wallpaper now has the
+ // correct size.
+ displayContent.layoutNeeded = true;
+ }
+
+ final WindowList windows = token.windows;
+ for (int wallpaperNdx = windows.size() - 1; wallpaperNdx >= 0; wallpaperNdx--) {
+ WindowState wallpaper = windows.get(wallpaperNdx);
+ if (visible) {
+ updateWallpaperOffset(wallpaper, dw, dh, false);
+ }
+
+ dispatchWallpaperVisibility(wallpaper, visible);
+ }
+ }
+ }
+
+ void hideDeferredWallpapersIfNeeded() {
+ if (mDeferredHideWallpaper != null) {
+ hideWallpapers(mDeferredHideWallpaper);
+ mDeferredHideWallpaper = null;
+ }
+ }
+
+ void hideWallpapers(final WindowState winGoingAway) {
+ if (mWallpaperTarget != null
+ && (mWallpaperTarget != winGoingAway || mLowerWallpaperTarget != null)) {
+ return;
+ }
+ if (mService.mAppTransition.isRunning()) {
+ // Defer hiding the wallpaper when app transition is running until the animations
+ // are done.
+ mDeferredHideWallpaper = winGoingAway;
+ return;
+ }
+
+ final boolean wasDeferred = (mDeferredHideWallpaper == winGoingAway);
+ for (int i = mWallpaperTokens.size() - 1; i >= 0; i--) {
+ final WindowToken token = mWallpaperTokens.get(i);
+ for (int j = token.windows.size() - 1; j >= 0; j--) {
+ final WindowState wallpaper = token.windows.get(j);
+ final WindowStateAnimator winAnimator = wallpaper.mWinAnimator;
+ if (!winAnimator.mLastHidden || wasDeferred) {
+ winAnimator.hide();
+ dispatchWallpaperVisibility(wallpaper, false);
+ final DisplayContent displayContent = wallpaper.getDisplayContent();
+ if (displayContent != null) {
+ displayContent.pendingLayoutChanges |=
+ WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
+ }
+ }
+ }
+ if (DEBUG_WALLPAPER_LIGHT && !token.hidden) Slog.d(TAG, "Hiding wallpaper " + token
+ + " from " + winGoingAway + " target=" + mWallpaperTarget + " lower="
+ + mLowerWallpaperTarget + "\n" + Debug.getCallers(5, " "));
+ token.hidden = true;
+ }
+ }
+
+ /**
+ * Check wallpaper for visibility change and notify window if so.
+ * @param wallpaper The wallpaper to test and notify.
+ * @param visible Current visibility.
+ */
+ void dispatchWallpaperVisibility(final WindowState wallpaper, final boolean visible) {
+ // Only send notification if the visibility actually changed and we are not trying to hide
+ // the wallpaper when we are deferring hiding of the wallpaper.
+ if (wallpaper.mWallpaperVisible != visible
+ && (mDeferredHideWallpaper == null || visible)) {
+ wallpaper.mWallpaperVisible = visible;
+ try {
+ if (DEBUG_VISIBILITY || DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
+ "Updating vis of wallpaper " + wallpaper
+ + ": " + visible + " from:\n" + Debug.getCallers(4, " "));
+ wallpaper.mClient.dispatchAppVisibility(visible);
+ } catch (RemoteException e) {
+ }
+ }
+ }
+
+ boolean updateWallpaperOffset(WindowState wallpaperWin, int dw, int dh, boolean sync) {
+ boolean rawChanged = false;
+ float wpx = mLastWallpaperX >= 0 ? mLastWallpaperX : 0.5f;
+ float wpxs = mLastWallpaperXStep >= 0 ? mLastWallpaperXStep : -1.0f;
+ int availw = wallpaperWin.mFrame.right - wallpaperWin.mFrame.left - dw;
+ int offset = availw > 0 ? -(int)(availw * wpx + .5f) : 0;
+ if (mLastWallpaperDisplayOffsetX != Integer.MIN_VALUE) {
+ offset += mLastWallpaperDisplayOffsetX;
+ }
+ boolean changed = wallpaperWin.mXOffset != offset;
+ if (changed) {
+ if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper " + wallpaperWin + " x: " + offset);
+ wallpaperWin.mXOffset = offset;
+ }
+ if (wallpaperWin.mWallpaperX != wpx || wallpaperWin.mWallpaperXStep != wpxs) {
+ wallpaperWin.mWallpaperX = wpx;
+ wallpaperWin.mWallpaperXStep = wpxs;
+ rawChanged = true;
+ }
+
+ float wpy = mLastWallpaperY >= 0 ? mLastWallpaperY : 0.5f;
+ float wpys = mLastWallpaperYStep >= 0 ? mLastWallpaperYStep : -1.0f;
+ int availh = wallpaperWin.mFrame.bottom - wallpaperWin.mFrame.top - dh;
+ offset = availh > 0 ? -(int)(availh * wpy + .5f) : 0;
+ if (mLastWallpaperDisplayOffsetY != Integer.MIN_VALUE) {
+ offset += mLastWallpaperDisplayOffsetY;
+ }
+ if (wallpaperWin.mYOffset != offset) {
+ if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper " + wallpaperWin + " y: " + offset);
+ changed = true;
+ wallpaperWin.mYOffset = offset;
+ }
+ if (wallpaperWin.mWallpaperY != wpy || wallpaperWin.mWallpaperYStep != wpys) {
+ wallpaperWin.mWallpaperY = wpy;
+ wallpaperWin.mWallpaperYStep = wpys;
+ rawChanged = true;
+ }
+
+ if (rawChanged && (wallpaperWin.mAttrs.privateFlags &
+ WindowManager.LayoutParams.PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS) != 0) {
+ try {
+ if (DEBUG_WALLPAPER) Slog.v(TAG, "Report new wp offset "
+ + wallpaperWin + " x=" + wallpaperWin.mWallpaperX
+ + " y=" + wallpaperWin.mWallpaperY);
+ if (sync) {
+ mWaitingOnWallpaper = wallpaperWin;
+ }
+ wallpaperWin.mClient.dispatchWallpaperOffsets(
+ wallpaperWin.mWallpaperX, wallpaperWin.mWallpaperY,
+ wallpaperWin.mWallpaperXStep, wallpaperWin.mWallpaperYStep, sync);
+ if (sync) {
+ if (mWaitingOnWallpaper != null) {
+ long start = SystemClock.uptimeMillis();
+ if ((mLastWallpaperTimeoutTime + WALLPAPER_TIMEOUT_RECOVERY)
+ < start) {
+ try {
+ if (DEBUG_WALLPAPER) Slog.v(TAG,
+ "Waiting for offset complete...");
+ mService.mWindowMap.wait(WALLPAPER_TIMEOUT);
+ } catch (InterruptedException e) {
+ }
+ if (DEBUG_WALLPAPER) Slog.v(TAG, "Offset complete!");
+ if ((start + WALLPAPER_TIMEOUT) < SystemClock.uptimeMillis()) {
+ Slog.i(TAG, "Timeout waiting for wallpaper to offset: "
+ + wallpaperWin);
+ mLastWallpaperTimeoutTime = start;
+ }
+ }
+ mWaitingOnWallpaper = null;
+ }
+ }
+ } catch (RemoteException e) {
+ }
+ }
+
+ return changed;
+ }
+
+ void setWindowWallpaperPosition(
+ WindowState window, float x, float y, float xStep, float yStep) {
+ if (window.mWallpaperX != x || window.mWallpaperY != y) {
+ window.mWallpaperX = x;
+ window.mWallpaperY = y;
+ window.mWallpaperXStep = xStep;
+ window.mWallpaperYStep = yStep;
+ updateWallpaperOffsetLocked(window, true);
+ }
+ }
+
+ void setWindowWallpaperDisplayOffset(WindowState window, int x, int y) {
+ if (window.mWallpaperDisplayOffsetX != x || window.mWallpaperDisplayOffsetY != y) {
+ window.mWallpaperDisplayOffsetX = x;
+ window.mWallpaperDisplayOffsetY = y;
+ updateWallpaperOffsetLocked(window, true);
+ }
+ }
+
+ Bundle sendWindowWallpaperCommand(
+ WindowState window, String action, int x, int y, int z, Bundle extras, boolean sync) {
+ if (window == mWallpaperTarget
+ || window == mLowerWallpaperTarget
+ || window == mUpperWallpaperTarget) {
+ boolean doWait = sync;
+ for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) {
+ final WindowList windows = mWallpaperTokens.get(curTokenNdx).windows;
+ for (int wallpaperNdx = windows.size() - 1; wallpaperNdx >= 0; wallpaperNdx--) {
+ WindowState wallpaper = windows.get(wallpaperNdx);
+ try {
+ wallpaper.mClient.dispatchWallpaperCommand(action,
+ x, y, z, extras, sync);
+ // We only want to be synchronous with one wallpaper.
+ sync = false;
+ } catch (RemoteException e) {
+ }
+ }
+ }
+
+ if (doWait) {
+ // TODO: Need to wait for result.
+ }
+ }
+
+ return null;
+ }
+
+ void updateWallpaperOffsetLocked(WindowState changingTarget, boolean sync) {
+ final DisplayContent displayContent = changingTarget.getDisplayContent();
+ if (displayContent == null) {
+ return;
+ }
+ final DisplayInfo displayInfo = displayContent.getDisplayInfo();
+ final int dw = displayInfo.logicalWidth;
+ final int dh = displayInfo.logicalHeight;
+
+ WindowState target = mWallpaperTarget;
+ if (target != null) {
+ if (target.mWallpaperX >= 0) {
+ mLastWallpaperX = target.mWallpaperX;
+ } else if (changingTarget.mWallpaperX >= 0) {
+ mLastWallpaperX = changingTarget.mWallpaperX;
+ }
+ if (target.mWallpaperY >= 0) {
+ mLastWallpaperY = target.mWallpaperY;
+ } else if (changingTarget.mWallpaperY >= 0) {
+ mLastWallpaperY = changingTarget.mWallpaperY;
+ }
+ if (target.mWallpaperDisplayOffsetX != Integer.MIN_VALUE) {
+ mLastWallpaperDisplayOffsetX = target.mWallpaperDisplayOffsetX;
+ } else if (changingTarget.mWallpaperDisplayOffsetX != Integer.MIN_VALUE) {
+ mLastWallpaperDisplayOffsetX = changingTarget.mWallpaperDisplayOffsetX;
+ }
+ if (target.mWallpaperDisplayOffsetY != Integer.MIN_VALUE) {
+ mLastWallpaperDisplayOffsetY = target.mWallpaperDisplayOffsetY;
+ } else if (changingTarget.mWallpaperDisplayOffsetY != Integer.MIN_VALUE) {
+ mLastWallpaperDisplayOffsetY = changingTarget.mWallpaperDisplayOffsetY;
+ }
+ if (target.mWallpaperXStep >= 0) {
+ mLastWallpaperXStep = target.mWallpaperXStep;
+ } else if (changingTarget.mWallpaperXStep >= 0) {
+ mLastWallpaperXStep = changingTarget.mWallpaperXStep;
+ }
+ if (target.mWallpaperYStep >= 0) {
+ mLastWallpaperYStep = target.mWallpaperYStep;
+ } else if (changingTarget.mWallpaperYStep >= 0) {
+ mLastWallpaperYStep = changingTarget.mWallpaperYStep;
+ }
+ }
+
+ for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) {
+ WindowList windows = mWallpaperTokens.get(curTokenNdx).windows;
+ for (int wallpaperNdx = windows.size() - 1; wallpaperNdx >= 0; wallpaperNdx--) {
+ WindowState wallpaper = windows.get(wallpaperNdx);
+ if (updateWallpaperOffset(wallpaper, dw, dh, sync)) {
+ WindowStateAnimator winAnimator = wallpaper.mWinAnimator;
+ winAnimator.computeShownFrameLocked();
+ // No need to lay out the windows - we can just set the wallpaper position
+ // directly.
+ winAnimator.setWallpaperOffset(wallpaper.mShownFrame);
+ // We only want to be synchronous with one wallpaper.
+ sync = false;
+ }
+ }
+ }
+ }
+
+ void clearLastWallpaperTimeoutTime() {
+ mLastWallpaperTimeoutTime = 0;
+ }
+
+ void wallpaperCommandComplete(IBinder window) {
+ if (mWaitingOnWallpaper != null &&
+ mWaitingOnWallpaper.mClient.asBinder() == window) {
+ mWaitingOnWallpaper = null;
+ mService.mWindowMap.notifyAll();
+ }
+ }
+
+ void wallpaperOffsetsComplete(IBinder window) {
+ if (mWaitingOnWallpaper != null &&
+ mWaitingOnWallpaper.mClient.asBinder() == window) {
+ mWaitingOnWallpaper = null;
+ mService.mWindowMap.notifyAll();
+ }
+ }
+
+ int getAnimLayerAdjustment() {
+ return mWallpaperAnimLayerAdjustment;
+ }
+
+ void setAnimLayerAdjustment(WindowState win, int adj) {
+ if (win != mWallpaperTarget || mLowerWallpaperTarget != null) {
+ return;
+ }
+
+ if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "Setting wallpaper layer adj to " + adj);
+ mWallpaperAnimLayerAdjustment = adj;
+ for (int i = mWallpaperTokens.size() - 1; i >= 0; i--) {
+ WindowList windows = mWallpaperTokens.get(i).windows;
+ for (int j = windows.size() - 1; j >= 0; j--) {
+ WindowState wallpaper = windows.get(j);
+ wallpaper.mWinAnimator.mAnimLayer = wallpaper.mLayer + adj;
+ if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "setWallpaper win "
+ + wallpaper + " anim layer: " + wallpaper.mWinAnimator.mAnimLayer);
+ }
+ }
+ }
+
+ private void findWallpaperTarget(WindowList windows, FindWallpaperTargetResult result) {
+
+ final WindowAnimator winAnimator = mService.mAnimator;
+ result.reset();
+ WindowState w = null;
+ int windowDetachedI = -1;
+ boolean resetTopWallpaper = false;
+ boolean inFreeformSpace = false;
+ for (int i = windows.size() - 1; i >= 0; i--) {
+ w = windows.get(i);
+ if ((w.mAttrs.type == TYPE_WALLPAPER)) {
+ if (result.topWallpaper == null || resetTopWallpaper) {
+ result.setTopWallpaper(w, i);
+ resetTopWallpaper = false;
+ }
+ continue;
+ }
+ resetTopWallpaper = true;
+ if (w != winAnimator.mWindowDetachedWallpaper && w.mAppToken != null) {
+ // If this window's app token is hidden and not animating,
+ // it is of no interest to us.
+ if (w.mAppToken.hidden && w.mAppToken.mAppAnimator.animation == null) {
+ if (DEBUG_WALLPAPER) Slog.v(TAG,
+ "Skipping hidden and not animating token: " + w);
+ continue;
+ }
+ }
+ if (DEBUG_WALLPAPER) Slog.v(TAG, "Win #" + i + " " + w + ": isOnScreen="
+ + w.isOnScreen() + " mDrawState=" + w.mWinAnimator.mDrawState);
+
+ if (!inFreeformSpace) {
+ TaskStack stack = w.getStack();
+ inFreeformSpace = stack != null && stack.mStackId == FREEFORM_WORKSPACE_STACK_ID;
+ }
+
+ // If the app is executing an animation because the keyguard is going away,
+ // keep the wallpaper during the animation so it doesn't flicker out.
+ final boolean hasWallpaper = (w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0
+ || (w.mAppToken != null && w.mWinAnimator.mKeyguardGoingAwayAnimation);
+ if (hasWallpaper && w.isOnScreen()
+ && (mWallpaperTarget == w || w.isDrawFinishedLw())) {
+ if (DEBUG_WALLPAPER) Slog.v(TAG, "Found wallpaper target: #" + i + "=" + w);
+ result.setWallpaperTarget(w, i);
+ if (w == mWallpaperTarget && w.mWinAnimator.isAnimating()) {
+ // The current wallpaper target is animating, so we'll look behind it for
+ // another possible target and figure out what is going on later.
+ if (DEBUG_WALLPAPER) Slog.v(TAG,
+ "Win " + w + ": token animating, looking behind.");
+ continue;
+ }
+ break;
+ } else if (w == winAnimator.mWindowDetachedWallpaper) {
+ windowDetachedI = i;
+ }
+ }
+
+ if (result.wallpaperTarget == null && windowDetachedI >= 0) {
+ if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
+ "Found animating detached wallpaper activity: #" + windowDetachedI + "=" + w);
+ result.setWallpaperTarget(w, windowDetachedI);
+ }
+ if (result.wallpaperTarget == null && inFreeformSpace) {
+ // In freeform mode we set the wallpaper as its own target, so we don't need an
+ // additional window to make it visible.
+ result.setWallpaperTarget(result.topWallpaper, result.topWallpaperIndex);
+ }
+ }
+
+ private boolean updateWallpaperWindowsTarget(
+ WindowList windows, FindWallpaperTargetResult result) {
+
+ boolean targetChanged = false;
+ WindowState wallpaperTarget = result.wallpaperTarget;
+ int wallpaperTargetIndex = result.wallpaperTargetIndex;
+
+ if (mWallpaperTarget != wallpaperTarget
+ && (mLowerWallpaperTarget == null || mLowerWallpaperTarget != wallpaperTarget)) {
+ if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
+ "New wallpaper target: " + wallpaperTarget + " oldTarget: " + mWallpaperTarget);
+
+ mLowerWallpaperTarget = null;
+ mUpperWallpaperTarget = null;
+
+ WindowState oldW = mWallpaperTarget;
+ mWallpaperTarget = wallpaperTarget;
+ targetChanged = true;
+
+ // Now what is happening... if the current and new targets are animating,
+ // then we are in our super special mode!
+ if (wallpaperTarget != null && oldW != null) {
+ boolean oldAnim = oldW.isAnimatingLw();
+ boolean foundAnim = wallpaperTarget.isAnimatingLw();
+ if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
+ "New animation: " + foundAnim + " old animation: " + oldAnim);
+ if (foundAnim && oldAnim) {
+ int oldI = windows.indexOf(oldW);
+ if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
+ "New i: " + wallpaperTargetIndex + " old i: " + oldI);
+ if (oldI >= 0) {
+ if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
+ "Animating wallpapers: old#" + oldI + "=" + oldW + "; new#"
+ + wallpaperTargetIndex + "=" + wallpaperTarget);
+
+ // Set the new target correctly.
+ if (wallpaperTarget.mAppToken != null
+ && wallpaperTarget.mAppToken.hiddenRequested) {
+ if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
+ "Old wallpaper still the target.");
+ mWallpaperTarget = oldW;
+ wallpaperTarget = oldW;
+ wallpaperTargetIndex = oldI;
+ }
+ // Now set the upper and lower wallpaper targets correctly,
+ // and make sure that we are positioning the wallpaper below the lower.
+ else if (wallpaperTargetIndex > oldI) {
+ // The new target is on top of the old one.
+ if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
+ "Found target above old target.");
+ mUpperWallpaperTarget = wallpaperTarget;
+ mLowerWallpaperTarget = oldW;
+ wallpaperTarget = oldW;
+ wallpaperTargetIndex = oldI;
+ } else {
+ // The new target is below the old one.
+ if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
+ "Found target below old target.");
+ mUpperWallpaperTarget = oldW;
+ mLowerWallpaperTarget = wallpaperTarget;
+ }
+ }
+ }
+ }
+
+ } else if (mLowerWallpaperTarget != null) {
+ // Is it time to stop animating?
+ if (!mLowerWallpaperTarget.isAnimatingLw() || !mUpperWallpaperTarget.isAnimatingLw()) {
+ if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "No longer animating wallpaper targets!");
+ mLowerWallpaperTarget = null;
+ mUpperWallpaperTarget = null;
+ mWallpaperTarget = wallpaperTarget;
+ targetChanged = true;
+ }
+ }
+
+ result.setWallpaperTarget(wallpaperTarget, wallpaperTargetIndex);
+ return targetChanged;
+ }
+
+ boolean updateWallpaperWindowsTargetByLayer(
+ WindowList windows, FindWallpaperTargetResult result) {
+
+ WindowState wallpaperTarget = result.wallpaperTarget;
+ int wallpaperTargetIndex = result.wallpaperTargetIndex;
+ boolean visible = wallpaperTarget != null;
+
+ if (visible) {
+ // The window is visible to the compositor...but is it visible to the user?
+ // That is what the wallpaper cares about.
+ visible = isWallpaperVisible(wallpaperTarget);
+ if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper visibility: " + visible);
+
+ // If the wallpaper target is animating, we may need to copy its layer adjustment.
+ // Only do this if we are not transferring between two wallpaper targets.
+ mWallpaperAnimLayerAdjustment =
+ (mLowerWallpaperTarget == null && wallpaperTarget.mAppToken != null)
+ ? wallpaperTarget.mAppToken.mAppAnimator.animLayerAdjustment : 0;
+
+ final int maxLayer = (mService.mPolicy.getMaxWallpaperLayer() * TYPE_LAYER_MULTIPLIER)
+ + TYPE_LAYER_OFFSET;
+
+ // Now w is the window we are supposed to be behind... but we
+ // need to be sure to also be behind any of its attached windows,
+ // AND any starting window associated with it, AND below the
+ // maximum layer the policy allows for wallpapers.
+ while (wallpaperTargetIndex > 0) {
+ WindowState wb = windows.get(wallpaperTargetIndex - 1);
+ if (wb.mBaseLayer < maxLayer &&
+ wb.mAttachedWindow != wallpaperTarget &&
+ (wallpaperTarget.mAttachedWindow == null ||
+ wb.mAttachedWindow != wallpaperTarget.mAttachedWindow) &&
+ (wb.mAttrs.type != TYPE_APPLICATION_STARTING
+ || wallpaperTarget.mToken == null
+ || wb.mToken != wallpaperTarget.mToken)) {
+ // This window is not related to the previous one in any
+ // interesting way, so stop here.
+ break;
+ }
+ wallpaperTarget = wb;
+ wallpaperTargetIndex--;
+ }
+ } else {
+ if (DEBUG_WALLPAPER) Slog.v(TAG, "No wallpaper target");
+ }
+
+ result.setWallpaperTarget(wallpaperTarget, wallpaperTargetIndex);
+ return visible;
+ }
+
+ boolean updateWallpaperWindowsPlacement(WindowList windows,
+ WindowState wallpaperTarget, int wallpaperTargetIndex, boolean visible) {
+
+ // TODO(multidisplay): Wallpapers on main screen only.
+ final DisplayInfo displayInfo = mService.getDefaultDisplayContentLocked().getDisplayInfo();
+ final int dw = displayInfo.logicalWidth;
+ final int dh = displayInfo.logicalHeight;
+
+ // Start stepping backwards from here, ensuring that our wallpaper windows
+ // are correctly placed.
+ boolean changed = false;
+ for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) {
+ WindowToken token = mWallpaperTokens.get(curTokenNdx);
+ if (token.hidden == visible) {
+ if (DEBUG_WALLPAPER_LIGHT) Slog.d(TAG,
+ "Wallpaper token " + token + " hidden=" + !visible);
+ token.hidden = !visible;
+ // Need to do a layout to ensure the wallpaper now has the correct size.
+ mService.getDefaultDisplayContentLocked().layoutNeeded = true;
+ }
+
+ final WindowList tokenWindows = token.windows;
+ for (int wallpaperNdx = tokenWindows.size() - 1; wallpaperNdx >= 0; wallpaperNdx--) {
+ WindowState wallpaper = tokenWindows.get(wallpaperNdx);
+
+ if (visible) {
+ updateWallpaperOffset(wallpaper, dw, dh, false);
+ }
+
+ // First, make sure the client has the current visibility state.
+ dispatchWallpaperVisibility(wallpaper, visible);
+
+ wallpaper.mWinAnimator.mAnimLayer =
+ wallpaper.mLayer + mWallpaperAnimLayerAdjustment;
+ if (DEBUG_LAYERS || DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "adjustWallpaper win "
+ + wallpaper + " anim layer: " + wallpaper.mWinAnimator.mAnimLayer);
+
+ // First, if this window is at the current index, then all is well.
+ if (wallpaper == wallpaperTarget) {
+ wallpaperTargetIndex--;
+ wallpaperTarget = wallpaperTargetIndex > 0
+ ? windows.get(wallpaperTargetIndex - 1) : null;
+ continue;
+ }
+
+ // The window didn't match... the current wallpaper window,
+ // wherever it is, is in the wrong place, so make sure it is not in the list.
+ int oldIndex = windows.indexOf(wallpaper);
+ if (oldIndex >= 0) {
+ if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
+ "Wallpaper removing at " + oldIndex + ": " + wallpaper);
+ windows.remove(oldIndex);
+ mService.mWindowsChanged = true;
+ if (oldIndex < wallpaperTargetIndex) {
+ wallpaperTargetIndex--;
+ }
+ }
+
+ // Now stick it in. For apps over wallpaper keep the wallpaper at the bottommost
+ // layer. For keyguard over wallpaper put the wallpaper under the keyguard.
+ int insertionIndex = 0;
+ if (visible && wallpaperTarget != null) {
+ final int type = wallpaperTarget.mAttrs.type;
+ final int privateFlags = wallpaperTarget.mAttrs.privateFlags;
+ if ((privateFlags & PRIVATE_FLAG_KEYGUARD) != 0
+ || type == TYPE_KEYGUARD_SCRIM) {
+ insertionIndex = windows.indexOf(wallpaperTarget);
+ }
+ }
+ if (DEBUG_WALLPAPER_LIGHT || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG,
+ "Moving wallpaper " + wallpaper
+ + " from " + oldIndex + " to " + insertionIndex);
+
+ windows.add(insertionIndex, wallpaper);
+ mService.mWindowsChanged = true;
+ changed = true;
+ }
+ }
+
+ return changed;
+ }
+
+ boolean adjustWallpaperWindows() {
+ mService.mInnerFields.mWallpaperMayChange = false;
+
+ final WindowList windows = mService.getDefaultWindowListLocked();
+ // First find top-most window that has asked to be on top of the wallpaper;
+ // all wallpapers go behind it.
+ findWallpaperTarget(windows, mFindResults);
+ final boolean targetChanged = updateWallpaperWindowsTarget(windows, mFindResults);
+ final boolean visible = updateWallpaperWindowsTargetByLayer(windows, mFindResults);
+ WindowState wallpaperTarget = mFindResults.wallpaperTarget;
+ int wallpaperTargetIndex = mFindResults.wallpaperTargetIndex;
+
+ if (wallpaperTarget == null && mFindResults.topWallpaper != null) {
+ // There is no wallpaper target, so it goes at the bottom.
+ // We will assume it is the same place as last time, if known.
+ wallpaperTarget = mFindResults.topWallpaper;
+ wallpaperTargetIndex = mFindResults.topWallpaperIndex + 1;
+ } else {
+ // Okay i is the position immediately above the wallpaper.
+ // Look at what is below it for later.
+ wallpaperTarget = wallpaperTargetIndex > 0
+ ? windows.get(wallpaperTargetIndex - 1) : null;
+ }
+
+ if (visible) {
+ if (mWallpaperTarget.mWallpaperX >= 0) {
+ mLastWallpaperX = mWallpaperTarget.mWallpaperX;
+ mLastWallpaperXStep = mWallpaperTarget.mWallpaperXStep;
+ }
+ if (mWallpaperTarget.mWallpaperY >= 0) {
+ mLastWallpaperY = mWallpaperTarget.mWallpaperY;
+ mLastWallpaperYStep = mWallpaperTarget.mWallpaperYStep;
+ }
+ if (mWallpaperTarget.mWallpaperDisplayOffsetX != Integer.MIN_VALUE) {
+ mLastWallpaperDisplayOffsetX = mWallpaperTarget.mWallpaperDisplayOffsetX;
+ }
+ if (mWallpaperTarget.mWallpaperDisplayOffsetY != Integer.MIN_VALUE) {
+ mLastWallpaperDisplayOffsetY = mWallpaperTarget.mWallpaperDisplayOffsetY;
+ }
+ }
+
+ final boolean changed = updateWallpaperWindowsPlacement(
+ windows, wallpaperTarget, wallpaperTargetIndex, visible);
+
+ if (targetChanged && DEBUG_WALLPAPER_LIGHT) Slog.d(TAG, "New wallpaper: target="
+ + mWallpaperTarget + " lower=" + mLowerWallpaperTarget + " upper="
+ + mUpperWallpaperTarget);
+
+ return changed;
+ }
+
+ boolean processWallpaperDrawPendingTimeout() {
+ if (mWallpaperDrawState == WALLPAPER_DRAW_PENDING) {
+ mWallpaperDrawState = WALLPAPER_DRAW_TIMEOUT;
+ if (DEBUG_APP_TRANSITIONS || DEBUG_WALLPAPER) Slog.v(TAG,
+ "*** WALLPAPER DRAW TIMEOUT");
+ return true;
+ }
+ return false;
+ }
+
+ boolean wallpaperTransitionReady() {
+ boolean transitionReady = true;
+ boolean wallpaperReady = true;
+ for (int curTokenIndex = mWallpaperTokens.size() - 1;
+ curTokenIndex >= 0 && wallpaperReady; curTokenIndex--) {
+ WindowToken token = mWallpaperTokens.get(curTokenIndex);
+ for (int curWallpaperIndex = token.windows.size() - 1; curWallpaperIndex >= 0;
+ curWallpaperIndex--) {
+ WindowState wallpaper = token.windows.get(curWallpaperIndex);
+ if (wallpaper.mWallpaperVisible && !wallpaper.isDrawnLw()) {
+ // We've told this wallpaper to be visible, but it is not drawn yet
+ wallpaperReady = false;
+ if (mWallpaperDrawState != WALLPAPER_DRAW_TIMEOUT) {
+ // wait for this wallpaper until it is drawn or timeout
+ transitionReady = false;
+ }
+ if (mWallpaperDrawState == WALLPAPER_DRAW_NORMAL) {
+ mWallpaperDrawState = WALLPAPER_DRAW_PENDING;
+ mService.mH.removeMessages(WALLPAPER_DRAW_PENDING_TIMEOUT);
+ mService.mH.sendEmptyMessageDelayed(WALLPAPER_DRAW_PENDING_TIMEOUT,
+ WALLPAPER_DRAW_PENDING_TIMEOUT_DURATION);
+ }
+ if (DEBUG_APP_TRANSITIONS || DEBUG_WALLPAPER) Slog.v(TAG,
+ "Wallpaper should be visible but has not been drawn yet. " +
+ "mWallpaperDrawState=" + mWallpaperDrawState);
+ break;
+ }
+ }
+ }
+ if (wallpaperReady) {
+ mWallpaperDrawState = WALLPAPER_DRAW_NORMAL;
+ mService.mH.removeMessages(WALLPAPER_DRAW_PENDING_TIMEOUT);
+ }
+
+ return transitionReady;
+ }
+
+ void addWallpaperToken(WindowToken token) {
+ mWallpaperTokens.add(token);
+ }
+
+ void removeWallpaperToken(WindowToken token) {
+ mWallpaperTokens.remove(token);
+ }
+
+ void dump(PrintWriter pw, String prefix) {
+ pw.print(prefix); pw.print("mWallpaperTarget="); pw.println(mWallpaperTarget);
+ if (mLowerWallpaperTarget != null || mUpperWallpaperTarget != null) {
+ pw.print(prefix); pw.print("mLowerWallpaperTarget="); pw.println(mLowerWallpaperTarget);
+ pw.print(prefix); pw.print("mUpperWallpaperTarget="); pw.println(mUpperWallpaperTarget);
+ }
+ pw.print(prefix); pw.print("mLastWallpaperX="); pw.print(mLastWallpaperX);
+ pw.print(" mLastWallpaperY="); pw.println(mLastWallpaperY);
+ if (mLastWallpaperDisplayOffsetX != Integer.MIN_VALUE
+ || mLastWallpaperDisplayOffsetY != Integer.MIN_VALUE) {
+ pw.print(prefix);
+ pw.print("mLastWallpaperDisplayOffsetX="); pw.print(mLastWallpaperDisplayOffsetX);
+ pw.print(" mLastWallpaperDisplayOffsetY="); pw.println(mLastWallpaperDisplayOffsetY);
+ }
+ }
+
+ void dumpTokens(PrintWriter pw, String prefix, boolean dumpAll) {
+ if (!mWallpaperTokens.isEmpty()) {
+ pw.println();
+ pw.print(prefix); pw.println("Wallpaper tokens:");
+ for (int i = mWallpaperTokens.size() - 1; i >= 0; i--) {
+ WindowToken token = mWallpaperTokens.get(i);
+ pw.print(prefix); pw.print("Wallpaper #"); pw.print(i);
+ pw.print(' '); pw.print(token);
+ if (dumpAll) {
+ pw.println(':');
+ token.dump(pw, " ");
+ } else {
+ pw.println();
+ }
+ }
+ }
+ }
+
+ /** Helper class for storing the results of a wallpaper target find operation. */
+ final private static class FindWallpaperTargetResult {
+ int topWallpaperIndex = 0;
+ WindowState topWallpaper = null;
+ int wallpaperTargetIndex = 0;
+ WindowState wallpaperTarget = null;
+
+ void setTopWallpaper(WindowState win, int index) {
+ topWallpaper = win;
+ topWallpaperIndex = index;
+ }
+
+ void setWallpaperTarget(WindowState win, int index) {
+ wallpaperTarget = win;
+ wallpaperTargetIndex = index;
+ }
+
+ void reset() {
+ topWallpaperIndex = 0;
+ topWallpaper = null;
+ wallpaperTargetIndex = 0;
+ wallpaperTarget = null;
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index 7578256..e6a1be1 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -258,6 +258,7 @@
boolean startingInUnForceHiding = false;
ArrayList<WindowStateAnimator> unForceHiding = null;
WindowState wallpaper = null;
+ final WallpaperController wallpaperController = mService.mWallpaperControllerLocked;
for (int i = windows.size() - 1; i >= 0; i--) {
WindowState win = windows.get(i);
WindowStateAnimator winAnimator = win.mWinAnimator;
@@ -294,7 +295,8 @@
", nowAnimating=" + nowAnimating);
}
- if (wasAnimating && !winAnimator.mAnimating && mService.mWallpaperTarget == win) {
+ if (wasAnimating && !winAnimator.mAnimating
+ && wallpaperController.isWallpaperTarget(win)) {
mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE;
setPendingLayoutChanges(Display.DEFAULT_DISPLAY,
WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER);
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 355b09b..a200678 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -78,6 +78,7 @@
import android.util.SparseIntArray;
import android.util.TimeUtils;
import android.util.TypedValue;
+import android.view.AppTransitionAnimationSpec;
import android.view.Choreographer;
import android.view.Display;
import android.view.DisplayInfo;
@@ -113,6 +114,7 @@
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
+import static com.android.server.wm.WindowState.BOUNDS_FOR_TOUCH;
import com.android.internal.app.IAssistScreenshotReceiver;
import com.android.internal.app.IBatteryStats;
import com.android.internal.util.FastPrintWriter;
@@ -176,7 +178,6 @@
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
-import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_SCRIM;
import static android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION;
import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
@@ -443,6 +444,7 @@
final float[] mTmpFloats = new float[9];
final Rect mTmpContentRect = new Rect();
+ private final Rect mTmpStartRect = new Rect();
boolean mDisplayReady;
boolean mSafeMode;
@@ -579,48 +581,10 @@
}
}
- private final ArrayList<WindowToken> mWallpaperTokens = new ArrayList<WindowToken>();
+ WallpaperController mWallpaperControllerLocked;
- // If non-null, this is the currently visible window that is associated
- // with the wallpaper.
- WindowState mWallpaperTarget = null;
- // If non-null, we are in the middle of animating from one wallpaper target
- // to another, and this is the lower one in Z-order.
- WindowState mLowerWallpaperTarget = null;
- // If non-null, we are in the middle of animating from one wallpaper target
- // to another, and this is the higher one in Z-order.
- WindowState mUpperWallpaperTarget = null;
- int mWallpaperAnimLayerAdjustment;
- float mLastWallpaperX = -1;
- float mLastWallpaperY = -1;
- float mLastWallpaperXStep = -1;
- float mLastWallpaperYStep = -1;
- int mLastWallpaperDisplayOffsetX = Integer.MIN_VALUE;
- int mLastWallpaperDisplayOffsetY = Integer.MIN_VALUE;
- // This is set when we are waiting for a wallpaper to tell us it is done
- // changing its scroll position.
- WindowState mWaitingOnWallpaper;
- // The last time we had a timeout when waiting for a wallpaper.
- long mLastWallpaperTimeoutTime;
- // We give a wallpaper up to 150ms to finish scrolling.
- static final long WALLPAPER_TIMEOUT = 150;
- // Time we wait after a timeout before trying to wait again.
- static final long WALLPAPER_TIMEOUT_RECOVERY = 10000;
boolean mAnimateWallpaperWithTarget;
- // We give a wallpaper up to 500ms to finish drawing before playing app transitions.
- static final long WALLPAPER_DRAW_PENDING_TIMEOUT_DURATION = 500;
- static final int WALLPAPER_DRAW_NORMAL = 0;
- static final int WALLPAPER_DRAW_PENDING = 1;
- static final int WALLPAPER_DRAW_TIMEOUT = 2;
- int mWallpaperDrawState = WALLPAPER_DRAW_NORMAL;
-
- // Set to the wallpaper window we would like to hide once the transition animations are done.
- // This is useful in cases where we don't want the wallpaper to be hidden when the close app
- // is a wallpaper target and is done animating out, but the opening app isn't a wallpaper
- // target and isn't done animating in.
- WindowState mDeferredHideWallpaper = null;
-
AppWindowToken mFocusedApp = null;
PowerManager mPowerManager;
@@ -634,6 +598,7 @@
final InputManagerService mInputManager;
final DisplayManagerInternal mDisplayManagerInternal;
final DisplayManager mDisplayManager;
+ final Display[] mDisplays;
// Who is holding the screen on.
Session mHoldingScreenOn;
@@ -804,7 +769,7 @@
private ViewServer mViewServer;
private final ArrayList<WindowChangeListener> mWindowChangeListeners = new ArrayList<>();
- private boolean mWindowsChanged = false;
+ boolean mWindowsChanged = false;
public interface WindowChangeListener {
public void windowsChanged();
@@ -907,8 +872,8 @@
mFxSession = new SurfaceSession();
mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
- Display[] displays = mDisplayManager.getDisplays();
- for (Display display : displays) {
+ mDisplays = mDisplayManager.getDisplays();
+ for (Display display : mDisplays) {
createDisplayContentLocked(display);
}
@@ -988,6 +953,8 @@
updateCircularDisplayMaskIfNeeded();
showEmulatorDisplayOverlayIfNeeded();
+
+ mWallpaperControllerLocked = new WallpaperController(this);
}
public InputMonitor getInputMonitor() {
@@ -1767,578 +1734,6 @@
return true;
}
- private boolean isWallpaperVisible(WindowState wallpaperTarget) {
- if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper vis: target " + wallpaperTarget + ", obscured="
- + (wallpaperTarget != null ? Boolean.toString(wallpaperTarget.mObscured) : "??")
- + " anim=" + ((wallpaperTarget != null && wallpaperTarget.mAppToken != null)
- ? wallpaperTarget.mAppToken.mAppAnimator.animation : null)
- + " upper=" + mUpperWallpaperTarget
- + " lower=" + mLowerWallpaperTarget);
- return (wallpaperTarget != null
- && (!wallpaperTarget.mObscured || (wallpaperTarget.mAppToken != null
- && wallpaperTarget.mAppToken.mAppAnimator.animation != null)))
- || mUpperWallpaperTarget != null
- || mLowerWallpaperTarget != null;
- }
-
- void hideWallpapersLocked(final WindowState winGoingAway) {
- if (mWallpaperTarget != null
- && (mWallpaperTarget != winGoingAway || mLowerWallpaperTarget != null)) {
- return;
- }
- if (mAppTransition.isRunning()) {
- // Defer hiding the wallpaper when app transition is running until the animations
- // are done.
- mDeferredHideWallpaper = winGoingAway;
- return;
- }
-
- final boolean wasDeferred = (mDeferredHideWallpaper == winGoingAway);
- for (int i = mWallpaperTokens.size() - 1; i >= 0; i--) {
- final WindowToken token = mWallpaperTokens.get(i);
- for (int j = token.windows.size() - 1; j >= 0; j--) {
- final WindowState wallpaper = token.windows.get(j);
- final WindowStateAnimator winAnimator = wallpaper.mWinAnimator;
- if (!winAnimator.mLastHidden || wasDeferred) {
- winAnimator.hide();
- dispatchWallpaperVisibility(wallpaper, false);
- final DisplayContent displayContent = wallpaper.getDisplayContent();
- if (displayContent != null) {
- displayContent.pendingLayoutChanges |=
- WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
- }
- }
- }
- if (DEBUG_WALLPAPER_LIGHT && !token.hidden) Slog.d(TAG, "Hiding wallpaper " + token
- + " from " + winGoingAway + " target=" + mWallpaperTarget + " lower="
- + mLowerWallpaperTarget + "\n" + Debug.getCallers(5, " "));
- token.hidden = true;
- }
- }
-
- boolean adjustWallpaperWindowsLocked() {
- mInnerFields.mWallpaperMayChange = false;
- boolean targetChanged = false;
-
- // TODO(multidisplay): Wallpapers on main screen only.
- final DisplayInfo displayInfo = getDefaultDisplayContentLocked().getDisplayInfo();
- final int dw = displayInfo.logicalWidth;
- final int dh = displayInfo.logicalHeight;
-
- // First find top-most window that has asked to be on top of the
- // wallpaper; all wallpapers go behind it.
- final WindowList windows = getDefaultWindowListLocked();
- int N = windows.size();
- WindowState w = null;
- WindowState foundW = null;
- int foundI = 0;
- WindowState topCurW = null;
- int topCurI = 0;
- int windowDetachedI = -1;
- int i = N;
- while (i > 0) {
- i--;
- w = windows.get(i);
- if ((w.mAttrs.type == TYPE_WALLPAPER)) {
- if (topCurW == null) {
- topCurW = w;
- topCurI = i;
- }
- continue;
- }
- topCurW = null;
- if (w != mAnimator.mWindowDetachedWallpaper && w.mAppToken != null) {
- // If this window's app token is hidden and not animating,
- // it is of no interest to us.
- if (w.mAppToken.hidden && w.mAppToken.mAppAnimator.animation == null) {
- if (DEBUG_WALLPAPER) Slog.v(TAG,
- "Skipping hidden and not animating token: " + w);
- continue;
- }
- }
- if (DEBUG_WALLPAPER) Slog.v(TAG, "Win #" + i + " " + w + ": isOnScreen="
- + w.isOnScreen() + " mDrawState=" + w.mWinAnimator.mDrawState);
-
- // If the app is executing an animation because the keyguard is going away, keep the
- // wallpaper during the animation so it doesn't flicker out.
- final boolean hasWallpaper = (w.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0
- || (w.mAppToken != null
- && w.mWinAnimator.mKeyguardGoingAwayAnimation);
- if (hasWallpaper && w.isOnScreen()
- && (mWallpaperTarget == w || w.isDrawFinishedLw())) {
- if (DEBUG_WALLPAPER) Slog.v(TAG,
- "Found wallpaper target: #" + i + "=" + w);
- foundW = w;
- foundI = i;
- if (w == mWallpaperTarget && w.mWinAnimator.isAnimating()) {
- // The current wallpaper target is animating, so we'll
- // look behind it for another possible target and figure
- // out what is going on below.
- if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w
- + ": token animating, looking behind.");
- continue;
- }
- break;
- } else if (w == mAnimator.mWindowDetachedWallpaper) {
- windowDetachedI = i;
- }
- }
-
- if (foundW == null && windowDetachedI >= 0) {
- if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
- "Found animating detached wallpaper activity: #" + i + "=" + w);
- foundW = w;
- foundI = windowDetachedI;
- }
-
- if (mWallpaperTarget != foundW
- && (mLowerWallpaperTarget == null || mLowerWallpaperTarget != foundW)) {
- if (DEBUG_WALLPAPER_LIGHT) {
- Slog.v(TAG, "New wallpaper target: " + foundW
- + " oldTarget: " + mWallpaperTarget);
- }
-
- mLowerWallpaperTarget = null;
- mUpperWallpaperTarget = null;
-
- WindowState oldW = mWallpaperTarget;
- mWallpaperTarget = foundW;
- targetChanged = true;
-
- // Now what is happening... if the current and new targets are
- // animating, then we are in our super special mode!
- if (foundW != null && oldW != null) {
- boolean oldAnim = oldW.isAnimatingLw();
- boolean foundAnim = foundW.isAnimatingLw();
- if (DEBUG_WALLPAPER_LIGHT) {
- Slog.v(TAG, "New animation: " + foundAnim
- + " old animation: " + oldAnim);
- }
- if (foundAnim && oldAnim) {
- int oldI = windows.indexOf(oldW);
- if (DEBUG_WALLPAPER_LIGHT) {
- Slog.v(TAG, "New i: " + foundI + " old i: " + oldI);
- }
- if (oldI >= 0) {
- if (DEBUG_WALLPAPER_LIGHT) {
- Slog.v(TAG, "Animating wallpapers: old#" + oldI
- + "=" + oldW + "; new#" + foundI
- + "=" + foundW);
- }
-
- // Set the new target correctly.
- if (foundW.mAppToken != null && foundW.mAppToken.hiddenRequested) {
- if (DEBUG_WALLPAPER_LIGHT) {
- Slog.v(TAG, "Old wallpaper still the target.");
- }
- mWallpaperTarget = oldW;
- foundW = oldW;
- foundI = oldI;
- }
- // Now set the upper and lower wallpaper targets
- // correctly, and make sure that we are positioning
- // the wallpaper below the lower.
- else if (foundI > oldI) {
- // The new target is on top of the old one.
- if (DEBUG_WALLPAPER_LIGHT) {
- Slog.v(TAG, "Found target above old target.");
- }
- mUpperWallpaperTarget = foundW;
- mLowerWallpaperTarget = oldW;
- foundW = oldW;
- foundI = oldI;
- } else {
- // The new target is below the old one.
- if (DEBUG_WALLPAPER_LIGHT) {
- Slog.v(TAG, "Found target below old target.");
- }
- mUpperWallpaperTarget = oldW;
- mLowerWallpaperTarget = foundW;
- }
- }
- }
- }
-
- } else if (mLowerWallpaperTarget != null) {
- // Is it time to stop animating?
- if (!mLowerWallpaperTarget.isAnimatingLw() || !mUpperWallpaperTarget.isAnimatingLw()) {
- if (DEBUG_WALLPAPER_LIGHT) {
- Slog.v(TAG, "No longer animating wallpaper targets!");
- }
- mLowerWallpaperTarget = null;
- mUpperWallpaperTarget = null;
- mWallpaperTarget = foundW;
- targetChanged = true;
- }
- }
-
- boolean visible = foundW != null;
- if (visible) {
- // The window is visible to the compositor... but is it visible
- // to the user? That is what the wallpaper cares about.
- visible = isWallpaperVisible(foundW);
- if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper visibility: " + visible);
-
- // If the wallpaper target is animating, we may need to copy
- // its layer adjustment. Only do this if we are not transfering
- // between two wallpaper targets.
- mWallpaperAnimLayerAdjustment =
- (mLowerWallpaperTarget == null && foundW.mAppToken != null)
- ? foundW.mAppToken.mAppAnimator.animLayerAdjustment : 0;
-
- final int maxLayer = mPolicy.getMaxWallpaperLayer()
- * TYPE_LAYER_MULTIPLIER
- + TYPE_LAYER_OFFSET;
-
- // Now w is the window we are supposed to be behind... but we
- // need to be sure to also be behind any of its attached windows,
- // AND any starting window associated with it, AND below the
- // maximum layer the policy allows for wallpapers.
- while (foundI > 0) {
- WindowState wb = windows.get(foundI - 1);
- if (wb.mBaseLayer < maxLayer &&
- wb.mAttachedWindow != foundW &&
- (foundW.mAttachedWindow == null ||
- wb.mAttachedWindow != foundW.mAttachedWindow) &&
- (wb.mAttrs.type != TYPE_APPLICATION_STARTING ||
- foundW.mToken == null || wb.mToken != foundW.mToken)) {
- // This window is not related to the previous one in any
- // interesting way, so stop here.
- break;
- }
- foundW = wb;
- foundI--;
- }
- } else {
- if (DEBUG_WALLPAPER) Slog.v(TAG, "No wallpaper target");
- }
-
- if (foundW == null && topCurW != null) {
- // There is no wallpaper target, so it goes at the bottom.
- // We will assume it is the same place as last time, if known.
- foundW = topCurW;
- foundI = topCurI+1;
- } else {
- // Okay i is the position immediately above the wallpaper. Look at
- // what is below it for later.
- foundW = foundI > 0 ? windows.get(foundI - 1) : null;
- }
-
- if (visible) {
- if (mWallpaperTarget.mWallpaperX >= 0) {
- mLastWallpaperX = mWallpaperTarget.mWallpaperX;
- mLastWallpaperXStep = mWallpaperTarget.mWallpaperXStep;
- }
- if (mWallpaperTarget.mWallpaperY >= 0) {
- mLastWallpaperY = mWallpaperTarget.mWallpaperY;
- mLastWallpaperYStep = mWallpaperTarget.mWallpaperYStep;
- }
- if (mWallpaperTarget.mWallpaperDisplayOffsetX != Integer.MIN_VALUE) {
- mLastWallpaperDisplayOffsetX = mWallpaperTarget.mWallpaperDisplayOffsetX;
- }
- if (mWallpaperTarget.mWallpaperDisplayOffsetY != Integer.MIN_VALUE) {
- mLastWallpaperDisplayOffsetY = mWallpaperTarget.mWallpaperDisplayOffsetY;
- }
- }
-
- // Start stepping backwards from here, ensuring that our wallpaper windows
- // are correctly placed.
- boolean changed = false;
- for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) {
- WindowToken token = mWallpaperTokens.get(curTokenNdx);
- if (token.hidden == visible) {
- if (DEBUG_WALLPAPER_LIGHT) Slog.d(TAG,
- "Wallpaper token " + token + " hidden=" + !visible);
- token.hidden = !visible;
- // Need to do a layout to ensure the wallpaper now has the correct size.
- getDefaultDisplayContentLocked().layoutNeeded = true;
- }
-
- final WindowList tokenWindows = token.windows;
- for (int wallpaperNdx = tokenWindows.size() - 1; wallpaperNdx >= 0; wallpaperNdx--) {
- WindowState wallpaper = tokenWindows.get(wallpaperNdx);
-
- if (visible) {
- updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
- }
-
- // First, make sure the client has the current visibility state.
- dispatchWallpaperVisibility(wallpaper, visible);
-
- wallpaper.mWinAnimator.mAnimLayer =
- wallpaper.mLayer + mWallpaperAnimLayerAdjustment;
- if (DEBUG_LAYERS || DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "adjustWallpaper win "
- + wallpaper + " anim layer: " + wallpaper.mWinAnimator.mAnimLayer);
-
- // First, if this window is at the current index, then all is well.
- if (wallpaper == foundW) {
- foundI--;
- foundW = foundI > 0 ? windows.get(foundI - 1) : null;
- continue;
- }
-
- // The window didn't match... the current wallpaper window,
- // wherever it is, is in the wrong place, so make sure it is
- // not in the list.
- int oldIndex = windows.indexOf(wallpaper);
- if (oldIndex >= 0) {
- if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Wallpaper removing at "
- + oldIndex + ": " + wallpaper);
- windows.remove(oldIndex);
- mWindowsChanged = true;
- if (oldIndex < foundI) {
- foundI--;
- }
- }
-
- // Now stick it in. For apps over wallpaper keep the wallpaper at the bottommost
- // layer. For keyguard over wallpaper put the wallpaper under the keyguard.
- int insertionIndex = 0;
- if (visible && foundW != null) {
- final int type = foundW.mAttrs.type;
- final int privateFlags = foundW.mAttrs.privateFlags;
- if ((privateFlags & PRIVATE_FLAG_KEYGUARD) != 0
- || type == TYPE_KEYGUARD_SCRIM) {
- insertionIndex = windows.indexOf(foundW);
- }
- }
- if (DEBUG_WALLPAPER_LIGHT || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) {
- Slog.v(TAG, "Moving wallpaper " + wallpaper
- + " from " + oldIndex + " to " + insertionIndex);
- }
-
- windows.add(insertionIndex, wallpaper);
- mWindowsChanged = true;
- changed = true;
- }
- }
-
- if (targetChanged && DEBUG_WALLPAPER_LIGHT) Slog.d(TAG, "New wallpaper: target="
- + mWallpaperTarget + " lower=" + mLowerWallpaperTarget + " upper="
- + mUpperWallpaperTarget);
-
- return changed;
- }
-
- void setWallpaperAnimLayerAdjustmentLocked(int adj) {
- if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "Setting wallpaper layer adj to " + adj);
- mWallpaperAnimLayerAdjustment = adj;
- for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) {
- WindowList windows = mWallpaperTokens.get(curTokenNdx).windows;
- for (int wallpaperNdx = windows.size() - 1; wallpaperNdx >= 0; wallpaperNdx--) {
- WindowState wallpaper = windows.get(wallpaperNdx);
- wallpaper.mWinAnimator.mAnimLayer = wallpaper.mLayer + adj;
- if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "setWallpaper win "
- + wallpaper + " anim layer: " + wallpaper.mWinAnimator.mAnimLayer);
- }
- }
- }
-
- boolean updateWallpaperOffsetLocked(WindowState wallpaperWin, int dw, int dh,
- boolean sync) {
- boolean changed = false;
- boolean rawChanged = false;
- float wpx = mLastWallpaperX >= 0 ? mLastWallpaperX : 0.5f;
- float wpxs = mLastWallpaperXStep >= 0 ? mLastWallpaperXStep : -1.0f;
- int availw = wallpaperWin.mFrame.right-wallpaperWin.mFrame.left-dw;
- int offset = availw > 0 ? -(int)(availw*wpx+.5f) : 0;
- if (mLastWallpaperDisplayOffsetX != Integer.MIN_VALUE) {
- offset += mLastWallpaperDisplayOffsetX;
- }
- changed = wallpaperWin.mXOffset != offset;
- if (changed) {
- if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
- + wallpaperWin + " x: " + offset);
- wallpaperWin.mXOffset = offset;
- }
- if (wallpaperWin.mWallpaperX != wpx || wallpaperWin.mWallpaperXStep != wpxs) {
- wallpaperWin.mWallpaperX = wpx;
- wallpaperWin.mWallpaperXStep = wpxs;
- rawChanged = true;
- }
-
- float wpy = mLastWallpaperY >= 0 ? mLastWallpaperY : 0.5f;
- float wpys = mLastWallpaperYStep >= 0 ? mLastWallpaperYStep : -1.0f;
- int availh = wallpaperWin.mFrame.bottom-wallpaperWin.mFrame.top-dh;
- offset = availh > 0 ? -(int)(availh*wpy+.5f) : 0;
- if (mLastWallpaperDisplayOffsetY != Integer.MIN_VALUE) {
- offset += mLastWallpaperDisplayOffsetY;
- }
- if (wallpaperWin.mYOffset != offset) {
- if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
- + wallpaperWin + " y: " + offset);
- changed = true;
- wallpaperWin.mYOffset = offset;
- }
- if (wallpaperWin.mWallpaperY != wpy || wallpaperWin.mWallpaperYStep != wpys) {
- wallpaperWin.mWallpaperY = wpy;
- wallpaperWin.mWallpaperYStep = wpys;
- rawChanged = true;
- }
-
- if (rawChanged && (wallpaperWin.mAttrs.privateFlags &
- WindowManager.LayoutParams.PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS) != 0) {
- try {
- if (DEBUG_WALLPAPER) Slog.v(TAG, "Report new wp offset "
- + wallpaperWin + " x=" + wallpaperWin.mWallpaperX
- + " y=" + wallpaperWin.mWallpaperY);
- if (sync) {
- mWaitingOnWallpaper = wallpaperWin;
- }
- wallpaperWin.mClient.dispatchWallpaperOffsets(
- wallpaperWin.mWallpaperX, wallpaperWin.mWallpaperY,
- wallpaperWin.mWallpaperXStep, wallpaperWin.mWallpaperYStep, sync);
- if (sync) {
- if (mWaitingOnWallpaper != null) {
- long start = SystemClock.uptimeMillis();
- if ((mLastWallpaperTimeoutTime+WALLPAPER_TIMEOUT_RECOVERY)
- < start) {
- try {
- if (DEBUG_WALLPAPER) Slog.v(TAG,
- "Waiting for offset complete...");
- mWindowMap.wait(WALLPAPER_TIMEOUT);
- } catch (InterruptedException e) {
- }
- if (DEBUG_WALLPAPER) Slog.v(TAG, "Offset complete!");
- if ((start+WALLPAPER_TIMEOUT)
- < SystemClock.uptimeMillis()) {
- Slog.i(TAG, "Timeout waiting for wallpaper to offset: "
- + wallpaperWin);
- mLastWallpaperTimeoutTime = start;
- }
- }
- mWaitingOnWallpaper = null;
- }
- }
- } catch (RemoteException e) {
- }
- }
-
- return changed;
- }
-
- void wallpaperOffsetsComplete(IBinder window) {
- synchronized (mWindowMap) {
- if (mWaitingOnWallpaper != null &&
- mWaitingOnWallpaper.mClient.asBinder() == window) {
- mWaitingOnWallpaper = null;
- mWindowMap.notifyAll();
- }
- }
- }
-
- void updateWallpaperOffsetLocked(WindowState changingTarget, boolean sync) {
- final DisplayContent displayContent = changingTarget.getDisplayContent();
- if (displayContent == null) {
- return;
- }
- final DisplayInfo displayInfo = displayContent.getDisplayInfo();
- final int dw = displayInfo.logicalWidth;
- final int dh = displayInfo.logicalHeight;
-
- WindowState target = mWallpaperTarget;
- if (target != null) {
- if (target.mWallpaperX >= 0) {
- mLastWallpaperX = target.mWallpaperX;
- } else if (changingTarget.mWallpaperX >= 0) {
- mLastWallpaperX = changingTarget.mWallpaperX;
- }
- if (target.mWallpaperY >= 0) {
- mLastWallpaperY = target.mWallpaperY;
- } else if (changingTarget.mWallpaperY >= 0) {
- mLastWallpaperY = changingTarget.mWallpaperY;
- }
- if (target.mWallpaperDisplayOffsetX != Integer.MIN_VALUE) {
- mLastWallpaperDisplayOffsetX = target.mWallpaperDisplayOffsetX;
- } else if (changingTarget.mWallpaperDisplayOffsetX != Integer.MIN_VALUE) {
- mLastWallpaperDisplayOffsetX = changingTarget.mWallpaperDisplayOffsetX;
- }
- if (target.mWallpaperDisplayOffsetY != Integer.MIN_VALUE) {
- mLastWallpaperDisplayOffsetY = target.mWallpaperDisplayOffsetY;
- } else if (changingTarget.mWallpaperDisplayOffsetY != Integer.MIN_VALUE) {
- mLastWallpaperDisplayOffsetY = changingTarget.mWallpaperDisplayOffsetY;
- }
- if (target.mWallpaperXStep >= 0) {
- mLastWallpaperXStep = target.mWallpaperXStep;
- } else if (changingTarget.mWallpaperXStep >= 0) {
- mLastWallpaperXStep = changingTarget.mWallpaperXStep;
- }
- if (target.mWallpaperYStep >= 0) {
- mLastWallpaperYStep = target.mWallpaperYStep;
- } else if (changingTarget.mWallpaperYStep >= 0) {
- mLastWallpaperYStep = changingTarget.mWallpaperYStep;
- }
- }
-
- for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) {
- WindowList windows = mWallpaperTokens.get(curTokenNdx).windows;
- for (int wallpaperNdx = windows.size() - 1; wallpaperNdx >= 0; wallpaperNdx--) {
- WindowState wallpaper = windows.get(wallpaperNdx);
- if (updateWallpaperOffsetLocked(wallpaper, dw, dh, sync)) {
- WindowStateAnimator winAnimator = wallpaper.mWinAnimator;
- winAnimator.computeShownFrameLocked();
- // No need to lay out the windows - we can just set the wallpaper position
- // directly.
- winAnimator.setWallpaperOffset(wallpaper.mShownFrame);
- // We only want to be synchronous with one wallpaper.
- sync = false;
- }
- }
- }
- }
-
- /**
- * Check wallpaper for visibility change and notify window if so.
- * @param wallpaper The wallpaper to test and notify.
- * @param visible Current visibility.
- */
- void dispatchWallpaperVisibility(final WindowState wallpaper, final boolean visible) {
- // Only send notification if the visibility actually changed and we are not trying to hide
- // the wallpaper when we are deferring hiding of the wallpaper.
- if (wallpaper.mWallpaperVisible != visible
- && (mDeferredHideWallpaper == null || visible)) {
- wallpaper.mWallpaperVisible = visible;
- try {
- if (DEBUG_VISIBILITY || DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
- "Updating vis of wallpaper " + wallpaper
- + ": " + visible + " from:\n" + Debug.getCallers(4, " "));
- wallpaper.mClient.dispatchAppVisibility(visible);
- } catch (RemoteException e) {
- }
- }
- }
-
- private void updateWallpaperVisibilityLocked() {
- final boolean visible = isWallpaperVisible(mWallpaperTarget);
- final DisplayContent displayContent = mWallpaperTarget.getDisplayContent();
- if (displayContent == null) {
- return;
- }
- final DisplayInfo displayInfo = displayContent.getDisplayInfo();
- final int dw = displayInfo.logicalWidth;
- final int dh = displayInfo.logicalHeight;
-
- for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) {
- WindowToken token = mWallpaperTokens.get(curTokenNdx);
- if (token.hidden == visible) {
- token.hidden = !visible;
- // Need to do a layout to ensure the wallpaper now has the
- // correct size.
- displayContent.layoutNeeded = true;
- }
-
- final WindowList windows = token.windows;
- for (int wallpaperNdx = windows.size() - 1; wallpaperNdx >= 0; wallpaperNdx--) {
- WindowState wallpaper = windows.get(wallpaperNdx);
- if (visible) {
- updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
- }
-
- dispatchWallpaperVisibility(wallpaper, visible);
- }
- }
- }
-
public int addWindow(Session session, IWindow client, int seq,
WindowManager.LayoutParams attrs, int viewVisibility, int displayId,
Rect outContentInsets, Rect outStableInsets, Rect outOutsets,
@@ -2561,12 +1956,11 @@
} else {
addWindowToListInOrderLocked(win, true);
if (type == TYPE_WALLPAPER) {
- mLastWallpaperTimeoutTime = 0;
+ mWallpaperControllerLocked.clearLastWallpaperTimeoutTime();
displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
} else if ((attrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
- } else if (mWallpaperTarget != null
- && mWallpaperTarget.mLayer >= win.mBaseLayer) {
+ } else if (mWallpaperControllerLocked.isBelowWallpaperTarget(win)) {
// If there is currently a wallpaper being shown, and
// the base layer of the new window is below the current
// layer of the target window, then adjust the wallpaper.
@@ -2863,7 +2257,7 @@
}
if (win.mAttrs.type == TYPE_WALLPAPER) {
- mLastWallpaperTimeoutTime = 0;
+ mWallpaperControllerLocked.clearLastWallpaperTimeoutTime();
getDefaultDisplayContentLocked().pendingLayoutChanges |=
WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
} else if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
@@ -2983,62 +2377,6 @@
}
}
- public void setWindowWallpaperPositionLocked(WindowState window, float x, float y,
- float xStep, float yStep) {
- if (window.mWallpaperX != x || window.mWallpaperY != y) {
- window.mWallpaperX = x;
- window.mWallpaperY = y;
- window.mWallpaperXStep = xStep;
- window.mWallpaperYStep = yStep;
- updateWallpaperOffsetLocked(window, true);
- }
- }
-
- void wallpaperCommandComplete(IBinder window, Bundle result) {
- synchronized (mWindowMap) {
- if (mWaitingOnWallpaper != null &&
- mWaitingOnWallpaper.mClient.asBinder() == window) {
- mWaitingOnWallpaper = null;
- mWindowMap.notifyAll();
- }
- }
- }
-
- public void setWindowWallpaperDisplayOffsetLocked(WindowState window, int x, int y) {
- if (window.mWallpaperDisplayOffsetX != x || window.mWallpaperDisplayOffsetY != y) {
- window.mWallpaperDisplayOffsetX = x;
- window.mWallpaperDisplayOffsetY = y;
- updateWallpaperOffsetLocked(window, true);
- }
- }
-
- public Bundle sendWindowWallpaperCommandLocked(WindowState window,
- String action, int x, int y, int z, Bundle extras, boolean sync) {
- if (window == mWallpaperTarget || window == mLowerWallpaperTarget
- || window == mUpperWallpaperTarget) {
- boolean doWait = sync;
- for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) {
- final WindowList windows = mWallpaperTokens.get(curTokenNdx).windows;
- for (int wallpaperNdx = windows.size() - 1; wallpaperNdx >= 0; wallpaperNdx--) {
- WindowState wallpaper = windows.get(wallpaperNdx);
- try {
- wallpaper.mClient.dispatchWallpaperCommand(action,
- x, y, z, extras, sync);
- // We only want to be synchronous with one wallpaper.
- sync = false;
- } catch (RemoteException e) {
- }
- }
- }
-
- if (doWait) {
- // XXX Need to wait for result.
- }
- }
-
- return null;
- }
-
public void onRectangleOnScreenRequested(IBinder token, Rect rectangle) {
synchronized (mWindowMap) {
if (mAccessibilityController != null) {
@@ -3293,7 +2631,7 @@
// Currently in a hide animation... turn this into
// an exit.
win.mExiting = true;
- } else if (win == mWallpaperTarget) {
+ } else if (mWallpaperControllerLocked.isWallpaperTarget(win)) {
// If the wallpaper is currently behind this
// window, we need to change both of them inside
// of a transaction to avoid artifacts.
@@ -3351,8 +2689,8 @@
performLayoutAndPlaceSurfacesLocked();
if (toBeDisplayed && win.mIsWallpaper) {
DisplayInfo displayInfo = getDefaultDisplayInfoLocked();
- updateWallpaperOffsetLocked(win,
- displayInfo.logicalWidth, displayInfo.logicalHeight, false);
+ mWallpaperControllerLocked.updateWallpaperOffset(
+ win, displayInfo.logicalWidth, displayInfo.logicalHeight, false);
}
if (win.mAppToken != null) {
win.mAppToken.updateReportedVisibilityLocked();
@@ -3495,7 +2833,8 @@
final boolean resizedWindow = !fullscreen && !dialogWindow;
Animation a = mAppTransition.loadAnimation(lp, transit, enter, containingWidth,
containingHeight, mCurConfiguration.orientation, containingFrame, contentInsets,
- surfaceInsets, appFrame, isVoiceInteraction, resizedWindow);
+ surfaceInsets, appFrame, isVoiceInteraction, resizedWindow,
+ atoken.mTask.mTaskId);
if (a != null) {
if (DEBUG_ANIM) {
RuntimeException e = null;
@@ -3629,7 +2968,7 @@
wtoken = new WindowToken(this, token, type, true);
mTokenMap.put(token, wtoken);
if (type == TYPE_WALLPAPER) {
- mWallpaperTokens.add(wtoken);
+ mWallpaperControllerLocked.addWallpaperToken(wtoken);
}
}
}
@@ -3685,10 +3024,10 @@
if (delayed && displayContent != null) {
displayContent.mExitingTokens.add(wtoken);
} else if (wtoken.windowType == TYPE_WALLPAPER) {
- mWallpaperTokens.remove(wtoken);
+ mWallpaperControllerLocked.removeWallpaperToken(wtoken);
}
} else if (wtoken.windowType == TYPE_WALLPAPER) {
- mWallpaperTokens.remove(wtoken);
+ mWallpaperControllerLocked.removeWallpaperToken(wtoken);
}
mInputMonitor.updateInputWindowsLw(true /*force*/);
@@ -4219,6 +3558,14 @@
}
@Override
+ public void overridePendingAppTransitionMultiThumb(AppTransitionAnimationSpec[] specs,
+ IRemoteCallback callback, boolean scaleUp) {
+ synchronized (mWindowMap) {
+ mAppTransition.overridePendingAppTransitionMultiThumb(specs, callback, scaleUp);
+ }
+ }
+
+ @Override
public void overridePendingAppTransitionInPlace(String packageName, int anim) {
synchronized(mWindowMap) {
mAppTransition.overrideInPlaceAppTransition(packageName, anim);
@@ -4427,7 +3774,7 @@
}
if (ent.array.getBoolean(
com.android.internal.R.styleable.Window_windowShowWallpaper, false)) {
- if (mWallpaperTarget == null) {
+ if (mWallpaperControllerLocked.getWallpaperTarget() == null) {
// If this theme is requesting a wallpaper, and the wallpaper
// is not curently visible, then this effectively serves as
// an opaque window and our starting window transition animation
@@ -5853,6 +5200,7 @@
if (!mBootAnimationStopped) {
// Do this one time.
+ Trace.asyncTraceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "Stop bootanim", 0);
try {
IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
if (surfaceFlinger != null) {
@@ -5875,6 +5223,7 @@
}
EventLog.writeEvent(EventLogTags.WM_BOOT_ANIMATION_DONE, SystemClock.uptimeMillis());
+ Trace.asyncTraceEnd(Trace.TRACE_TAG_WINDOW_MANAGER, "Stop bootanim", 0);
mDisplayEnabled = true;
if (DEBUG_SCREEN_ON || DEBUG_BOOT) Slog.i(TAG, "******************** ENABLING SCREEN!");
@@ -6286,7 +5635,7 @@
int right = wf.right - cr.right;
int bottom = wf.bottom - cr.bottom;
frame.union(left, top, right, bottom);
- ws.getTaskBounds(stackBounds);
+ ws.getTaskBounds(stackBounds, !BOUNDS_FOR_TOUCH);
if (!frame.intersect(stackBounds)) {
// Set frame empty if there's no intersection.
frame.setEmpty();
@@ -7656,7 +7005,9 @@
}
public void displayReady() {
- displayReady(Display.DEFAULT_DISPLAY);
+ for (Display display : mDisplays) {
+ displayReady(display.getDisplayId());
+ }
synchronized(mWindowMap) {
final DisplayContent displayContent = getDefaultDisplayContentLocked();
@@ -8282,10 +7633,7 @@
break;
case WALLPAPER_DRAW_PENDING_TIMEOUT: {
synchronized (mWindowMap) {
- if (mWallpaperDrawState == WALLPAPER_DRAW_PENDING) {
- mWallpaperDrawState = WALLPAPER_DRAW_TIMEOUT;
- if (DEBUG_APP_TRANSITIONS || DEBUG_WALLPAPER) Slog.v(TAG,
- "*** WALLPAPER DRAW TIMEOUT");
+ if (mWallpaperControllerLocked.processWallpaperDrawPendingTimeout()) {
performLayoutAndPlaceSurfacesLocked();
}
}
@@ -8908,7 +8256,7 @@
if (w.mIsImWindow) {
winAnimator.mAnimLayer += mInputMethodAnimLayerAdjustment;
} else if (w.mIsWallpaper) {
- winAnimator.mAnimLayer += mWallpaperAnimLayerAdjustment;
+ winAnimator.mAnimLayer += mWallpaperControllerLocked.getAnimLayerAdjustment();
}
if (winAnimator.mAnimLayer != oldLayer) {
layerChanged = true;
@@ -9209,404 +8557,399 @@
* @return bitmap indicating if another pass through layout must be made.
*/
public int handleAppTransitionReadyLocked(WindowList windows) {
- int changes = 0;
- int i;
int appsCount = mOpeningApps.size();
- boolean goodToGo = true;
+ if (!checkIfTransitionGoodToGo(appsCount)) {
+ return 0;
+ }
+ if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "**** GOOD TO GO");
+ int transit = mAppTransition.getAppTransition();
+ if (mSkipAppTransitionAnimation) {
+ transit = AppTransition.TRANSIT_UNSET;
+ }
+ mSkipAppTransitionAnimation = false;
+ mNoAnimationNotifyOnTransitionFinished.clear();
+
+ mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
+
+ rebuildAppWindowListLocked();
+
+ mInnerFields.mWallpaperMayChange = false;
+
+ // The top-most window will supply the layout params,
+ // and we will determine it below.
+ LayoutParams animLp = null;
+ int bestAnimLayer = -1;
+ boolean fullscreenAnim = false;
+ boolean voiceInteraction = false;
+
+ final WindowState lowerWallpaperTarget =
+ mWallpaperControllerLocked.getLowerWallpaperTarget();
+ final WindowState upperWallpaperTarget =
+ mWallpaperControllerLocked.getUpperWallpaperTarget();
+
+ boolean openingAppHasWallpaper = false;
+ boolean closingAppHasWallpaper = false;
+ final AppWindowToken lowerWallpaperAppToken;
+ final AppWindowToken upperWallpaperAppToken;
+ if (lowerWallpaperTarget == null) {
+ lowerWallpaperAppToken = upperWallpaperAppToken = null;
+ } else {
+ lowerWallpaperAppToken = lowerWallpaperTarget.mAppToken;
+ upperWallpaperAppToken = upperWallpaperTarget.mAppToken;
+ }
+
+ int i;
+ // Do a first pass through the tokens for two
+ // things:
+ // (1) Determine if both the closing and opening
+ // app token sets are wallpaper targets, in which
+ // case special animations are needed
+ // (since the wallpaper needs to stay static
+ // behind them).
+ // (2) Find the layout params of the top-most
+ // application window in the tokens, which is
+ // what will control the animation theme.
+ final int closingAppsCount = mClosingApps.size();
+ appsCount = closingAppsCount + mOpeningApps.size();
+ for (i = 0; i < appsCount; i++) {
+ final AppWindowToken wtoken;
+ if (i < closingAppsCount) {
+ wtoken = mClosingApps.valueAt(i);
+ if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) {
+ closingAppHasWallpaper = true;
+ }
+ } else {
+ wtoken = mOpeningApps.valueAt(i - closingAppsCount);
+ if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) {
+ openingAppHasWallpaper = true;
+ }
+ }
+
+ voiceInteraction |= wtoken.voiceInteraction;
+
+ if (wtoken.appFullscreen) {
+ WindowState ws = wtoken.findMainWindow();
+ if (ws != null) {
+ animLp = ws.mAttrs;
+ bestAnimLayer = ws.mLayer;
+ fullscreenAnim = true;
+ }
+ } else if (!fullscreenAnim) {
+ WindowState ws = wtoken.findMainWindow();
+ if (ws != null) {
+ if (ws.mLayer > bestAnimLayer) {
+ animLp = ws.mAttrs;
+ bestAnimLayer = ws.mLayer;
+ }
+ }
+ }
+ }
+
+ transit = maybeUpdateTransitToWallpaper(transit, openingAppHasWallpaper,
+ closingAppHasWallpaper, lowerWallpaperTarget, upperWallpaperTarget);
+
+ // If all closing windows are obscured, then there is
+ // no need to do an animation. This is the case, for
+ // example, when this transition is being done behind
+ // the lock screen.
+ if (!mPolicy.allowAppAnimationsLw()) {
+ if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
+ "Animations disallowed by keyguard or dream.");
+ animLp = null;
+ }
+
+ processApplicationsAnimatingInPlace(transit);
+
+ AppWindowToken topClosingApp = null;
+ int topClosingLayer = 0;
+ appsCount = mClosingApps.size();
+ for (i = 0; i < appsCount; i++) {
+ AppWindowToken wtoken = mClosingApps.valueAt(i);
+ final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
+ if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now closing app " + wtoken);
+ appAnimator.clearThumbnail();
+ appAnimator.animation = null;
+ wtoken.inPendingTransaction = false;
+ setTokenVisibilityLocked(wtoken, animLp, false, transit, false, voiceInteraction);
+ wtoken.updateReportedVisibilityLocked();
+ // Force the allDrawn flag, because we want to start
+ // this guy's animations regardless of whether it's
+ // gotten drawn.
+ wtoken.allDrawn = true;
+ wtoken.deferClearAllDrawn = false;
+ // Ensure that apps that are mid-starting are also scheduled to have their
+ // starting windows removed after the animation is complete
+ if (wtoken.startingWindow != null && !wtoken.startingWindow.mExiting) {
+ scheduleRemoveStartingWindowLocked(wtoken);
+ }
+ mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
+
+ if (animLp != null) {
+ int layer = -1;
+ for (int j = 0; j < wtoken.windows.size(); j++) {
+ WindowState win = wtoken.windows.get(j);
+ if (win.mWinAnimator.mAnimLayer > layer) {
+ layer = win.mWinAnimator.mAnimLayer;
+ }
+ }
+ if (topClosingApp == null || layer > topClosingLayer) {
+ topClosingApp = wtoken;
+ topClosingLayer = layer;
+ }
+ }
+ }
+
+ AppWindowToken topOpeningApp = null;
+ appsCount = mOpeningApps.size();
+ for (i = 0; i < appsCount; i++) {
+ AppWindowToken wtoken = mOpeningApps.valueAt(i);
+ final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
+ if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now opening app" + wtoken);
+
+ if (!appAnimator.usingTransferredAnimation) {
+ appAnimator.clearThumbnail();
+ appAnimator.animation = null;
+ }
+ wtoken.inPendingTransaction = false;
+ if (!setTokenVisibilityLocked(
+ wtoken, animLp, true, transit, false, voiceInteraction)){
+ // This token isn't going to be animating. Add it to the list of tokens to
+ // be notified of app transition complete since the notification will not be
+ // sent be the app window animator.
+ mNoAnimationNotifyOnTransitionFinished.add(wtoken.token);
+ }
+ wtoken.updateReportedVisibilityLocked();
+ wtoken.waitingToShow = false;
+
+ appAnimator.mAllAppWinAnimators.clear();
+ final int windowsCount = wtoken.allAppWindows.size();
+ for (int j = 0; j < windowsCount; j++) {
+ appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
+ }
+ mAnimator.mAnimating |= appAnimator.showAllWindowsLocked();
+ mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
+
+ int topOpeningLayer = 0;
+ if (animLp != null) {
+ int layer = -1;
+ for (int j = 0; j < wtoken.windows.size(); j++) {
+ WindowState win = wtoken.windows.get(j);
+ if (win.mWinAnimator.mAnimLayer > layer) {
+ layer = win.mWinAnimator.mAnimLayer;
+ }
+ }
+ if (topOpeningApp == null || layer > topOpeningLayer) {
+ topOpeningApp = wtoken;
+ topOpeningLayer = layer;
+ }
+ }
+ createThumbnailAppAnimator(transit, wtoken, topOpeningLayer, topClosingLayer);
+ }
+
+ AppWindowAnimator openingAppAnimator = (topOpeningApp == null) ? null :
+ topOpeningApp.mAppAnimator;
+ AppWindowAnimator closingAppAnimator = (topClosingApp == null) ? null :
+ topClosingApp.mAppAnimator;
+
+ mAppTransition.goodToGo(openingAppAnimator, closingAppAnimator);
+ mAppTransition.postAnimationCallback();
+ mAppTransition.clear();
+
+ mOpeningApps.clear();
+ mClosingApps.clear();
+
+ // This has changed the visibility of windows, so perform
+ // a new layout to get them all up-to-date.
+ getDefaultDisplayContentLocked().layoutNeeded = true;
+
+ // TODO(multidisplay): IMEs are only supported on the default display.
+ if (windows == getDefaultWindowListLocked()
+ && !moveInputMethodWindowsIfNeededLocked(true)) {
+ assignLayersLocked(windows);
+ }
+ updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES, true /*updateInputWindows*/);
+ mFocusMayChange = false;
+ notifyActivityDrawnForKeyguard();
+ return WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT
+ | WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG;
+
+ }
+
+ private int maybeUpdateTransitToWallpaper(int transit, boolean openingAppHasWallpaper,
+ boolean closingAppHasWallpaper, WindowState lowerWallpaperTarget,
+ WindowState upperWallpaperTarget) {
+ // if wallpaper is animating in or out set oldWallpaper to null else to wallpaper
+ final WindowState wallpaperTarget = mWallpaperControllerLocked.getWallpaperTarget();
+ final WindowState oldWallpaper = mWallpaperControllerLocked.isWallpaperTargetAnimating()
+ ? null : wallpaperTarget;
+ if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
+ "New wallpaper target=" + wallpaperTarget
+ + ", oldWallpaper=" + oldWallpaper
+ + ", lower target=" + lowerWallpaperTarget
+ + ", upper target=" + upperWallpaperTarget);
+ mAnimateWallpaperWithTarget = false;
+ if (closingAppHasWallpaper && openingAppHasWallpaper) {
+ if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Wallpaper animation!");
+ switch (transit) {
+ case AppTransition.TRANSIT_ACTIVITY_OPEN:
+ case AppTransition.TRANSIT_TASK_OPEN:
+ case AppTransition.TRANSIT_TASK_TO_FRONT:
+ transit = AppTransition.TRANSIT_WALLPAPER_INTRA_OPEN;
+ break;
+ case AppTransition.TRANSIT_ACTIVITY_CLOSE:
+ case AppTransition.TRANSIT_TASK_CLOSE:
+ case AppTransition.TRANSIT_TASK_TO_BACK:
+ transit = AppTransition.TRANSIT_WALLPAPER_INTRA_CLOSE;
+ break;
+ }
+ if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
+ "New transit: " + AppTransition.appTransitionToString(transit));
+ } else if ((oldWallpaper != null) && !mOpeningApps.isEmpty()
+ && !mOpeningApps.contains(oldWallpaper.mAppToken)) {
+ // We are transitioning from an activity with
+ // a wallpaper to one without.
+ transit = AppTransition.TRANSIT_WALLPAPER_CLOSE;
+ if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
+ "New transit away from wallpaper: "
+ + AppTransition.appTransitionToString(transit));
+ } else if (wallpaperTarget != null && wallpaperTarget.isVisibleLw()) {
+ // We are transitioning from an activity without
+ // a wallpaper to now showing the wallpaper
+ transit = AppTransition.TRANSIT_WALLPAPER_OPEN;
+ if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
+ "New transit into wallpaper: "
+ + AppTransition.appTransitionToString(transit));
+ } else {
+ mAnimateWallpaperWithTarget = true;
+ }
+ return transit;
+ }
+
+ private void processApplicationsAnimatingInPlace(int transit) {
+ if (transit == AppTransition.TRANSIT_TASK_IN_PLACE) {
+ // Find the focused window
+ final WindowState win =
+ findFocusedWindowLocked(getDefaultDisplayContentLocked());
+ if (win != null) {
+ final AppWindowToken wtoken = win.mAppToken;
+ final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
+ if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now animating app in place " + wtoken);
+ appAnimator.clearThumbnail();
+ appAnimator.animation = null;
+ updateTokenInPlaceLocked(wtoken, transit);
+ wtoken.updateReportedVisibilityLocked();
+
+ appAnimator.mAllAppWinAnimators.clear();
+ final int N = wtoken.allAppWindows.size();
+ for (int j = 0; j < N; j++) {
+ appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
+ }
+ mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
+ mAnimator.mAnimating |= appAnimator.showAllWindowsLocked();
+ }
+ }
+ }
+
+ private boolean checkIfTransitionGoodToGo(int appsCount) {
if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
"Checking " + appsCount + " opening apps (frozen="
- + mDisplayFrozen + " timeout="
- + mAppTransition.isTimeout() + ")...");
+ + mDisplayFrozen + " timeout="
+ + mAppTransition.isTimeout() + ")...");
if (!mAppTransition.isTimeout()) {
- for (i = 0; i < appsCount && goodToGo; i++) {
+ for (int i = 0; i < appsCount; i++) {
AppWindowToken wtoken = mOpeningApps.valueAt(i);
if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
"Check opening app=" + wtoken + ": allDrawn="
+ wtoken.allDrawn + " startingDisplayed="
+ wtoken.startingDisplayed + " startingMoved="
+ wtoken.startingMoved);
- if (!wtoken.allDrawn && !wtoken.startingDisplayed
- && !wtoken.startingMoved) {
- goodToGo = false;
+ if (!wtoken.allDrawn && !wtoken.startingDisplayed && !wtoken.startingMoved) {
+ return false;
}
}
- if (goodToGo && isWallpaperVisible(mWallpaperTarget)) {
- boolean wallpaperGoodToGo = true;
- for (int curTokenIndex = mWallpaperTokens.size() - 1;
- curTokenIndex >= 0 && wallpaperGoodToGo; curTokenIndex--) {
- WindowToken token = mWallpaperTokens.get(curTokenIndex);
- for (int curWallpaperIndex = token.windows.size() - 1; curWallpaperIndex >= 0;
- curWallpaperIndex--) {
- WindowState wallpaper = token.windows.get(curWallpaperIndex);
- if (wallpaper.mWallpaperVisible && !wallpaper.isDrawnLw()) {
- // We've told this wallpaper to be visible, but it is not drawn yet
- wallpaperGoodToGo = false;
- if (mWallpaperDrawState != WALLPAPER_DRAW_TIMEOUT) {
- // wait for this wallpaper until it is drawn or timeout
- goodToGo = false;
- }
- if (mWallpaperDrawState == WALLPAPER_DRAW_NORMAL) {
- mWallpaperDrawState = WALLPAPER_DRAW_PENDING;
- mH.removeMessages(H.WALLPAPER_DRAW_PENDING_TIMEOUT);
- mH.sendEmptyMessageDelayed(H.WALLPAPER_DRAW_PENDING_TIMEOUT,
- WALLPAPER_DRAW_PENDING_TIMEOUT_DURATION);
- }
- if (DEBUG_APP_TRANSITIONS || DEBUG_WALLPAPER) Slog.v(TAG,
- "Wallpaper should be visible but has not been drawn yet. " +
- "mWallpaperDrawState=" + mWallpaperDrawState);
- break;
- }
- }
- }
- if (wallpaperGoodToGo) {
- mWallpaperDrawState = WALLPAPER_DRAW_NORMAL;
- mH.removeMessages(H.WALLPAPER_DRAW_PENDING_TIMEOUT);
- }
- }
+ // If the wallpaper is visible, we need to check it's ready too.
+ return !mWallpaperControllerLocked.isWallpaperVisible() ||
+ mWallpaperControllerLocked.wallpaperTransitionReady();
}
- if (goodToGo) {
- if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "**** GOOD TO GO");
- int transit = mAppTransition.getAppTransition();
- if (mSkipAppTransitionAnimation) {
- transit = AppTransition.TRANSIT_UNSET;
- }
- mSkipAppTransitionAnimation = false;
- mNoAnimationNotifyOnTransitionFinished.clear();
+ return true;
+ }
- mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
-
- rebuildAppWindowListLocked();
-
- // if wallpaper is animating in or out set oldWallpaper to null else to wallpaper
- WindowState oldWallpaper =
- mWallpaperTarget != null && mWallpaperTarget.mWinAnimator.isAnimating()
- && !mWallpaperTarget.mWinAnimator.isDummyAnimation()
- ? null : mWallpaperTarget;
-
- mInnerFields.mWallpaperMayChange = false;
-
- // The top-most window will supply the layout params,
- // and we will determine it below.
- LayoutParams animLp = null;
- int bestAnimLayer = -1;
- boolean fullscreenAnim = false;
- boolean voiceInteraction = false;
-
- if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
- "New wallpaper target=" + mWallpaperTarget
- + ", oldWallpaper=" + oldWallpaper
- + ", lower target=" + mLowerWallpaperTarget
- + ", upper target=" + mUpperWallpaperTarget);
-
- boolean openingAppHasWallpaper = false;
- boolean closingAppHasWallpaper = false;
- final AppWindowToken lowerWallpaperAppToken;
- final AppWindowToken upperWallpaperAppToken;
- if (mLowerWallpaperTarget == null) {
- lowerWallpaperAppToken = upperWallpaperAppToken = null;
- } else {
- lowerWallpaperAppToken = mLowerWallpaperTarget.mAppToken;
- upperWallpaperAppToken = mUpperWallpaperTarget.mAppToken;
- }
-
- // Do a first pass through the tokens for two
- // things:
- // (1) Determine if both the closing and opening
- // app token sets are wallpaper targets, in which
- // case special animations are needed
- // (since the wallpaper needs to stay static
- // behind them).
- // (2) Find the layout params of the top-most
- // application window in the tokens, which is
- // what will control the animation theme.
- final int closingAppsCount = mClosingApps.size();
- appsCount = closingAppsCount + mOpeningApps.size();
- for (i = 0; i < appsCount; i++) {
- final AppWindowToken wtoken;
- if (i < closingAppsCount) {
- wtoken = mClosingApps.valueAt(i);
- if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) {
- closingAppHasWallpaper = true;
- }
- } else {
- wtoken = mOpeningApps.valueAt(i - closingAppsCount);
- if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) {
- openingAppHasWallpaper = true;
- }
- }
-
- voiceInteraction |= wtoken.voiceInteraction;
-
- if (wtoken.appFullscreen) {
- WindowState ws = wtoken.findMainWindow();
- if (ws != null) {
- animLp = ws.mAttrs;
- bestAnimLayer = ws.mLayer;
- fullscreenAnim = true;
- }
- } else if (!fullscreenAnim) {
- WindowState ws = wtoken.findMainWindow();
- if (ws != null) {
- if (ws.mLayer > bestAnimLayer) {
- animLp = ws.mAttrs;
- bestAnimLayer = ws.mLayer;
- }
- }
- }
- }
-
- mAnimateWallpaperWithTarget = false;
- if (closingAppHasWallpaper && openingAppHasWallpaper) {
- if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Wallpaper animation!");
- switch (transit) {
- case AppTransition.TRANSIT_ACTIVITY_OPEN:
- case AppTransition.TRANSIT_TASK_OPEN:
- case AppTransition.TRANSIT_TASK_TO_FRONT:
- transit = AppTransition.TRANSIT_WALLPAPER_INTRA_OPEN;
- break;
- case AppTransition.TRANSIT_ACTIVITY_CLOSE:
- case AppTransition.TRANSIT_TASK_CLOSE:
- case AppTransition.TRANSIT_TASK_TO_BACK:
- transit = AppTransition.TRANSIT_WALLPAPER_INTRA_CLOSE;
- break;
- }
- if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
- "New transit: " + AppTransition.appTransitionToString(transit));
- } else if ((oldWallpaper != null) && !mOpeningApps.isEmpty()
- && !mOpeningApps.contains(oldWallpaper.mAppToken)) {
- // We are transitioning from an activity with
- // a wallpaper to one without.
- transit = AppTransition.TRANSIT_WALLPAPER_CLOSE;
- if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
- "New transit away from wallpaper: "
- + AppTransition.appTransitionToString(transit));
- } else if (mWallpaperTarget != null && mWallpaperTarget.isVisibleLw()) {
- // We are transitioning from an activity without
- // a wallpaper to now showing the wallpaper
- transit = AppTransition.TRANSIT_WALLPAPER_OPEN;
- if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
- "New transit into wallpaper: "
- + AppTransition.appTransitionToString(transit));
- } else {
- mAnimateWallpaperWithTarget = true;
- }
-
- // If all closing windows are obscured, then there is
- // no need to do an animation. This is the case, for
- // example, when this transition is being done behind
- // the lock screen.
- if (!mPolicy.allowAppAnimationsLw()) {
- if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
- "Animations disallowed by keyguard or dream.");
- animLp = null;
- }
-
- AppWindowToken topOpeningApp = null;
- AppWindowToken topClosingApp = null;
- int topOpeningLayer = 0;
- int topClosingLayer = 0;
-
- // Process all applications animating in place
- if (transit == AppTransition.TRANSIT_TASK_IN_PLACE) {
- // Find the focused window
- final WindowState win =
- findFocusedWindowLocked(getDefaultDisplayContentLocked());
- if (win != null) {
- final AppWindowToken wtoken = win.mAppToken;
- final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
- if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now animating app in place " + wtoken);
- appAnimator.clearThumbnail();
- appAnimator.animation = null;
- updateTokenInPlaceLocked(wtoken, transit);
- wtoken.updateReportedVisibilityLocked();
-
- appAnimator.mAllAppWinAnimators.clear();
- final int N = wtoken.allAppWindows.size();
- for (int j = 0; j < N; j++) {
- appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
- }
- mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
- mAnimator.mAnimating |= appAnimator.showAllWindowsLocked();
- }
- }
-
- appsCount = mOpeningApps.size();
- for (i = 0; i < appsCount; i++) {
- AppWindowToken wtoken = mOpeningApps.valueAt(i);
- final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
- if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now opening app" + wtoken);
-
- if (!appAnimator.usingTransferredAnimation) {
- appAnimator.clearThumbnail();
- appAnimator.animation = null;
- }
- wtoken.inPendingTransaction = false;
- if (!setTokenVisibilityLocked(
- wtoken, animLp, true, transit, false, voiceInteraction)){
- // This token isn't going to be animating. Add it to the list of tokens to
- // be notified of app transition complete since the notification will not be
- // sent be the app window animator.
- mNoAnimationNotifyOnTransitionFinished.add(wtoken.token);
- }
- wtoken.updateReportedVisibilityLocked();
- wtoken.waitingToShow = false;
-
- appAnimator.mAllAppWinAnimators.clear();
- final int windowsCount = wtoken.allAppWindows.size();
- for (int j = 0; j < windowsCount; j++) {
- appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
- }
- mAnimator.mAnimating |= appAnimator.showAllWindowsLocked();
- mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
-
- if (animLp != null) {
- int layer = -1;
- for (int j = 0; j < wtoken.windows.size(); j++) {
- WindowState win = wtoken.windows.get(j);
- if (win.mWinAnimator.mAnimLayer > layer) {
- layer = win.mWinAnimator.mAnimLayer;
- }
- }
- if (topOpeningApp == null || layer > topOpeningLayer) {
- topOpeningApp = wtoken;
- topOpeningLayer = layer;
- }
- }
- }
- appsCount = mClosingApps.size();
- for (i = 0; i < appsCount; i++) {
- AppWindowToken wtoken = mClosingApps.valueAt(i);
- final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
- if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now closing app " + wtoken);
- appAnimator.clearThumbnail();
- appAnimator.animation = null;
- wtoken.inPendingTransaction = false;
- setTokenVisibilityLocked(wtoken, animLp, false, transit, false, voiceInteraction);
- wtoken.updateReportedVisibilityLocked();
- // Force the allDrawn flag, because we want to start
- // this guy's animations regardless of whether it's
- // gotten drawn.
- wtoken.allDrawn = true;
- wtoken.deferClearAllDrawn = false;
- // Ensure that apps that are mid-starting are also scheduled to have their
- // starting windows removed after the animation is complete
- if (wtoken.startingWindow != null && !wtoken.startingWindow.mExiting) {
- scheduleRemoveStartingWindowLocked(wtoken);
- }
- mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
-
- if (animLp != null) {
- int layer = -1;
- for (int j = 0; j < wtoken.windows.size(); j++) {
- WindowState win = wtoken.windows.get(j);
- if (win.mWinAnimator.mAnimLayer > layer) {
- layer = win.mWinAnimator.mAnimLayer;
- }
- }
- if (topClosingApp == null || layer > topClosingLayer) {
- topClosingApp = wtoken;
- topClosingLayer = layer;
- }
- }
- }
-
- AppWindowAnimator openingAppAnimator = (topOpeningApp == null) ? null :
- topOpeningApp.mAppAnimator;
- AppWindowAnimator closingAppAnimator = (topClosingApp == null) ? null :
- topClosingApp.mAppAnimator;
- Bitmap nextAppTransitionThumbnail = mAppTransition.getNextAppTransitionThumbnail();
- if (nextAppTransitionThumbnail != null
- && openingAppAnimator != null && openingAppAnimator.animation != null &&
- nextAppTransitionThumbnail.getConfig() != Config.ALPHA_8) {
- // This thumbnail animation is very special, we need to have
- // an extra surface with the thumbnail included with the animation.
- Rect dirty = new Rect(0, 0, nextAppTransitionThumbnail.getWidth(),
- nextAppTransitionThumbnail.getHeight());
- try {
- // TODO(multi-display): support other displays
- final DisplayContent displayContent = getDefaultDisplayContentLocked();
- final Display display = displayContent.getDisplay();
- final DisplayInfo displayInfo = displayContent.getDisplayInfo();
-
- // Create a new surface for the thumbnail
- SurfaceControl surfaceControl = new SurfaceControl(mFxSession,
- "thumbnail anim", dirty.width(), dirty.height(),
- PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
- surfaceControl.setLayerStack(display.getLayerStack());
- if (SHOW_TRANSACTIONS) {
- Slog.i(TAG, " THUMBNAIL " + surfaceControl + ": CREATE");
- }
-
- // Draw the thumbnail onto the surface
- Surface drawSurface = new Surface();
- drawSurface.copyFrom(surfaceControl);
- Canvas c = drawSurface.lockCanvas(dirty);
- c.drawBitmap(nextAppTransitionThumbnail, 0, 0, null);
- drawSurface.unlockCanvasAndPost(c);
- drawSurface.release();
-
- // Get the thumbnail animation
- Animation anim;
- if (mAppTransition.isNextThumbnailTransitionAspectScaled()) {
- // If this is a multi-window scenario, we use the windows frame as
- // destination of the thumbnail header animation. If this is a full screen
- // window scenario, we use the whole display as the target.
- WindowState win = topOpeningApp.findMainWindow();
- Rect appRect = win != null ? win.getContentFrameLw() :
- new Rect(0, 0, displayInfo.appWidth, displayInfo.appHeight);
- // For the new aspect-scaled transition, we want it to always show
- // above the animating opening/closing window, and we want to
- // synchronize its thumbnail surface with the surface for the
- // open/close animation (only on the way down)
- anim = mAppTransition.createThumbnailAspectScaleAnimationLocked(appRect);
- openingAppAnimator.thumbnailForceAboveLayer = Math.max(topOpeningLayer,
- topClosingLayer);
- openingAppAnimator.deferThumbnailDestruction =
- !mAppTransition.isNextThumbnailTransitionScaleUp();
- } else {
- anim = mAppTransition.createThumbnailScaleAnimationLocked(
- displayInfo.appWidth, displayInfo.appHeight, transit);
- }
- anim.restrictDuration(MAX_ANIMATION_DURATION);
- anim.scaleCurrentDuration(getTransitionAnimationScaleLocked());
-
- openingAppAnimator.thumbnail = surfaceControl;
- openingAppAnimator.thumbnailLayer = topOpeningLayer;
- openingAppAnimator.thumbnailAnimation = anim;
- openingAppAnimator.thumbnailX = mAppTransition.getStartingX();
- openingAppAnimator.thumbnailY = mAppTransition.getStartingY();
- } catch (OutOfResourcesException e) {
- Slog.e(TAG, "Can't allocate thumbnail/Canvas surface w=" + dirty.width()
- + " h=" + dirty.height(), e);
- openingAppAnimator.clearThumbnail();
- }
- }
-
- mAppTransition.goodToGo(openingAppAnimator, closingAppAnimator);
- mAppTransition.postAnimationCallback();
- mAppTransition.clear();
-
- mOpeningApps.clear();
- mClosingApps.clear();
-
- // This has changed the visibility of windows, so perform
- // a new layout to get them all up-to-date.
- changes |= WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT
- | WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG;
- getDefaultDisplayContentLocked().layoutNeeded = true;
-
- // TODO(multidisplay): IMEs are only supported on the default display.
- if (windows == getDefaultWindowListLocked()
- && !moveInputMethodWindowsIfNeededLocked(true)) {
- assignLayersLocked(windows);
- }
- updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES, true /*updateInputWindows*/);
- mFocusMayChange = false;
- notifyActivityDrawnForKeyguard();
+ private void createThumbnailAppAnimator(int transit, AppWindowToken appToken,
+ int openingLayer, int closingLayer) {
+ AppWindowAnimator openingAppAnimator = (appToken == null) ? null : appToken.mAppAnimator;
+ if (openingAppAnimator == null || openingAppAnimator.animation == null) {
+ return;
}
+ final int taskId = appToken.mTask.mTaskId;
+ Bitmap thumbnailHeader = mAppTransition.getAppTransitionThumbnailHeader(taskId);
+ if (thumbnailHeader == null || thumbnailHeader.getConfig() == Config.ALPHA_8) {
+ return;
+ }
+ // This thumbnail animation is very special, we need to have
+ // an extra surface with the thumbnail included with the animation.
+ Rect dirty = new Rect(0, 0, thumbnailHeader.getWidth(), thumbnailHeader.getHeight());
+ try {
+ // TODO(multi-display): support other displays
+ final DisplayContent displayContent = getDefaultDisplayContentLocked();
+ final Display display = displayContent.getDisplay();
+ final DisplayInfo displayInfo = displayContent.getDisplayInfo();
- return changes;
+ // Create a new surface for the thumbnail
+ SurfaceControl surfaceControl = new SurfaceControl(mFxSession,
+ "thumbnail anim", dirty.width(), dirty.height(),
+ PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
+ surfaceControl.setLayerStack(display.getLayerStack());
+ if (SHOW_TRANSACTIONS) {
+ Slog.i(TAG, " THUMBNAIL " + surfaceControl + ": CREATE");
+ }
+
+ // Draw the thumbnail onto the surface
+ Surface drawSurface = new Surface();
+ drawSurface.copyFrom(surfaceControl);
+ Canvas c = drawSurface.lockCanvas(dirty);
+ c.drawBitmap(thumbnailHeader, 0, 0, null);
+ drawSurface.unlockCanvasAndPost(c);
+ drawSurface.release();
+
+ // Get the thumbnail animation
+ Animation anim;
+ if (mAppTransition.isNextThumbnailTransitionAspectScaled()) {
+ // If this is a multi-window scenario, we use the windows frame as
+ // destination of the thumbnail header animation. If this is a full screen
+ // window scenario, we use the whole display as the target.
+ WindowState win = appToken.findMainWindow();
+ Rect appRect = win != null ? win.getContentFrameLw() :
+ new Rect(0, 0, displayInfo.appWidth, displayInfo.appHeight);
+ // For the new aspect-scaled transition, we want it to always show
+ // above the animating opening/closing window, and we want to
+ // synchronize its thumbnail surface with the surface for the
+ // open/close animation (only on the way down)
+ anim = mAppTransition.createThumbnailAspectScaleAnimationLocked(appRect,
+ thumbnailHeader, taskId);
+ Log.d(TAG, "assigning thumbnail force above layer: " + openingLayer + " " +
+ closingLayer);
+ openingAppAnimator.thumbnailForceAboveLayer = Math.max(openingLayer, closingLayer);
+ openingAppAnimator.deferThumbnailDestruction =
+ !mAppTransition.isNextThumbnailTransitionScaleUp();
+ } else {
+ anim = mAppTransition.createThumbnailScaleAnimationLocked(
+ displayInfo.appWidth, displayInfo.appHeight, transit, thumbnailHeader);
+ }
+ anim.restrictDuration(MAX_ANIMATION_DURATION);
+ anim.scaleCurrentDuration(getTransitionAnimationScaleLocked());
+
+ openingAppAnimator.thumbnail = surfaceControl;
+ openingAppAnimator.thumbnailLayer = openingLayer;
+ openingAppAnimator.thumbnailAnimation = anim;
+ mAppTransition.getNextAppTransitionStartRect(taskId, mTmpStartRect);
+ openingAppAnimator.thumbnailX = mTmpStartRect.left;
+ openingAppAnimator.thumbnailY = mTmpStartRect.top;
+ } catch (OutOfResourcesException e) {
+ Slog.e(TAG, "Can't allocate thumbnail/Canvas surface w=" + dirty.width()
+ + " h=" + dirty.height(), e);
+ openingAppAnimator.clearThumbnail();
+ }
}
/**
@@ -9624,10 +8967,7 @@
}
mNoAnimationNotifyOnTransitionFinished.clear();
- if (mDeferredHideWallpaper != null) {
- hideWallpapersLocked(mDeferredHideWallpaper);
- mDeferredHideWallpaper = null;
- }
+ mWallpaperControllerLocked.hideDeferredWallpapersIfNeeded();
// Restore window app tokens to the ActivityManager views
ArrayList<TaskStack> stacks = getDefaultDisplayContentLocked().getStacks();
@@ -9948,7 +9288,7 @@
if ((displayContent.pendingLayoutChanges &
WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0 &&
- adjustWallpaperWindowsLocked()) {
+ mWallpaperControllerLocked.adjustWallpaperWindows()) {
assignLayersLocked(windows);
displayContent.layoutNeeded = true;
}
@@ -10020,12 +9360,12 @@
handleFlagDimBehind(w);
}
- if (isDefaultDisplay && obscuredChanged && (mWallpaperTarget == w)
- && w.isVisibleLw()) {
+ if (isDefaultDisplay && obscuredChanged
+ && mWallpaperControllerLocked.isWallpaperTarget(w) && w.isVisibleLw()) {
// This is the wallpaper target and its obscured state
// changed... make sure the current wallaper's visibility
// has been updated accordingly.
- updateWallpaperVisibilityLocked();
+ mWallpaperControllerLocked.updateWallpaperVisibility();
}
final WindowStateAnimator winAnimator = w.mWinAnimator;
@@ -10274,7 +9614,7 @@
if (mInputMethodWindow == win) {
mInputMethodWindow = null;
}
- if (win == mWallpaperTarget) {
+ if (mWallpaperControllerLocked.isWallpaperTarget(win)) {
wallpaperDestroyed = true;
}
win.mWinAnimator.destroySurfaceLocked();
@@ -10291,7 +9631,7 @@
if (!token.hasVisible) {
exitingTokens.remove(i);
if (token.windowType == TYPE_WALLPAPER) {
- mWallpaperTokens.remove(token);
+ mWallpaperControllerLocked.removeWallpaperToken(token);
}
}
}
@@ -11198,21 +10538,7 @@
}
}
}
- if (!mWallpaperTokens.isEmpty()) {
- pw.println();
- pw.println(" Wallpaper tokens:");
- for (int i=mWallpaperTokens.size()-1; i>=0; i--) {
- WindowToken token = mWallpaperTokens.get(i);
- pw.print(" Wallpaper #"); pw.print(i);
- pw.print(' '); pw.print(token);
- if (dumpAll) {
- pw.println(':');
- token.dump(pw, " ");
- } else {
- pw.println();
- }
- }
- }
+ mWallpaperControllerLocked.dumpTokens(pw, " ", dumpAll);
if (!mFinishedStarting.isEmpty()) {
pw.println();
pw.println(" Finishing start of application tokens:");
@@ -11412,25 +10738,13 @@
if (mInputMethodWindow != null) {
pw.print(" mInputMethodWindow="); pw.println(mInputMethodWindow);
}
- pw.print(" mWallpaperTarget="); pw.println(mWallpaperTarget);
- if (mLowerWallpaperTarget != null || mUpperWallpaperTarget != null) {
- pw.print(" mLowerWallpaperTarget="); pw.println(mLowerWallpaperTarget);
- pw.print(" mUpperWallpaperTarget="); pw.println(mUpperWallpaperTarget);
- }
- pw.print(" mLastWallpaperX="); pw.print(mLastWallpaperX);
- pw.print(" mLastWallpaperY="); pw.println(mLastWallpaperY);
- if (mLastWallpaperDisplayOffsetX != Integer.MIN_VALUE
- || mLastWallpaperDisplayOffsetY != Integer.MIN_VALUE) {
- pw.print(" mLastWallpaperDisplayOffsetX="); pw.print(mLastWallpaperDisplayOffsetX);
- pw.print(" mLastWallpaperDisplayOffsetY=");
- pw.println(mLastWallpaperDisplayOffsetY);
- }
+ mWallpaperControllerLocked.dump(pw, " ");
if (mInputMethodAnimLayerAdjustment != 0 ||
- mWallpaperAnimLayerAdjustment != 0) {
+ mWallpaperControllerLocked.getAnimLayerAdjustment() != 0) {
pw.print(" mInputMethodAnimLayerAdjustment=");
pw.print(mInputMethodAnimLayerAdjustment);
pw.print(" mWallpaperAnimLayerAdjustment=");
- pw.println(mWallpaperAnimLayerAdjustment);
+ pw.println(mWallpaperControllerLocked.getAnimLayerAdjustment());
}
pw.print(" mSystemBooted="); pw.print(mSystemBooted);
pw.print(" mDisplayEnabled="); pw.println(mDisplayEnabled);
@@ -11985,12 +11299,18 @@
final WindowList windows = getDefaultWindowListLocked();
for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
final WindowState win = windows.get(winNdx);
+ final boolean isForceHiding = mPolicy.isForceHiding(win.mAttrs);
if (win.isVisibleLw()
- && (win.mAppToken != null || mPolicy.isForceHiding(win.mAttrs))) {
+ && (win.mAppToken != null || isForceHiding)) {
win.mWinAnimator.mDrawState = WindowStateAnimator.DRAW_PENDING;
// Force add to mResizingWindows.
win.mLastContentInsets.set(-1, -1, -1, -1);
mWaitingForDrawn.add(win);
+
+ // No need to wait for the windows below Keyguard.
+ if (isForceHiding) {
+ break;
+ }
}
}
requestTraversalLocked();
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 4061149..092a6d1 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -16,6 +16,7 @@
package com.android.server.wm;
+import static android.app.ActivityManager.FREEFORM_WORKSPACE_STACK_ID;
import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
@@ -33,11 +34,11 @@
import static com.android.server.wm.WindowManagerService.DEBUG_VISIBILITY;
import android.app.AppOpsManager;
-import android.os.Debug;
import android.os.PowerManager;
import android.os.RemoteCallbackList;
import android.os.SystemClock;
import android.os.WorkSource;
+import android.util.DisplayMetrics;
import android.util.TimeUtils;
import android.view.Display;
import android.view.IWindowFocusObserver;
@@ -78,6 +79,16 @@
final class WindowState implements WindowManagerPolicy.WindowState {
static final String TAG = "WindowState";
+ // The minimal size of a window within the usable area of the freeform stack.
+ private static final int MINIMUM_VISIBLE_WIDTH_IN_DP = 48;
+ private static final int MINIMUM_VISIBLE_HEIGHT_IN_DP = 32;
+
+ // The thickness of a window resize handle outside the window bounds on the free form workspace
+ // to capture touch events in that area.
+ private static final int RESIZE_HANDLE_WIDTH_IN_DP = 10;
+
+ static final boolean BOUNDS_FOR_TOUCH = true;
+
final WindowManagerService mService;
final WindowManagerPolicy mPolicy;
final Context mContext;
@@ -537,6 +548,7 @@
final Task task = mAppToken != null ? getTask() : null;
final boolean nonFullscreenTask = task != null && !task.isFullscreen();
+ final boolean freeformWorkspace = inFreeformWorkspace();
if (nonFullscreenTask) {
task.getBounds(mContainingFrame);
final WindowState imeWin = mService.mInputMethodWindow;
@@ -545,10 +557,20 @@
// IME is up and obscuring this window. Adjust the window position so it is visible.
mContainingFrame.top -= mContainingFrame.bottom - cf.bottom;
}
- // Make sure the containing frame is within the content frame so we don't layout
- // resized window under screen decorations.
- if (!mContainingFrame.intersect(cf)) {
- mContainingFrame.set(cf);
+
+ if (freeformWorkspace) {
+ // In free form mode we have only to set the rectangle if it wasn't set already. No
+ // need to intersect it with the (visible) "content frame" since it is allowed to
+ // be outside the visible desktop.
+ if (mContainingFrame.isEmpty()) {
+ mContainingFrame.set(cf);
+ }
+ } else {
+ // Make sure the containing frame is within the content frame so we don't layout
+ // resized window under screen decorations.
+ if (!mContainingFrame.intersect(cf)) {
+ mContainingFrame.set(cf);
+ }
}
mDisplayFrame.set(mContainingFrame);
} else {
@@ -652,20 +674,38 @@
// Make sure the content and visible frames are inside of the
// final window frame.
- mContentFrame.set(Math.max(mContentFrame.left, mFrame.left),
- Math.max(mContentFrame.top, mFrame.top),
- Math.min(mContentFrame.right, mFrame.right),
- Math.min(mContentFrame.bottom, mFrame.bottom));
+ if (freeformWorkspace && !mFrame.isEmpty()) {
+ // Keep the frame out of the blocked system area, limit it in size to the content area
+ // and make sure that there is always a minimum visible so that the user can drag it
+ // into a usable area..
+ final int height = Math.min(mFrame.height(), mContentFrame.height());
+ final int width = Math.min(mContentFrame.width(), mFrame.width());
+ final int minVisibleHeight = calculatePixelFromDp(MINIMUM_VISIBLE_HEIGHT_IN_DP);
+ final int minVisibleWidth = calculatePixelFromDp(MINIMUM_VISIBLE_WIDTH_IN_DP);
+ final int top = Math.max(mContentFrame.top,
+ Math.min(mFrame.top, mContentFrame.bottom - minVisibleHeight));
+ final int left = Math.max(mContentFrame.left + minVisibleWidth - width,
+ Math.min(mFrame.left, mContentFrame.right - minVisibleWidth));
+ mFrame.set(left, top, left + width, top + height);
+ mContentFrame.set(mFrame);
+ mVisibleFrame.set(mContentFrame);
+ mStableFrame.set(mContentFrame);
+ } else {
+ mContentFrame.set(Math.max(mContentFrame.left, mFrame.left),
+ Math.max(mContentFrame.top, mFrame.top),
+ Math.min(mContentFrame.right, mFrame.right),
+ Math.min(mContentFrame.bottom, mFrame.bottom));
- mVisibleFrame.set(Math.max(mVisibleFrame.left, mFrame.left),
- Math.max(mVisibleFrame.top, mFrame.top),
- Math.min(mVisibleFrame.right, mFrame.right),
- Math.min(mVisibleFrame.bottom, mFrame.bottom));
+ mVisibleFrame.set(Math.max(mVisibleFrame.left, mFrame.left),
+ Math.max(mVisibleFrame.top, mFrame.top),
+ Math.min(mVisibleFrame.right, mFrame.right),
+ Math.min(mVisibleFrame.bottom, mFrame.bottom));
- mStableFrame.set(Math.max(mStableFrame.left, mFrame.left),
- Math.max(mStableFrame.top, mFrame.top),
- Math.min(mStableFrame.right, mFrame.right),
- Math.min(mStableFrame.bottom, mFrame.bottom));
+ mStableFrame.set(Math.max(mStableFrame.left, mFrame.left),
+ Math.max(mStableFrame.top, mFrame.top),
+ Math.min(mStableFrame.right, mFrame.right),
+ Math.min(mStableFrame.bottom, mFrame.bottom));
+ }
mOverscanInsets.set(Math.max(mOverscanFrame.left - mFrame.left, 0),
Math.max(mOverscanFrame.top - mFrame.top, 0),
@@ -707,8 +747,8 @@
final DisplayContent displayContent = getDisplayContent();
if (displayContent != null) {
final DisplayInfo displayInfo = displayContent.getDisplayInfo();
- mService.updateWallpaperOffsetLocked(this,
- displayInfo.logicalWidth, displayInfo.logicalHeight, false);
+ mService.mWallpaperControllerLocked.updateWallpaperOffset(
+ this, displayInfo.logicalWidth, displayInfo.logicalHeight, false);
}
}
@@ -875,10 +915,22 @@
return mDisplayContent.getHomeStack();
}
- void getTaskBounds(Rect bounds) {
+ /**
+ * Retrieves the bounds for a task.
+ * @param bounds The rect which gets the bounds.
+ * @param forTouch Pass in BOUNDS_FOR_TOUCH to get touch related bounds, otherwise visible
+ * bounds will be returned.
+ */
+ void getTaskBounds(Rect bounds, boolean forTouch) {
final Task task = getTask();
if (task != null) {
task.getBounds(bounds);
+ if (forTouch == BOUNDS_FOR_TOUCH) {
+ if (inFreeformWorkspace()) {
+ final int delta = calculatePixelFromDp(RESIZE_HANDLE_WIDTH_IN_DP);
+ bounds.inset(-delta, -delta);
+ }
+ }
return;
}
bounds.set(mFrame);
@@ -1577,6 +1629,19 @@
}
}
+ private boolean inFreeformWorkspace() {
+ final Task task = getTask();
+ return task != null && task.mStack != null &&
+ task.mStack.mStackId == FREEFORM_WORKSPACE_STACK_ID;
+ }
+
+ private int calculatePixelFromDp(int dp) {
+ final Configuration serviceConfig = mService.mCurConfiguration;
+ // TODO(multidisplay): Update Dp to that of display stack is on.
+ final float density = serviceConfig.densityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE;
+ return (int)(dp * density);
+ }
+
void dump(PrintWriter pw, String prefix, boolean dumpAll) {
final TaskStack stack = getStack();
pw.print(prefix); pw.print("mDisplayId="); pw.print(getDisplayId());
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 28491e4..7aa48ab 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -47,7 +47,6 @@
import android.view.Surface.OutOfResourcesException;
import android.view.SurfaceControl;
import android.view.SurfaceSession;
-import android.view.View;
import android.view.WindowManager;
import android.view.WindowManagerPolicy;
import android.view.WindowManager.LayoutParams;
@@ -77,6 +76,7 @@
final WindowManagerPolicy mPolicy;
final Context mContext;
final boolean mIsWallpaper;
+ final WallpaperController mWallpaperControllerLocked;
// Currently running animation.
boolean mAnimating;
@@ -209,6 +209,7 @@
mSession = win.mSession;
mAttrType = win.mAttrs.type;
mIsWallpaper = win.mIsWallpaper;
+ mWallpaperControllerLocked = mService.mWallpaperControllerLocked;
}
public void setAnimation(Animation anim, long startTime) {
@@ -375,7 +376,7 @@
if (mWin.mIsImWindow) {
mAnimLayer += mService.mInputMethodAnimLayerAdjustment;
} else if (mIsWallpaper) {
- mAnimLayer += mService.mWallpaperAnimLayerAdjustment;
+ mAnimLayer += mWallpaperControllerLocked.getAnimLayerAdjustment();
}
if (DEBUG_LAYERS) Slog.v(TAG, "Stepping win " + this
+ " anim layer: " + mAnimLayer);
@@ -484,7 +485,7 @@
mService.mPendingRemove.add(mWin);
mWin.mRemoveOnExit = false;
}
- mService.hideWallpapersLocked(mWin);
+ mWallpaperControllerLocked.hideWallpapers(mWin);
}
void hide() {
@@ -986,7 +987,7 @@
}
mSurfaceControl.destroy();
}
- mService.hideWallpapersLocked(mWin);
+ mWallpaperControllerLocked.hideWallpapers(mWin);
} catch (RuntimeException e) {
Slog.w(TAG, "Exception thrown when destroying Window " + this
+ " surface " + mSurfaceControl + " session " + mSession
@@ -1012,7 +1013,7 @@
WindowManagerService.logSurface(mWin, "DESTROY PENDING", e);
}
mPendingDestroySurface.destroy();
- mService.hideWallpapersLocked(mWin);
+ mWallpaperControllerLocked.hideWallpapers(mWin);
}
} catch (RuntimeException e) {
Slog.w(TAG, "Exception thrown when destroying Window "
@@ -1033,7 +1034,7 @@
// Wallpapers are animated based on the "real" window they
// are currently targeting.
- final WindowState wallpaperTarget = mService.mWallpaperTarget;
+ final WindowState wallpaperTarget = mWallpaperControllerLocked.getWallpaperTarget();
if (mIsWallpaper && wallpaperTarget != null && mService.mAnimateWallpaperWithTarget) {
final WindowStateAnimator wallpaperAnimator = wallpaperTarget.mWinAnimator;
if (wallpaperAnimator.mHasLocalTransformation &&
@@ -1467,7 +1468,7 @@
hide();
} else if (w.mAttachedHidden || !w.isOnScreen()) {
hide();
- mService.hideWallpapersLocked(w);
+ mWallpaperControllerLocked.hideWallpapers(w);
// If we are waiting for this window to handle an
// orientation change, well, it is hidden, so
@@ -1522,7 +1523,7 @@
if (showSurfaceRobustlyLocked()) {
mLastHidden = false;
if (mIsWallpaper) {
- mService.dispatchWallpaperVisibility(w, true);
+ mWallpaperControllerLocked.dispatchWallpaperVisibility(w, true);
}
// This draw means the difference between unique content and mirroring.
// Run another pass through performLayout to set mHasContent in the
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index cd2885b..0f60cc8 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -21,6 +21,7 @@
import static android.app.admin.DevicePolicyManager.WIPE_EXTERNAL_STORAGE;
import static android.app.admin.DevicePolicyManager.WIPE_RESET_PROTECTION_DATA;
import static android.content.pm.PackageManager.GET_UNINSTALLED_PACKAGES;
+import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW;
import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
import static org.xmlpull.v1.XmlPullParser.END_TAG;
import static org.xmlpull.v1.XmlPullParser.TEXT;
@@ -44,6 +45,7 @@
import android.app.admin.IDevicePolicyManager;
import android.app.admin.SystemUpdatePolicy;
import android.app.backup.IBackupManager;
+import android.app.trust.TrustManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentResolver;
@@ -2957,7 +2959,8 @@
}
boolean requireEntry = (flags & DevicePolicyManager.RESET_PASSWORD_REQUIRE_ENTRY) != 0;
if (requireEntry) {
- utils.requireCredentialEntry(UserHandle.USER_ALL);
+ utils.requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW,
+ UserHandle.USER_ALL);
}
synchronized (this) {
int newOwner = requireEntry ? callingUid : -1;
@@ -3089,7 +3092,8 @@
mPowerManager.goToSleep(SystemClock.uptimeMillis(),
PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN, 0);
// Ensure the device is locked
- new LockPatternUtils(mContext).requireCredentialEntry(UserHandle.USER_ALL);
+ new LockPatternUtils(mContext).requireStrongAuth(
+ STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW, UserHandle.USER_ALL);
getWindowManager().lockNow(null);
} catch (RemoteException e) {
} finally {
@@ -4523,12 +4527,12 @@
long id = Binder.clearCallingIdentity();
try {
mUserManager.setUserEnabled(userId);
+ UserInfo parent = mUserManager.getProfileParent(userId);
Intent intent = new Intent(Intent.ACTION_MANAGED_PROFILE_ADDED);
intent.putExtra(Intent.EXTRA_USER, new UserHandle(userHandle));
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY |
Intent.FLAG_RECEIVER_FOREGROUND);
- // TODO This should send to parent of profile (which is always owner at the moment).
- mContext.sendBroadcastAsUser(intent, UserHandle.OWNER);
+ mContext.sendBroadcastAsUser(intent, new UserHandle(parent.id));
} finally {
restoreCallingIdentity(id);
}
@@ -4963,13 +4967,19 @@
IPackageManager pm = AppGlobals.getPackageManager();
long id = Binder.clearCallingIdentity();
try {
+ UserInfo parent = mUserManager.getProfileParent(callingUserId);
+ if (parent == null) {
+ Slog.e(LOG_TAG, "Cannot call addCrossProfileIntentFilter if there is no "
+ + "parent");
+ return;
+ }
if ((flags & DevicePolicyManager.FLAG_PARENT_CAN_ACCESS_MANAGED) != 0) {
pm.addCrossProfileIntentFilter(filter, who.getPackageName(), callingUserId,
- UserHandle.USER_OWNER, 0);
+ parent.id, 0);
}
if ((flags & DevicePolicyManager.FLAG_MANAGED_CAN_ACCESS_PARENT) != 0) {
pm.addCrossProfileIntentFilter(filter, who.getPackageName(),
- UserHandle.USER_OWNER, callingUserId, 0);
+ parent.id, callingUserId, 0);
}
} catch (RemoteException re) {
// Shouldn't happen
@@ -4988,12 +4998,18 @@
IPackageManager pm = AppGlobals.getPackageManager();
long id = Binder.clearCallingIdentity();
try {
- // Removing those that go from the managed profile to the primary user.
+ UserInfo parent = mUserManager.getProfileParent(callingUserId);
+ if (parent == null) {
+ Slog.e(LOG_TAG, "Cannot call clearCrossProfileIntentFilter if there is no "
+ + "parent");
+ return;
+ }
+ // Removing those that go from the managed profile to the parent.
pm.clearCrossProfileIntentFilters(callingUserId, who.getPackageName());
- // And those that go from the primary user to the managed profile.
+ // And those that go from the parent to the managed profile.
// If we want to support multiple managed profiles, we will have to only remove
// those that have callingUserId as their target.
- pm.clearCrossProfileIntentFilters(UserHandle.USER_OWNER, who.getPackageName());
+ pm.clearCrossProfileIntentFilters(parent.id, who.getPackageName());
} catch (RemoteException re) {
// Shouldn't happen
} finally {
diff --git a/services/tests/servicestests/Android.mk b/services/tests/servicestests/Android.mk
index 33979b1..3ad26d3 100644
--- a/services/tests/servicestests/Android.mk
+++ b/services/tests/servicestests/Android.mk
@@ -13,6 +13,7 @@
services.net \
easymocklib \
guava \
+ android-support-test \
mockito-target
LOCAL_JAVA_LIBRARIES := android.test.runner
diff --git a/services/tests/servicestests/AndroidManifest.xml b/services/tests/servicestests/AndroidManifest.xml
index 919293a..386a9cb 100644
--- a/services/tests/servicestests/AndroidManifest.xml
+++ b/services/tests/servicestests/AndroidManifest.xml
@@ -69,7 +69,7 @@
</application>
<instrumentation
- android:name="android.test.InstrumentationTestRunner"
+ android:name="android.support.test.runner.AndroidJUnitRunner"
android:targetPackage="com.android.frameworks.servicestests"
android:label="Frameworks Services Tests" />
</manifest>
diff --git a/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java b/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java
index 696f106..b4c76b7 100644
--- a/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java
@@ -943,8 +943,7 @@
if (capability == NET_CAPABILITY_CBS || capability == NET_CAPABILITY_DUN ||
capability == NET_CAPABILITY_EIMS || capability == NET_CAPABILITY_FOTA ||
capability == NET_CAPABILITY_IA || capability == NET_CAPABILITY_IMS ||
- capability == NET_CAPABILITY_RCS || capability == NET_CAPABILITY_XCAP ||
- capability == NET_CAPABILITY_TRUSTED || capability == NET_CAPABILITY_NOT_VPN) {
+ capability == NET_CAPABILITY_RCS || capability == NET_CAPABILITY_XCAP) {
assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED));
} else {
assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED));
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index d91fa90..2d31a78 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -512,8 +512,8 @@
Objects.equals(mGatewayInfo, d.mGatewayInfo) &&
Objects.equals(mVideoState, d.mVideoState) &&
Objects.equals(mStatusHints, d.mStatusHints) &&
- Objects.equals(mExtras, d.mExtras) &&
- Objects.equals(mIntentExtras, d.mIntentExtras);
+ areBundlesEqual(mExtras, d.mExtras) &&
+ areBundlesEqual(mIntentExtras, d.mIntentExtras);
}
return false;
}
@@ -1253,4 +1253,32 @@
});
}
}
+
+ /**
+ * Determines if two bundles are equal.
+ *
+ * @param bundle The original bundle.
+ * @param newBundle The bundle to compare with.
+ * @retrun {@code true} if the bundles are equal, {@code false} otherwise.
+ */
+ private static boolean areBundlesEqual(Bundle bundle, Bundle newBundle) {
+ if (bundle == null || newBundle == null) {
+ return bundle == newBundle;
+ }
+
+ if (bundle.size() != newBundle.size()) {
+ return false;
+ }
+
+ for(String key : bundle.keySet()) {
+ if (key != null) {
+ final Object value = bundle.get(key);
+ final Object newValue = newBundle.get(key);
+ if (!Objects.equals(value, newValue)) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
}
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 263c5e9..31f1d7f 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -358,6 +358,13 @@
public static final String KEY_CDMA_DTMF_TONE_DELAY_INT = "cdma_dtmf_tone_delay_int";
/**
+ * Determines whether conference calls are supported by a carrier. When {@code true},
+ * conference calling is supported, {@code false otherwise}.
+ * @hide
+ */
+ public static final String KEY_SUPPORT_CONFERENCE_CALL_BOOL = "support_conference_call_bool";
+
+ /**
* If this is true, the SIM card (through Customer Service Profile EF file) will be able to
* prevent manual operator selection. If false, this SIM setting will be ignored and manual
* operator selection will always be available. See CPHS4_2.WW6, CPHS B.4.7.1 for more
@@ -457,6 +464,7 @@
sDefaults.putBoolean(KEY_FORCE_HOME_NETWORK_BOOL, false);
sDefaults.putInt(KEY_IMS_DTMF_TONE_DELAY_INT, 0);
sDefaults.putInt(KEY_CDMA_DTMF_TONE_DELAY_INT, 100);
+ sDefaults.putBoolean(KEY_SUPPORT_CONFERENCE_CALL_BOOL, true);
// MMS defaults
sDefaults.putBoolean(KEY_MMS_ALIAS_ENABLED_BOOL, false);
diff --git a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
index 62859ec..a8fd91c 100644
--- a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
+++ b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
@@ -30,6 +30,7 @@
import android.os.IRemoteCallback;
import android.os.RemoteException;
import android.util.DisplayMetrics;
+import android.view.AppTransitionAnimationSpec;
import java.lang.Override;
@@ -241,6 +242,12 @@
}
@Override
+ public void overridePendingAppTransitionMultiThumb(AppTransitionAnimationSpec[] specs,
+ IRemoteCallback callback, boolean scaleUp) {
+ // TODO Auto-generated method stub
+ }
+
+ @Override
public void pauseKeyDispatching(IBinder arg0) throws RemoteException {
// TODO Auto-generated method stub