diff options
Diffstat (limited to 'core/java')
25 files changed, 498 insertions, 106 deletions
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java index 2a17fa6..d56dc1e 100644 --- a/core/java/android/app/ActivityManagerInternal.java +++ b/core/java/android/app/ActivityManagerInternal.java @@ -23,8 +23,8 @@ package android.app; */ public abstract class ActivityManagerInternal { // Called by the power manager. - public abstract void goingToSleep(); - public abstract void wakingUp(); + public abstract void onWakefulnessChanged(int wakefulness); + public abstract int startIsolatedProcess(String entryPoint, String[] mainArgs, String processName, String abiOverride, int uid, Runnable crashHandler); } diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index 1de9b47..2df35df 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -20,9 +20,9 @@ import android.app.usage.IUsageStatsManager; import android.app.usage.UsageStatsManager; import android.appwidget.AppWidgetManager; import android.os.Build; - import android.service.persistentdata.IPersistentDataBlockService; import android.service.persistentdata.PersistentDataBlockManager; + import com.android.internal.appwidget.IAppWidgetService; import com.android.internal.policy.PolicyManager; import com.android.internal.util.Preconditions; @@ -125,6 +125,7 @@ import android.print.PrintManager; import android.service.fingerprint.IFingerprintService; import android.service.fingerprint.FingerprintManager; import android.telecom.TelecomManager; +import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.content.ClipboardManager; import android.util.AndroidRuntimeException; @@ -561,6 +562,11 @@ class ContextImpl extends Context { return new TelephonyManager(ctx.getOuterContext()); }}); + registerService(TELEPHONY_SUBSCRIPTION_SERVICE, new ServiceFetcher() { + public Object createService(ContextImpl ctx) { + return new SubscriptionManager(ctx.getOuterContext()); + }}); + registerService(TELECOM_SERVICE, new ServiceFetcher() { public Object createService(ContextImpl ctx) { return new TelecomManager(ctx.getOuterContext()); diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 07e8dc5..9e8a793 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -4115,9 +4115,9 @@ public class Notification implements Parcelable * <pre class="prettyprint"> * Notification noti = new Notification.Builder() * .setSmallIcon(R.drawable.ic_stat_player) - * .setContentTitle("Track title") // these three lines are optional - * .setContentText("Artist - Album") // if you use - * .setLargeIcon(albumArtBitmap)) // setMediaSession(token) + * .setContentTitle("Track title") + * .setContentText("Artist - Album") + * .setLargeIcon(albumArtBitmap)) * .setStyle(<b>new Notification.MediaStyle()</b> * .setMediaSession(mySession)) * .build(); diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index 57d53aa..d00cbb7 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -1345,6 +1345,24 @@ public class DevicePolicyManager { } /** + * Returns the profile with the smallest maximum failed passwords for wipe, + * for the given user. So for primary user, it might return the primary or + * a managed profile. For a secondary user, it would be the same as the + * user passed in. + * @hide Used only by Keyguard + */ + public int getProfileWithMinimumFailedPasswordsForWipe(int userHandle) { + if (mService != null) { + try { + return mService.getProfileWithMinimumFailedPasswordsForWipe(userHandle); + } catch (RemoteException e) { + Log.w(TAG, "Failed talking with device policy service", e); + } + } + return UserHandle.USER_NULL; + } + + /** * Flag for {@link #resetPassword}: don't allow other admins to change * the password again until the user has entered it. */ @@ -1363,13 +1381,16 @@ public class DevicePolicyManager { * characters when the requested quality is only numeric), in which case * the currently active quality will be increased to match. * + * <p>Calling with a null or empty password will clear any existing PIN, + * pattern or password if the current password constraints allow it. + * * <p>The calling device admin must have requested * {@link DeviceAdminInfo#USES_POLICY_RESET_PASSWORD} to be able to call * this method; if it has not, a security exception will be thrown. * * <p>Calling this from a managed profile will throw a security exception. * - * @param password The new password for the user. + * @param password The new password for the user. Null or empty clears the password. * @param flags May be 0 or {@link #RESET_PASSWORD_REQUIRE_ENTRY}. * @return Returns true if the password was applied, or false if it is * not acceptable for the current constraints. diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl index 07aa800..d144ae8 100644 --- a/core/java/android/app/admin/IDevicePolicyManager.aidl +++ b/core/java/android/app/admin/IDevicePolicyManager.aidl @@ -66,6 +66,7 @@ interface IDevicePolicyManager { boolean isActivePasswordSufficient(int userHandle); int getCurrentFailedPasswordAttempts(int userHandle); + int getProfileWithMinimumFailedPasswordsForWipe(int userHandle); void setMaximumFailedPasswordsForWipe(in ComponentName admin, int num, int userHandle); int getMaximumFailedPasswordsForWipe(in ComponentName admin, int userHandle); diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index a73ba74..0daa8e2 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -2245,6 +2245,8 @@ public abstract class Context { * @see android.media.MediaRouter * @see #TELEPHONY_SERVICE * @see android.telephony.TelephonyManager + * @see #TELEPHONY_SUBSCRIPTION_SERVICE + * @see android.telephony.SubscriptionManager * @see #INPUT_METHOD_SERVICE * @see android.view.inputmethod.InputMethodManager * @see #UI_MODE_SERVICE @@ -2589,6 +2591,16 @@ public abstract class Context { /** * Use with {@link #getSystemService} to retrieve a + * {@link android.telephony.SubscriptionManager} for handling management the + * telephony subscriptions of the device. + * + * @see #getSystemService + * @see android.telephony.SubscriptionManager + */ + public static final String TELEPHONY_SUBSCRIPTION_SERVICE = "telephony_subscription_service"; + + /** + * Use with {@link #getSystemService} to retrieve a * {@link android.telecom.TelecomManager} to manage telecom-related features * of the device. * diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index e9f7c50..5c705e6 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -1078,6 +1078,26 @@ public abstract class PackageManager { "android.hardware.camera.capability.raw"; /** + * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}: At least one + * of the cameras on the device supports the + * {@link android.hardware.camera2.CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE BURST_CAPTURE} + * capability level. + */ + @SdkConstant(SdkConstantType.FEATURE) + public static final String FEATURE_CAMERA_CAPABILITY_BURST_CAPTURE = + "android.hardware.camera.capability.burst_capture"; + + /** + * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}: At least one + * of the cameras on the device supports the + * {@link android.hardware.camera2.CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS READ_SENSOR_SETTINGS} + * capability level. + */ + @SdkConstant(SdkConstantType.FEATURE) + public static final String FEATURE_CAMERA_CAPABILITY_READ_SENSOR_SETTINGS = + "android.hardware.camera.capability.read_sensor_settings"; + + /** * Feature for {@link #getSystemAvailableFeatures} and * {@link #hasSystemFeature}: The device is capable of communicating with * consumer IR devices. diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java index 754f270..98096dc 100644 --- a/core/java/android/hardware/camera2/CameraCharacteristics.java +++ b/core/java/android/hardware/camera2/CameraCharacteristics.java @@ -395,6 +395,8 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * <p><b>Range of valid values:</b><br></p> * <p><code>Min.exposure compensation * {@link CameraCharacteristics#CONTROL_AE_COMPENSATION_STEP android.control.aeCompensationStep} <= -2 EV</code></p> * <p><code>Max.exposure compensation * {@link CameraCharacteristics#CONTROL_AE_COMPENSATION_STEP android.control.aeCompensationStep} >= 2 EV</code></p> + * <p>LEGACY devices may support a smaller range than this, including the range [0,0], which + * indicates that changing the exposure compensation is not supported.</p> * <p>This key is available on all devices.</p> * * @see CameraCharacteristics#CONTROL_AE_COMPENSATION_STEP diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl index e140c1f..79f920e 100644 --- a/core/java/android/net/IConnectivityManager.aidl +++ b/core/java/android/net/IConnectivityManager.aidl @@ -163,4 +163,5 @@ interface IConnectivityManager boolean addVpnAddress(String address, int prefixLength); boolean removeVpnAddress(String address, int prefixLength); + boolean setUnderlyingNetworksForVpn(in Network[] networks); } diff --git a/core/java/android/net/NetworkIdentity.java b/core/java/android/net/NetworkIdentity.java index 36dd2fdfb..d36707e 100644 --- a/core/java/android/net/NetworkIdentity.java +++ b/core/java/android/net/NetworkIdentity.java @@ -34,7 +34,7 @@ import java.util.Objects; * * @hide */ -public class NetworkIdentity { +public class NetworkIdentity implements Comparable<NetworkIdentity> { /** * When enabled, combine all {@link #mSubType} together under * {@link #SUBTYPE_COMBINED}. @@ -76,7 +76,7 @@ public class NetworkIdentity { @Override public String toString() { - final StringBuilder builder = new StringBuilder("["); + final StringBuilder builder = new StringBuilder("{"); builder.append("type=").append(getNetworkTypeName(mType)); builder.append(", subType="); if (COMBINE_SUBTYPE_ENABLED) { @@ -95,7 +95,7 @@ public class NetworkIdentity { if (mRoaming) { builder.append(", ROAMING"); } - return builder.append("]").toString(); + return builder.append("}").toString(); } public int getType() { @@ -170,4 +170,22 @@ public class NetworkIdentity { return new NetworkIdentity(type, subType, subscriberId, networkId, roaming); } + + @Override + public int compareTo(NetworkIdentity another) { + int res = Integer.compare(mType, another.mType); + if (res == 0) { + res = Integer.compare(mSubType, another.mSubType); + } + if (res == 0 && mSubscriberId != null && another.mSubscriberId != null) { + res = mSubscriberId.compareTo(another.mSubscriberId); + } + if (res == 0 && mNetworkId != null && another.mNetworkId != null) { + res = mNetworkId.compareTo(another.mNetworkId); + } + if (res == 0) { + res = Boolean.compare(mRoaming, another.mRoaming); + } + return res; + } } diff --git a/core/java/android/net/NetworkStats.java b/core/java/android/net/NetworkStats.java index ea5dfd1..2afe578 100644 --- a/core/java/android/net/NetworkStats.java +++ b/core/java/android/net/NetworkStats.java @@ -733,6 +733,22 @@ public class NetworkStats implements Parcelable { } /** + * Return text description of {@link #set} value. + */ + public static String setToCheckinString(int set) { + switch (set) { + case SET_ALL: + return "all"; + case SET_DEFAULT: + return "def"; + case SET_FOREGROUND: + return "fg"; + default: + return "unk"; + } + } + + /** * Return text description of {@link #tag} value. */ public static String tagToString(int tag) { diff --git a/core/java/android/net/NetworkStatsHistory.java b/core/java/android/net/NetworkStatsHistory.java index 62d8738..4a4accb 100644 --- a/core/java/android/net/NetworkStatsHistory.java +++ b/core/java/android/net/NetworkStatsHistory.java @@ -26,6 +26,7 @@ import static android.net.NetworkStatsHistory.DataStreamUtils.writeVarLongArray; import static android.net.NetworkStatsHistory.Entry.UNKNOWN; import static android.net.NetworkStatsHistory.ParcelUtils.readLongArray; import static android.net.NetworkStatsHistory.ParcelUtils.writeLongArray; +import static android.text.format.DateUtils.SECOND_IN_MILLIS; import static com.android.internal.util.ArrayUtils.total; import android.os.Parcel; @@ -38,6 +39,7 @@ import java.io.CharArrayWriter; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; +import java.io.PrintWriter; import java.net.ProtocolException; import java.util.Arrays; import java.util.Random; @@ -573,8 +575,22 @@ public class NetworkStatsHistory implements Parcelable { return (long) (start + (r.nextFloat() * (end - start))); } + /** + * Quickly determine if this history intersects with given window. + */ + public boolean intersects(long start, long end) { + final long dataStart = getStart(); + final long dataEnd = getEnd(); + if (start >= dataStart && start <= dataEnd) return true; + if (end >= dataStart && end <= dataEnd) return true; + if (dataStart >= start && dataStart <= end) return true; + if (dataEnd >= start && dataEnd <= end) return true; + return false; + } + public void dump(IndentingPrintWriter pw, boolean fullHistory) { - pw.print("NetworkStatsHistory: bucketDuration="); pw.println(bucketDuration); + pw.print("NetworkStatsHistory: bucketDuration="); + pw.println(bucketDuration / SECOND_IN_MILLIS); pw.increaseIndent(); final int start = fullHistory ? 0 : Math.max(0, bucketCount - 32); @@ -583,19 +599,35 @@ public class NetworkStatsHistory implements Parcelable { } for (int i = start; i < bucketCount; i++) { - pw.print("bucketStart="); pw.print(bucketStart[i]); - if (activeTime != null) { pw.print(" activeTime="); pw.print(activeTime[i]); } - if (rxBytes != null) { pw.print(" rxBytes="); pw.print(rxBytes[i]); } - if (rxPackets != null) { pw.print(" rxPackets="); pw.print(rxPackets[i]); } - if (txBytes != null) { pw.print(" txBytes="); pw.print(txBytes[i]); } - if (txPackets != null) { pw.print(" txPackets="); pw.print(txPackets[i]); } - if (operations != null) { pw.print(" operations="); pw.print(operations[i]); } + pw.print("st="); pw.print(bucketStart[i] / SECOND_IN_MILLIS); + if (rxBytes != null) { pw.print(" rb="); pw.print(rxBytes[i]); } + if (rxPackets != null) { pw.print(" rp="); pw.print(rxPackets[i]); } + if (txBytes != null) { pw.print(" tb="); pw.print(txBytes[i]); } + if (txPackets != null) { pw.print(" tp="); pw.print(txPackets[i]); } + if (operations != null) { pw.print(" op="); pw.print(operations[i]); } pw.println(); } pw.decreaseIndent(); } + public void dumpCheckin(PrintWriter pw) { + pw.print("d,"); + pw.print(bucketDuration / SECOND_IN_MILLIS); + pw.println(); + + for (int i = 0; i < bucketCount; i++) { + pw.print("b,"); + pw.print(bucketStart[i] / SECOND_IN_MILLIS); pw.print(','); + if (rxBytes != null) { pw.print(rxBytes[i]); } else { pw.print("*"); } pw.print(','); + if (rxPackets != null) { pw.print(rxPackets[i]); } else { pw.print("*"); } pw.print(','); + if (txBytes != null) { pw.print(txBytes[i]); } else { pw.print("*"); } pw.print(','); + if (txPackets != null) { pw.print(txPackets[i]); } else { pw.print("*"); } pw.print(','); + if (operations != null) { pw.print(operations[i]); } else { pw.print("*"); } + pw.println(); + } + } + @Override public String toString() { final CharArrayWriter writer = new CharArrayWriter(); diff --git a/core/java/android/net/NetworkTemplate.java b/core/java/android/net/NetworkTemplate.java index 27197cc..b839e0a 100644 --- a/core/java/android/net/NetworkTemplate.java +++ b/core/java/android/net/NetworkTemplate.java @@ -16,6 +16,7 @@ package android.net; +import static android.net.ConnectivityManager.TYPE_BLUETOOTH; import static android.net.ConnectivityManager.TYPE_ETHERNET; import static android.net.ConnectivityManager.TYPE_WIFI; import static android.net.ConnectivityManager.TYPE_WIFI_P2P; @@ -34,10 +35,10 @@ import android.content.res.Resources; import android.os.Parcel; import android.os.Parcelable; -import java.util.Objects; - import com.android.internal.annotations.VisibleForTesting; +import java.util.Objects; + /** * Template definition used to generically match {@link NetworkIdentity}, * usually when collecting statistics. @@ -53,6 +54,7 @@ public class NetworkTemplate implements Parcelable { public static final int MATCH_ETHERNET = 5; public static final int MATCH_MOBILE_WILDCARD = 6; public static final int MATCH_WIFI_WILDCARD = 7; + public static final int MATCH_BLUETOOTH = 8; /** * Set of {@link NetworkInfo#getType()} that reflect data usage. @@ -134,6 +136,14 @@ public class NetworkTemplate implements Parcelable { return new NetworkTemplate(MATCH_ETHERNET, null, null); } + /** + * Template to combine all {@link ConnectivityManager#TYPE_BLUETOOTH} style + * networks together. + */ + public static NetworkTemplate buildTemplateBluetooth() { + return new NetworkTemplate(MATCH_BLUETOOTH, null, null); + } + private final int mMatchRule; private final String mSubscriberId; private final String mNetworkId; @@ -222,6 +232,8 @@ public class NetworkTemplate implements Parcelable { return matchesMobileWildcard(ident); case MATCH_WIFI_WILDCARD: return matchesWifiWildcard(ident); + case MATCH_BLUETOOTH: + return matchesBluetooth(ident); default: throw new IllegalArgumentException("unknown network template"); } @@ -316,6 +328,16 @@ public class NetworkTemplate implements Parcelable { } } + /** + * Check if matches Bluetooth network template. + */ + private boolean matchesBluetooth(NetworkIdentity ident) { + if (ident.mType == TYPE_BLUETOOTH) { + return true; + } + return false; + } + private static String getMatchRuleName(int matchRule) { switch (matchRule) { case MATCH_MOBILE_3G_LOWER: @@ -332,6 +354,8 @@ public class NetworkTemplate implements Parcelable { return "MOBILE_WILDCARD"; case MATCH_WIFI_WILDCARD: return "WIFI_WILDCARD"; + case MATCH_BLUETOOTH: + return "BLUETOOTH"; default: return "UNKNOWN"; } diff --git a/core/java/android/net/VpnService.java b/core/java/android/net/VpnService.java index d469487..ad54912 100644 --- a/core/java/android/net/VpnService.java +++ b/core/java/android/net/VpnService.java @@ -27,6 +27,7 @@ import android.content.Context; import android.content.Intent; import android.content.pm.IPackageManager; import android.content.pm.PackageManager; +import android.net.Network; import android.net.NetworkUtils; import android.os.Binder; import android.os.IBinder; @@ -288,6 +289,46 @@ public class VpnService extends Service { } /** + * Sets the underlying networks used by the VPN for its upstream connections. + * + * Used by the system to know the actual networks that carry traffic for apps affected by this + * VPN in order to present this information to the user (e.g., via status bar icons). + * + * This method only needs to be called if the VPN has explicitly bound its underlying + * communications channels — such as the socket(s) passed to {@link #protect(int)} — + * to a {@code Network} using APIs such as {@link Network#bindSocket} or {@link + * Network#bindDatagramSocket}. The VPN should call this method every time the set of {@code + * Network}s it is using changes. + * + * {@code networks} is one of the following: + * <ul> + * <li><strong>a non-empty array</strong>: an array of one or more {@link Network}s, in + * decreasing preference order. For example, if this VPN uses both wifi and mobile (cellular) + * networks to carry app traffic, but prefers or uses wifi more than mobile, wifi should appear + * first in the array.</li> + * <li><strong>an empty array</strong>: a zero-element array, meaning that the VPN has no + * underlying network connection, and thus, app traffic will not be sent or received.</li> + * <li><strong>null</strong>: (default) signifies that the VPN uses whatever is the system's + * default network. I.e., it doesn't use the {@code bindSocket} or {@code bindDatagramSocket} + * APIs mentioned above to send traffic over specific channels. + * </ul> + * + * This call will succeed only if the VPN is currently established. For setting this value when + * the VPN has not yet been established, see {@link Builder#setUnderlyingNetworks}. + * + * @param networks An array of networks the VPN uses to tunnel traffic to/from its servers. + * + * @return {@code true} on success. + */ + public boolean setUnderlyingNetworks(Network[] networks) { + try { + return getService().setUnderlyingNetworksForVpn(networks); + } catch (RemoteException e) { + throw new IllegalStateException(e); + } + } + + /** * Return the communication interface to the service. This method returns * {@code null} on {@link Intent}s other than {@link #SERVICE_INTERFACE} * action. Applications overriding this method must identify the intent @@ -663,6 +704,20 @@ public class VpnService extends Service { } /** + * Sets the underlying networks used by the VPN for its upstream connections. + * + * @see VpnService#setUnderlyingNetworks + * + * @param networks An array of networks the VPN uses to tunnel traffic to/from its servers. + * + * @return this {@link Builder} object to facilitate chaining method calls. + */ + public Builder setUnderlyingNetworks(Network[] networks) { + mConfig.underlyingNetworks = networks != null ? networks.clone() : null; + return this; + } + + /** * Create a VPN interface using the parameters supplied to this * builder. The interface works on IP packets, and a file descriptor * is returned for the application to access them. Each read diff --git a/core/java/android/os/PowerManagerInternal.java b/core/java/android/os/PowerManagerInternal.java index 9d78360..6f31768 100644 --- a/core/java/android/os/PowerManagerInternal.java +++ b/core/java/android/os/PowerManagerInternal.java @@ -25,6 +25,58 @@ import android.view.Display; */ public abstract class PowerManagerInternal { /** + * Wakefulness: The device is asleep. It can only be awoken by a call to wakeUp(). + * The screen should be off or in the process of being turned off by the display controller. + * The device typically passes through the dozing state first. + */ + public static final int WAKEFULNESS_ASLEEP = 0; + + /** + * Wakefulness: The device is fully awake. It can be put to sleep by a call to goToSleep(). + * When the user activity timeout expires, the device may start dreaming or go to sleep. + */ + public static final int WAKEFULNESS_AWAKE = 1; + + /** + * Wakefulness: The device is dreaming. It can be awoken by a call to wakeUp(), + * which ends the dream. The device goes to sleep when goToSleep() is called, when + * the dream ends or when unplugged. + * User activity may brighten the screen but does not end the dream. + */ + public static final int WAKEFULNESS_DREAMING = 2; + + /** + * Wakefulness: The device is dozing. It is almost asleep but is allowing a special + * low-power "doze" dream to run which keeps the display on but lets the application + * processor be suspended. It can be awoken by a call to wakeUp() which ends the dream. + * The device fully goes to sleep if the dream cannot be started or ends on its own. + */ + public static final int WAKEFULNESS_DOZING = 3; + + public static String wakefulnessToString(int wakefulness) { + switch (wakefulness) { + case WAKEFULNESS_ASLEEP: + return "Asleep"; + case WAKEFULNESS_AWAKE: + return "Awake"; + case WAKEFULNESS_DREAMING: + return "Dreaming"; + case WAKEFULNESS_DOZING: + return "Dozing"; + default: + return Integer.toString(wakefulness); + } + } + + /** + * Returns true if the wakefulness state represents an interactive state + * as defined by {@link android.os.PowerManager#isInteractive}. + */ + public static boolean isInteractive(int wakefulness) { + return wakefulness == WAKEFULNESS_AWAKE || wakefulness == WAKEFULNESS_DREAMING; + } + + /** * Used by the window manager to override the screen brightness based on the * current foreground activity. * diff --git a/core/java/android/provider/CallLog.java b/core/java/android/provider/CallLog.java index 3ec45e9..f023df7 100644 --- a/core/java/android/provider/CallLog.java +++ b/core/java/android/provider/CallLog.java @@ -387,7 +387,6 @@ public class CallLog { public static Uri addCall(CallerInfo ci, Context context, String number, int presentation, int callType, int features, PhoneAccountHandle accountHandle, long start, int duration, Long dataUsage) { - // FIXME using -1 as subId instead of SubscriptionManager.INVALID_SUB_ID return addCall(ci, context, number, presentation, callType, features, accountHandle, start, duration, dataUsage, false); } diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java index 36401eb..ce28d0a 100644 --- a/core/java/android/service/notification/ZenModeConfig.java +++ b/core/java/android/service/notification/ZenModeConfig.java @@ -474,13 +474,14 @@ public class ZenModeConfig implements Parcelable { return downtime; } - public static Condition toTimeCondition(Context context, int minutesFromNow) { + public static Condition toTimeCondition(Context context, int minutesFromNow, int userHandle) { final long now = System.currentTimeMillis(); final long millis = minutesFromNow == 0 ? ZERO_VALUE_MS : minutesFromNow * MINUTES_MS; - return toTimeCondition(context, now + millis, minutesFromNow, now); + return toTimeCondition(context, now + millis, minutesFromNow, now, userHandle); } - public static Condition toTimeCondition(Context context, long time, int minutes, long now) { + public static Condition toTimeCondition(Context context, long time, int minutes, long now, + int userHandle) { final int num, summaryResId, line1ResId; if (minutes < 60) { // display as minutes @@ -493,7 +494,7 @@ public class ZenModeConfig implements Parcelable { summaryResId = com.android.internal.R.plurals.zen_mode_duration_hours_summary; line1ResId = com.android.internal.R.plurals.zen_mode_duration_hours; } - final String skeleton = DateFormat.is24HourFormat(context) ? "Hm" : "hma"; + final String skeleton = DateFormat.is24HourFormat(context, userHandle) ? "Hm" : "hma"; final String pattern = DateFormat.getBestDateTimePattern(Locale.getDefault(), skeleton); final CharSequence formattedTime = DateFormat.format(pattern, time); final Resources res = context.getResources(); diff --git a/core/java/android/text/format/DateFormat.java b/core/java/android/text/format/DateFormat.java index 933bcee..72bbb2b 100755 --- a/core/java/android/text/format/DateFormat.java +++ b/core/java/android/text/format/DateFormat.java @@ -17,6 +17,7 @@ package android.text.format; import android.content.Context; +import android.os.UserHandle; import android.provider.Settings; import android.text.SpannableStringBuilder; import android.text.Spanned; @@ -166,8 +167,20 @@ public class DateFormat { * @return true if 24 hour time format is selected, false otherwise. */ public static boolean is24HourFormat(Context context) { - String value = Settings.System.getString(context.getContentResolver(), - Settings.System.TIME_12_24); + return is24HourFormat(context, UserHandle.myUserId()); + } + + /** + * Returns true if user preference with the given user handle is set to 24-hour format. + * @param context the context to use for the content resolver + * @param userHandle the user handle of the user to query. + * @return true if 24 hour time format is selected, false otherwise. + * + * @hide + */ + public static boolean is24HourFormat(Context context, int userHandle) { + String value = Settings.System.getStringForUser(context.getContentResolver(), + Settings.System.TIME_12_24, userHandle); if (value == null) { Locale locale = context.getResources().getConfiguration().locale; @@ -179,7 +192,7 @@ public class DateFormat { } java.text.DateFormat natural = - java.text.DateFormat.getTimeInstance(java.text.DateFormat.LONG, locale); + java.text.DateFormat.getTimeInstance(java.text.DateFormat.LONG, locale); if (natural instanceof SimpleDateFormat) { SimpleDateFormat sdf = (SimpleDateFormat) natural; @@ -253,8 +266,19 @@ public class DateFormat { * @hide */ public static String getTimeFormatString(Context context) { + return getTimeFormatString(context, UserHandle.myUserId()); + } + + /** + * Returns a String pattern that can be used to format the time according + * to the current locale and the user's 12-/24-hour clock preference. + * @param context the application context + * @param userHandle the user handle of the user to query the format for + * @hide + */ + public static String getTimeFormatString(Context context, int userHandle) { LocaleData d = LocaleData.get(context.getResources().getConfiguration().locale); - return is24HourFormat(context) ? d.timeFormat24 : d.timeFormat12; + return is24HourFormat(context, userHandle) ? d.timeFormat24 : d.timeFormat12; } /** diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java index dbd580d..9061679 100644 --- a/core/java/android/view/GLES20Canvas.java +++ b/core/java/android/view/GLES20Canvas.java @@ -997,15 +997,4 @@ class GLES20Canvas extends HardwareCanvas { int indexOffset, int indexCount, Paint paint) { // TODO: Implement } - - @Override - public void setOverrideXfermode(PorterDuff.Mode xfermode) { - int xfermodeValue = -1; - if (xfermode != null) { - xfermodeValue = xfermode.nativeInt; - } - nSetOverrideXfermode(mRenderer, xfermodeValue); - } - - private static native void nSetOverrideXfermode(long renderer, int xfermode); } diff --git a/core/java/android/view/RenderNodeAnimator.java b/core/java/android/view/RenderNodeAnimator.java index b95f9a4..7feca30 100644 --- a/core/java/android/view/RenderNodeAnimator.java +++ b/core/java/android/view/RenderNodeAnimator.java @@ -189,9 +189,6 @@ public class RenderNodeAnimator extends Animator { } private void doStart() { - mState = STATE_RUNNING; - nStart(mNativePtr.get(), this); - // Alpha is a special snowflake that has the canonical value stored // in mTransformationInfo instead of in RenderNode, so we need to update // it with the final value here. @@ -201,7 +198,7 @@ public class RenderNodeAnimator extends Animator { mViewTarget.mTransformationInfo.mAlpha = mFinalValue; } - notifyStartListeners(); + moveToRunningState(); if (mViewTarget != null) { // Kick off a frame to start the process @@ -209,6 +206,12 @@ public class RenderNodeAnimator extends Animator { } } + private void moveToRunningState() { + mState = STATE_RUNNING; + nStart(mNativePtr.get(), this); + notifyStartListeners(); + } + private void notifyStartListeners() { final ArrayList<AnimatorListener> listeners = cloneListeners(); final int numListeners = listeners == null ? 0 : listeners.size(); @@ -222,7 +225,7 @@ public class RenderNodeAnimator extends Animator { if (mState != STATE_PREPARE && mState != STATE_FINISHED) { if (mState == STATE_DELAYED) { getHelper().removeDelayedAnimation(this); - notifyStartListeners(); + moveToRunningState(); } nEnd(mNativePtr.get()); @@ -242,7 +245,15 @@ public class RenderNodeAnimator extends Animator { @Override public void end() { if (mState != STATE_FINISHED) { + if (mState < STATE_RUNNING) { + getHelper().removeDelayedAnimation(this); + doStart(); + } nEnd(mNativePtr.get()); + if (mViewTarget != null) { + // Kick off a frame to flush the state change + mViewTarget.invalidateViewProperty(true, false); + } } } diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java index 0076abf..2e5c1e0 100644 --- a/core/java/android/view/Window.java +++ b/core/java/android/view/Window.java @@ -20,6 +20,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; import android.content.res.Configuration; +import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.PixelFormat; import android.graphics.drawable.Drawable; @@ -155,6 +156,7 @@ public abstract class Window { "android:navigation:background"; /** The default features enabled */ + @Deprecated @SuppressWarnings({"PointlessBitwiseExpression"}) protected static final int DEFAULT_FEATURES = (1 << FEATURE_OPTIONS_PANEL) | (1 << FEATURE_CONTEXT_MENU); @@ -183,8 +185,8 @@ public abstract class Window { private boolean mSetCloseOnTouchOutside = false; private int mForcedWindowFlags = 0; - private int mFeatures = DEFAULT_FEATURES; - private int mLocalFeatures = DEFAULT_FEATURES; + private int mFeatures; + private int mLocalFeatures; private boolean mHaveWindowFormat = false; private boolean mHaveDimAmount = false; @@ -442,6 +444,7 @@ public abstract class Window { public Window(Context context) { mContext = context; + mFeatures = mLocalFeatures = getDefaultFeatures(context); } /** @@ -1270,6 +1273,25 @@ public abstract class Window { } /** + * Return the feature bits set by default on a window. + * @param context The context used to access resources + */ + public static int getDefaultFeatures(Context context) { + int features = 0; + + final Resources res = context.getResources(); + if (res.getBoolean(com.android.internal.R.bool.config_defaultWindowFeatureOptionsPanel)) { + features |= 1 << FEATURE_OPTIONS_PANEL; + } + + if (res.getBoolean(com.android.internal.R.bool.config_defaultWindowFeatureContextMenu)) { + features |= 1 << FEATURE_CONTEXT_MENU; + } + + return features; + } + + /** * Query for the availability of a certain feature. * * @param feature The feature ID to check diff --git a/core/java/android/widget/GridLayout.java b/core/java/android/widget/GridLayout.java index defc26c..161ae7e 100644 --- a/core/java/android/widget/GridLayout.java +++ b/core/java/android/widget/GridLayout.java @@ -1613,7 +1613,11 @@ public class GridLayout extends ViewGroup { equivalent to the single-source shortest paths problem on a digraph, for which the O(n^2) Bellman-Ford algorithm the most commonly used general solution. */ - private void solve(Arc[] arcs, int[] locations) { + private boolean solve(Arc[] arcs, int[] locations) { + return solve(arcs, locations, true); + } + + private boolean solve(Arc[] arcs, int[] locations, boolean modifyOnError) { String axisName = horizontal ? "horizontal" : "vertical"; int N = getCount() + 1; // The number of vertices is the number of columns/rows + 1. boolean[] originalCulprits = null; @@ -1631,10 +1635,14 @@ public class GridLayout extends ViewGroup { if (originalCulprits != null) { logError(axisName, arcs, originalCulprits); } - return; + return true; } } + if (!modifyOnError) { + return false; // cannot solve with these constraints + } + boolean[] culprits = new boolean[arcs.length]; for (int i = 0; i < N; i++) { for (int j = 0, length = arcs.length; j < length; j++) { @@ -1658,6 +1666,7 @@ public class GridLayout extends ViewGroup { } } } + return true; } private void computeMargins(boolean leading) { @@ -1697,8 +1706,8 @@ public class GridLayout extends ViewGroup { return trailingMargins; } - private void solve(int[] a) { - solve(getArcs(), a); + private boolean solve(int[] a) { + return solve(getArcs(), a); } private boolean computeHasWeights() { @@ -1740,28 +1749,18 @@ public class GridLayout extends ViewGroup { return deltas; } - private void shareOutDelta() { - int totalDelta = 0; - float totalWeight = 0; + private void shareOutDelta(int totalDelta, float totalWeight) { + Arrays.fill(deltas, 0); for (int i = 0, N = getChildCount(); i < N; i++) { View c = getChildAt(i); LayoutParams lp = getLayoutParams(c); Spec spec = horizontal ? lp.columnSpec : lp.rowSpec; float weight = spec.weight; if (weight != 0) { - int delta = getMeasurement(c, horizontal) - getOriginalMeasurements()[i]; - totalDelta += delta; - totalWeight += weight; - } - } - for (int i = 0, N = getChildCount(); i < N; i++) { - LayoutParams lp = getLayoutParams(getChildAt(i)); - Spec spec = horizontal ? lp.columnSpec : lp.rowSpec; - float weight = spec.weight; - if (weight != 0) { int delta = Math.round((weight * totalDelta / totalWeight)); deltas[i] = delta; - // the two adjustments below are to counter the above rounding and avoid off-by-ones at the end + // the two adjustments below are to counter the above rounding and avoid + // off-by-ones at the end totalDelta -= delta; totalWeight -= weight; } @@ -1771,12 +1770,46 @@ public class GridLayout extends ViewGroup { private void solveAndDistributeSpace(int[] a) { Arrays.fill(getDeltas(), 0); solve(a); - shareOutDelta(); - arcsValid = false; - forwardLinksValid = false; - backwardLinksValid = false; - groupBoundsValid = false; - solve(a); + int deltaMax = parentMin.value * getChildCount() + 1; //exclusive + if (deltaMax < 2) { + return; //don't have any delta to distribute + } + int deltaMin = 0; //inclusive + + float totalWeight = calculateTotalWeight(); + + int validDelta = -1; //delta for which a solution exists + boolean validSolution = true; + // do a binary search to find the max delta that won't conflict with constraints + while(deltaMin < deltaMax) { + final int delta = (deltaMin + deltaMax) / 2; + invalidateValues(); + shareOutDelta(delta, totalWeight); + validSolution = solve(getArcs(), a, false); + if (validSolution) { + validDelta = delta; + deltaMin = delta + 1; + } else { + deltaMax = delta; + } + } + if (validDelta > 0 && !validSolution) { + // last solution was not successful but we have a successful one. Use it. + invalidateValues(); + shareOutDelta(validDelta, totalWeight); + solve(a); + } + } + + private float calculateTotalWeight() { + float totalWeight = 0f; + for (int i = 0, N = getChildCount(); i < N; i++) { + View c = getChildAt(i); + LayoutParams lp = getLayoutParams(c); + Spec spec = horizontal ? lp.columnSpec : lp.rowSpec; + totalWeight += spec.weight; + } + return totalWeight; } private void computeLocations(int[] a) { diff --git a/core/java/android/widget/TextClock.java b/core/java/android/widget/TextClock.java index 4c5c71d..a98d272 100644 --- a/core/java/android/widget/TextClock.java +++ b/core/java/android/widget/TextClock.java @@ -16,6 +16,7 @@ package android.widget; +import android.app.ActivityManager; import android.content.BroadcastReceiver; import android.content.ContentResolver; import android.content.Context; @@ -26,6 +27,7 @@ import android.database.ContentObserver; import android.net.Uri; import android.os.Handler; import android.os.SystemClock; +import android.os.UserHandle; import android.provider.Settings; import android.text.format.DateFormat; import android.util.AttributeSet; @@ -127,6 +129,8 @@ public class TextClock extends TextView { private Calendar mTime; private String mTimeZone; + private boolean mShowCurrentUserTime; + private final ContentObserver mFormatChangeObserver = new ContentObserver(new Handler()) { @Override public void onChange(boolean selfChange) { @@ -342,6 +346,22 @@ public class TextClock extends TextView { } /** + * Sets whether this clock should always track the current user and not the user of the + * current process. This is used for single instance processes like the systemUI who need + * to display time for different users. + * + * @hide + */ + public void setShowCurrentUserTime(boolean showCurrentUserTime) { + mShowCurrentUserTime = showCurrentUserTime; + + chooseFormat(); + onTimeChanged(); + unregisterObserver(); + registerObserver(); + } + + /** * Indicates whether the system is currently using the 24-hour mode. * * When the system is in 24-hour mode, this view will use the pattern @@ -360,7 +380,11 @@ public class TextClock extends TextView { * @see #getFormat24Hour() */ public boolean is24HourModeEnabled() { - return DateFormat.is24HourFormat(getContext()); + if (mShowCurrentUserTime) { + return DateFormat.is24HourFormat(getContext(), ActivityManager.getCurrentUser()); + } else { + return DateFormat.is24HourFormat(getContext()); + } } /** @@ -500,7 +524,13 @@ public class TextClock extends TextView { private void registerObserver() { final ContentResolver resolver = getContext().getContentResolver(); - resolver.registerContentObserver(Settings.System.CONTENT_URI, true, mFormatChangeObserver); + if (mShowCurrentUserTime) { + resolver.registerContentObserver(Settings.System.CONTENT_URI, true, + mFormatChangeObserver, UserHandle.USER_ALL); + } else { + resolver.registerContentObserver(Settings.System.CONTENT_URI, true, + mFormatChangeObserver); + } } private void unregisterReceiver() { diff --git a/core/java/com/android/internal/net/VpnConfig.java b/core/java/com/android/internal/net/VpnConfig.java index 3d016be..c5d9db4 100644 --- a/core/java/com/android/internal/net/VpnConfig.java +++ b/core/java/com/android/internal/net/VpnConfig.java @@ -25,6 +25,7 @@ import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.ResolveInfo; import android.content.res.Resources; import android.net.LinkAddress; +import android.net.Network; import android.net.RouteInfo; import android.os.Parcel; import android.os.Parcelable; @@ -99,6 +100,7 @@ public class VpnConfig implements Parcelable { public boolean allowBypass; public boolean allowIPv4; public boolean allowIPv6; + public Network[] underlyingNetworks; public void updateAllowedFamilies(InetAddress address) { if (address instanceof Inet4Address) { @@ -162,6 +164,7 @@ public class VpnConfig implements Parcelable { out.writeInt(allowBypass ? 1 : 0); out.writeInt(allowIPv4 ? 1 : 0); out.writeInt(allowIPv6 ? 1 : 0); + out.writeTypedArray(underlyingNetworks, flags); } public static final Parcelable.Creator<VpnConfig> CREATOR = @@ -186,6 +189,7 @@ public class VpnConfig implements Parcelable { config.allowBypass = in.readInt() != 0; config.allowIPv4 = in.readInt() != 0; config.allowIPv6 = in.readInt() != 0; + config.underlyingNetworks = in.createTypedArray(Network.CREATOR); return config; } diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java index 8d3db5b..f6c42af 100644 --- a/core/java/com/android/internal/widget/LockPatternUtils.java +++ b/core/java/com/android/internal/widget/LockPatternUtils.java @@ -191,9 +191,6 @@ public class LockPatternUtils { return trust; } - /** - * @param contentResolver Used to look up and save settings. - */ public LockPatternUtils(Context context) { mContext = context; mContentResolver = context.getContentResolver(); @@ -490,17 +487,23 @@ public class LockPatternUtils { return activePasswordQuality; } + public void clearLock(boolean isFallback) { + clearLock(isFallback, getCurrentOrCallingUserId()); + } + /** * Clear any lock pattern or password. */ - public void clearLock(boolean isFallback) { - if(!isFallback) deleteGallery(); - saveLockPassword(null, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING); - setLockPatternEnabled(false); - saveLockPattern(null); - setLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED); - setLong(PASSWORD_TYPE_ALTERNATE_KEY, DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED); - onAfterChangingPassword(); + public void clearLock(boolean isFallback, int userHandle) { + if(!isFallback) deleteGallery(userHandle); + saveLockPassword(null, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, isFallback, + userHandle); + setLockPatternEnabled(false, userHandle); + saveLockPattern(null, isFallback, userHandle); + setLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, userHandle); + setLong(PASSWORD_TYPE_ALTERNATE_KEY, DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, + userHandle); + onAfterChangingPassword(userHandle); } /** @@ -547,11 +550,11 @@ public class LockPatternUtils { /** * Calls back SetupFaceLock to delete the gallery file when the lock type is changed */ - void deleteGallery() { - if(usingBiometricWeak()) { + void deleteGallery(int userId) { + if(usingBiometricWeak(userId)) { Intent intent = new Intent().setAction("com.android.facelock.DELETE_GALLERY"); intent.putExtra("deleteGallery", true); - mContext.sendBroadcast(intent); + mContext.sendBroadcastAsUser(intent, new UserHandle(userId)); } } @@ -566,11 +569,20 @@ public class LockPatternUtils { /** * Save a lock pattern. * @param pattern The new pattern to save. - * @param isFallback Specifies if this is a fallback to biometric weak */ public void saveLockPattern(List<LockPatternView.Cell> pattern, boolean isFallback) { + this.saveLockPattern(pattern, isFallback, getCurrentOrCallingUserId()); + } + + /** + * Save a lock pattern. + * @param pattern The new pattern to save. + * @param isFallback Specifies if this is a fallback to biometric weak + * @param userId the user whose pattern is to be saved. + */ + public void saveLockPattern(List<LockPatternView.Cell> pattern, boolean isFallback, + int userId) { try { - int userId = getCurrentOrCallingUserId(); getLockSettings().setLockPattern(patternToString(pattern), userId); DevicePolicyManager dpm = getDevicePolicyManager(); if (pattern != null) { @@ -586,17 +598,17 @@ public class LockPatternUtils { } } - setBoolean(PATTERN_EVER_CHOSEN_KEY, true); + setBoolean(PATTERN_EVER_CHOSEN_KEY, true, userId); if (!isFallback) { - deleteGallery(); - setLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING); + deleteGallery(userId); + setLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, userId); dpm.setActivePasswordState(DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, pattern.size(), 0, 0, 0, 0, 0, 0, userId); } else { - setLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK); + setLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK, userId); setLong(PASSWORD_TYPE_ALTERNATE_KEY, - DevicePolicyManager.PASSWORD_QUALITY_SOMETHING); - finishBiometricWeak(); + DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, userId); + finishBiometricWeak(userId); dpm.setActivePasswordState(DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK, 0, 0, 0, 0, 0, 0, 0, userId); } @@ -604,7 +616,7 @@ public class LockPatternUtils { dpm.setActivePasswordState(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, 0, 0, 0, 0, 0, 0, 0, userId); } - onAfterChangingPassword(); + onAfterChangingPassword(userId); } catch (RemoteException re) { Log.e(TAG, "Couldn't save lock pattern " + re); } @@ -822,7 +834,7 @@ public class LockPatternUtils { } if (!isFallback) { - deleteGallery(); + deleteGallery(userHandle); setLong(PASSWORD_TYPE_KEY, Math.max(quality, computedQuality), userHandle); if (computedQuality != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) { int letters = 0; @@ -862,7 +874,7 @@ public class LockPatternUtils { userHandle); setLong(PASSWORD_TYPE_ALTERNATE_KEY, Math.max(quality, computedQuality), userHandle); - finishBiometricWeak(); + finishBiometricWeak(userHandle); dpm.setActivePasswordState(DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK, 0, 0, 0, 0, 0, 0, 0, userHandle); } @@ -870,7 +882,7 @@ public class LockPatternUtils { // password hashes have the same length for simplicity of implementation. String passwordHistory = getString(PASSWORD_HISTORY_KEY, userHandle); if (passwordHistory == null) { - passwordHistory = new String(); + passwordHistory = ""; } int passwordHistoryLength = getRequestedPasswordHistoryLength(); if (passwordHistoryLength == 0) { @@ -897,7 +909,7 @@ public class LockPatternUtils { DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, 0, 0, 0, 0, 0, 0, 0, userHandle); } - onAfterChangingPassword(); + onAfterChangingPassword(userHandle); } catch (RemoteException re) { // Cant do much Log.e(TAG, "Unable to save lock password " + re); @@ -1190,7 +1202,14 @@ public class LockPatternUtils { * Set whether the lock pattern is enabled. */ public void setLockPatternEnabled(boolean enabled) { - setBoolean(Settings.Secure.LOCK_PATTERN_ENABLED, enabled); + setLockPatternEnabled(enabled, getCurrentOrCallingUserId()); + } + + /** + * Set whether the lock pattern is enabled. + */ + public void setLockPatternEnabled(boolean enabled, int userHandle) { + setBoolean(Settings.Secure.LOCK_PATTERN_ENABLED, enabled, userHandle); } /** @@ -1584,15 +1603,15 @@ public class LockPatternUtils { return (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE); } - private void finishBiometricWeak() { - setBoolean(BIOMETRIC_WEAK_EVER_CHOSEN_KEY, true); + private void finishBiometricWeak(int userId) { + setBoolean(BIOMETRIC_WEAK_EVER_CHOSEN_KEY, true, userId); // Launch intent to show final screen, this also // moves the temporary gallery to the actual gallery Intent intent = new Intent(); intent.setClassName("com.android.facelock", "com.android.facelock.SetupEndScreen"); - mContext.startActivity(intent); + mContext.startActivityAsUser(intent, new UserHandle(userId)); } public void setPowerButtonInstantlyLocks(boolean enabled) { @@ -1686,8 +1705,8 @@ public class LockPatternUtils { getTrustManager().reportRequireCredentialEntry(userId); } - private void onAfterChangingPassword() { - getTrustManager().reportEnabledTrustAgentsChanged(getCurrentOrCallingUserId()); + private void onAfterChangingPassword(int userHandle) { + getTrustManager().reportEnabledTrustAgentsChanged(userHandle); } public boolean isCredentialRequiredToDecrypt(boolean defaultValue) { |
