diff options
Diffstat (limited to 'core/java/android')
25 files changed, 334 insertions, 125 deletions
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index 9bbd544..21c8b75 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -6119,6 +6119,7 @@ public class Activity extends ContextThemeWrapper * * @hide */ + @SystemApi public interface TranslucentConversionListener { /** * Callback made following {@link Activity#convertToTranslucent} once all visible Activities diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 1b82d8e..d9ea671 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -1807,9 +1807,13 @@ public final class ActivityThread { } } - public void installSystemApplicationInfo(ApplicationInfo info) { + public void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) { synchronized (this) { - getSystemContext().installSystemApplicationInfo(info); + getSystemContext().installSystemApplicationInfo(info, classLoader); + + // The code package for "android" in the system server needs + // to be the system context's package. + mPackages.put("android", new WeakReference<LoadedApk>(getSystemContext().mPackageInfo)); // give ourselves a default profiler mProfiler = new Profiler(); diff --git a/core/java/android/app/ActivityTransitionCoordinator.java b/core/java/android/app/ActivityTransitionCoordinator.java index f7c0d23..7d2f677 100644 --- a/core/java/android/app/ActivityTransitionCoordinator.java +++ b/core/java/android/app/ActivityTransitionCoordinator.java @@ -239,7 +239,7 @@ abstract class ActivityTransitionCoordinator extends ResultReceiver { return mWindow; } - protected ViewGroup getDecor() { + public ViewGroup getDecor() { return (mWindow == null) ? null : (ViewGroup) mWindow.getDecorView(); } diff --git a/core/java/android/app/ActivityTransitionState.java b/core/java/android/app/ActivityTransitionState.java index 4f3b02c..613e248 100644 --- a/core/java/android/app/ActivityTransitionState.java +++ b/core/java/android/app/ActivityTransitionState.java @@ -17,9 +17,11 @@ package android.app; import android.os.Bundle; import android.os.ResultReceiver; +import android.transition.Transition; import android.util.ArrayMap; import android.util.SparseArray; import android.view.View; +import android.view.ViewGroup; import android.view.Window; import java.lang.ref.WeakReference; @@ -245,13 +247,23 @@ class ActivityTransitionState { } else { if (!mHasExited) { mHasExited = true; + Transition enterViewsTransition = null; + ViewGroup decor = null; if (mEnterTransitionCoordinator != null) { + enterViewsTransition = mEnterTransitionCoordinator.getEnterViewsTransition(); + decor = mEnterTransitionCoordinator.getDecor(); mEnterTransitionCoordinator.cancelEnter(); mEnterTransitionCoordinator = null; + if (enterViewsTransition != null && decor != null) { + enterViewsTransition.pause(decor); + } } ExitTransitionCoordinator exitCoordinator = new ExitTransitionCoordinator(activity, mEnteringNames, null, null, true); + if (enterViewsTransition != null && decor != null) { + enterViewsTransition.resume(decor); + } exitCoordinator.startExit(activity.mResultCode, activity.mResultData); } return true; diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index 4cf8cb4..da343ac 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -2301,8 +2301,8 @@ class ContextImpl extends Context { } } - void installSystemApplicationInfo(ApplicationInfo info) { - mPackageInfo.installSystemApplicationInfo(info); + void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) { + mPackageInfo.installSystemApplicationInfo(info, classLoader); } final void scheduleFinalCleanup(String who, String what) { diff --git a/core/java/android/app/EnterTransitionCoordinator.java b/core/java/android/app/EnterTransitionCoordinator.java index 54c5bc4..75ecbd9 100644 --- a/core/java/android/app/EnterTransitionCoordinator.java +++ b/core/java/android/app/EnterTransitionCoordinator.java @@ -59,6 +59,7 @@ class EnterTransitionCoordinator extends ActivityTransitionCoordinator { private boolean mIsViewsTransitionComplete; private boolean mIsSharedElementTransitionComplete; private ArrayList<Matrix> mSharedElementParentMatrices; + private Transition mEnterViewsTransition; public EnterTransitionCoordinator(Activity activity, ResultReceiver resultReceiver, ArrayList<String> sharedElementNames, boolean isReturning) { @@ -104,6 +105,10 @@ class EnterTransitionCoordinator extends ActivityTransitionCoordinator { triggerViewsReady(mapNamedElements(accepted, localNames)); } + public Transition getEnterViewsTransition() { + return mEnterViewsTransition; + } + @Override protected void viewsReady(ArrayMap<String, View> sharedElements) { super.viewsReady(sharedElements); @@ -399,10 +404,17 @@ class EnterTransitionCoordinator extends ActivityTransitionCoordinator { viewTransitionComplete(); } else { viewsTransition.forceVisibility(View.INVISIBLE, true); - setTransitionAlpha(mTransitioningViews, 1); viewsTransition.addListener(new ContinueTransitionListener() { @Override + public void onTransitionStart(Transition transition) { + mEnterViewsTransition = transition; + setTransitionAlpha(mTransitioningViews, 1); + super.onTransitionStart(transition); + } + + @Override public void onTransitionEnd(Transition transition) { + mEnterViewsTransition = null; transition.removeListener(this); viewTransitionComplete(); super.onTransitionEnd(transition); diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl index 4b65934..e8f6818 100644 --- a/core/java/android/app/INotificationManager.aidl +++ b/core/java/android/app/INotificationManager.aidl @@ -66,7 +66,7 @@ interface INotificationManager boolean setZenModeConfig(in ZenModeConfig config); oneway void notifyConditions(String pkg, in IConditionProvider provider, in Condition[] conditions); oneway void requestZenModeConditions(in IConditionListener callback, int relevance); - oneway void setZenModeCondition(in Uri conditionId); + oneway void setZenModeCondition(in Condition condition); oneway void setAutomaticZenModeConditions(in Uri[] conditionIds); Condition[] getAutomaticZenModeConditions(); }
\ No newline at end of file diff --git a/core/java/android/app/KeyguardManager.java b/core/java/android/app/KeyguardManager.java index db91742a..50e3a10 100644 --- a/core/java/android/app/KeyguardManager.java +++ b/core/java/android/app/KeyguardManager.java @@ -16,6 +16,7 @@ package android.app; +import android.content.Intent; import android.os.Binder; import android.os.RemoteException; import android.os.IBinder; @@ -24,7 +25,7 @@ import android.view.IOnKeyguardExitResult; import android.view.WindowManagerGlobal; /** - * Class that can be used to lock and unlock the keyboard. Get an instance of this + * Class that can be used to lock and unlock the keyboard. Get an instance of this * class by calling {@link android.content.Context#getSystemService(java.lang.String)} * with argument {@link android.content.Context#KEYGUARD_SERVICE}. The * actual class to control the keyboard locking is @@ -34,6 +35,45 @@ public class KeyguardManager { private IWindowManager mWM; /** + * Intent used to prompt user for device credentials. + * @hide + */ + public static final String ACTION_CONFIRM_DEVICE_CREDENTIAL = + "android.app.action.CONFIRM_DEVICE_CREDENTIAL"; + + /** + * A CharSequence dialog title to show to the user when used with a + * {@link #ACTION_CONFIRM_DEVICE_CREDENTIAL}. + * @hide + */ + public static final String EXTRA_TITLE = "android.app.extra.TITLE"; + + /** + * A CharSequence description to show to the user when used with + * {@link #ACTION_CONFIRM_DEVICE_CREDENTIAL}. + * @hide + */ + public static final String EXTRA_DESCRIPTION = "android.app.extra.DESCRIPTION"; + + /** + * Get an intent to prompt the user to confirm credentials (pin, pattern or password) + * for the current user of the device. The caller is expected to launch this activity using + * {@link android.app.Activity#startActivityForResult(Intent, int)} and check for + * {@link android.app.Activity#RESULT_OK} if the user successfully completes the challenge. + * + * @return the intent for launching the activity or null if no password is required. + **/ + public Intent getConfirmDeviceCredentialIntent(CharSequence title, CharSequence description) { + if (!isKeyguardSecure()) return null; + Intent intent = new Intent(ACTION_CONFIRM_DEVICE_CREDENTIAL); + intent.putExtra(EXTRA_TITLE, title); + intent.putExtra(EXTRA_DESCRIPTION, description); + // For security reasons, only allow this to come from system settings. + intent.setPackage("com.android.settings"); + return intent; + } + + /** * @deprecated Use {@link android.view.WindowManager.LayoutParams#FLAG_DISMISS_KEYGUARD} * and/or {@link android.view.WindowManager.LayoutParams#FLAG_SHOW_WHEN_LOCKED} * instead; this allows you to seamlessly hide the keyguard as your application @@ -58,7 +98,7 @@ public class KeyguardManager { * * A good place to call this is from {@link android.app.Activity#onResume()} * - * Note: This call has no effect while any {@link android.app.admin.DevicePolicyManager} + * Note: This call has no effect while any {@link android.app.admin.DevicePolicyManager} * is enabled that requires a password. * * <p>This method requires the caller to hold the permission @@ -121,7 +161,7 @@ public class KeyguardManager { * permissions be requested. * * Enables you to lock or unlock the keyboard. Get an instance of this class by - * calling {@link android.content.Context#getSystemService(java.lang.String) Context.getSystemService()}. + * calling {@link android.content.Context#getSystemService(java.lang.String) Context.getSystemService()}. * This class is wrapped by {@link android.app.KeyguardManager KeyguardManager}. * @param tag A tag that informally identifies who you are (for debugging who * is disabling he keyguard). diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java index 24c2835..fcfc1c4 100644 --- a/core/java/android/app/LoadedApk.java +++ b/core/java/android/app/LoadedApk.java @@ -199,9 +199,10 @@ public final class LoadedApk { /** * Sets application info about the system package. */ - void installSystemApplicationInfo(ApplicationInfo info) { + void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) { assert info.packageName.equals("android"); mApplicationInfo = info; + mClassLoader = classLoader; } public String getPackageName() { @@ -262,10 +263,6 @@ public final class LoadedApk { if (!Objects.equals(mPackageName, ActivityThread.currentPackageName())) { final String isa = VMRuntime.getRuntime().vmInstructionSet(); try { - // TODO: We can probably do away with the isa argument since - // the AM and PM have enough information to figure this out - // themselves. If we do need it, we should match it against the - // list of devices ISAs before sending it down to installd. ActivityThread.getPackageManager().performDexOptIfNeeded(mPackageName, isa); } catch (RemoteException re) { // Ignored. diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index abe4f0a..61e105b 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -1419,21 +1419,6 @@ public class Intent implements Parcelable, Cloneable { public static final String ACTION_UNINSTALL_PACKAGE = "android.intent.action.UNINSTALL_PACKAGE"; /** - * Activity Action: Prompt the user to confirm credentials (pin, pattern or password) - * for the current user of the device. Launch this activity using - * {@link android.app.Activity#startActivityForResult(Intent, int)} and check if the - * result is {@link android.app.Activity#RESULT_OK} for a successful response to the - * challenge.<p/> - * This intent is handled by the system at a high priority and applications cannot intercept - * it.<p/> - * You can use {@link android.app.KeyguardManager#isKeyguardSecure()} to determine if the user will be - * prompted. - */ - @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) - public static final String ACTION_CONFIRM_DEVICE_CREDENTIAL = "android.intent.action.CONFIRM_DEVICE_CREDENTIAL"; - - - /** * Specify whether the package should be uninstalled for all users. * @hide because these should not be part of normal application flow. */ @@ -3192,17 +3177,11 @@ public class Intent implements Parcelable, Cloneable { /** * A CharSequence dialog title to provide to the user when used with a - * {@link #ACTION_CHOOSER} or {@link #ACTION_CONFIRM_DEVICE_CREDENTIAL}. + * {@link #ACTION_CHOOSER}. */ public static final String EXTRA_TITLE = "android.intent.extra.TITLE"; /** - * A CharSequence description to provide to the user when used with - * {@link #ACTION_CONFIRM_DEVICE_CREDENTIAL}. - */ - public static final String EXTRA_DETAILS = "android.intent.extra.DETAILS"; - - /** * A Parcelable[] of {@link Intent} or * {@link android.content.pm.LabeledIntent} objects as set with * {@link #putExtra(String, Parcelable[])} of additional activities to place diff --git a/core/java/android/content/pm/PermissionInfo.java b/core/java/android/content/pm/PermissionInfo.java index af574db..4e7da48 100644 --- a/core/java/android/content/pm/PermissionInfo.java +++ b/core/java/android/content/pm/PermissionInfo.java @@ -70,7 +70,7 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable { /** * Additional flag for {@link #protectionLevel}, corresponding - * to the <code>development</code> value of + * to the <code>appop</code> value of * {@link android.R.attr#protectionLevel}. */ public static final int PROTECTION_FLAG_APPOP = 0x40; diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java index 8423d09..ba811b7 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -640,10 +640,13 @@ public class InputMethodService extends AbstractInputMethodService { * You can call this to try to enable hardware accelerated drawing for * your IME. This must be set before {@link #onCreate}, so you * will typically call it in your constructor. It is not always possible - * to use hardware acclerated drawing in an IME (for example on low-end + * to use hardware accelerated drawing in an IME (for example on low-end * devices that do not have the resources to support this), so the call * returns true if it succeeds otherwise false if you will need to draw * in software. You must be able to handle either case. + * + * @deprecated Starting in API 21, hardware acceleration is always enabled + * on capable devices. */ public boolean enableHardwareAcceleration() { if (mWindow != null) { diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java index 47b74ab..6160bc2 100644 --- a/core/java/android/net/LinkProperties.java +++ b/core/java/android/net/LinkProperties.java @@ -17,6 +17,7 @@ package android.net; import android.annotation.NonNull; +import android.annotation.Nullable; import android.net.ProxyInfo; import android.os.Parcelable; import android.os.Parcel; @@ -124,7 +125,7 @@ public final class LinkProperties implements Parcelable { * * @return The interface name set for this link or {@code null}. */ - public String getInterfaceName() { + public @Nullable String getInterfaceName() { return mIfaceName; } diff --git a/core/java/android/nfc/INfcAdapter.aidl b/core/java/android/nfc/INfcAdapter.aidl index ee4d45e..5815fa6 100644 --- a/core/java/android/nfc/INfcAdapter.aidl +++ b/core/java/android/nfc/INfcAdapter.aidl @@ -59,5 +59,5 @@ interface INfcAdapter void registerLockscreenDispatch(INfcLockscreenDispatch lockscreenDispatch, in int[] techList); void addNfcUnlockHandler(INfcUnlockHandler unlockHandler, in int[] techList); - void removeNfcUnlockHandler(IBinder b); + void removeNfcUnlockHandler(INfcUnlockHandler unlockHandler); } diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java index dde2cf1..6bd5a32 100644 --- a/core/java/android/nfc/NfcAdapter.java +++ b/core/java/android/nfc/NfcAdapter.java @@ -311,7 +311,7 @@ public final class NfcAdapter { final NfcActivityManager mNfcActivityManager; final Context mContext; - final HashMap<NfcUnlockHandler, IBinder> mNfcUnlockHandlers; + final HashMap<NfcUnlockHandler, INfcUnlockHandler> mNfcUnlockHandlers; final Object mLock; /** @@ -542,7 +542,7 @@ public final class NfcAdapter { NfcAdapter(Context context) { mContext = context; mNfcActivityManager = new NfcActivityManager(this); - mNfcUnlockHandlers = new HashMap<NfcUnlockHandler, IBinder>(); + mNfcUnlockHandlers = new HashMap<NfcUnlockHandler, INfcUnlockHandler>(); mLock = new Object(); } @@ -1498,27 +1498,37 @@ public final class NfcAdapter { * <p /> The parameter {@code tagTechnologies} determines which Tag technologies will be polled for * at the lockscreen. Polling for less tag technologies reduces latency, and so it is * strongly recommended to only provide the Tag technologies that the handler is expected to - * receive. + * receive. There must be at least one tag technology provided, otherwise the unlock handler + * is ignored. * * @hide */ @SystemApi public boolean addNfcUnlockHandler(final NfcUnlockHandler unlockHandler, String[] tagTechnologies) { - try { - INfcUnlockHandler.Stub iHandler = new INfcUnlockHandler.Stub() { - @Override - public boolean onUnlockAttempted(Tag tag) throws RemoteException { - return unlockHandler.onUnlockAttempted(tag); - } - }; + // If there are no tag technologies, don't bother adding unlock handler + if (tagTechnologies.length == 0) { + return false; + } + try { synchronized (mLock) { if (mNfcUnlockHandlers.containsKey(unlockHandler)) { - return true; + // update the tag technologies + sService.removeNfcUnlockHandler(mNfcUnlockHandlers.get(unlockHandler)); + mNfcUnlockHandlers.remove(unlockHandler); } - sService.addNfcUnlockHandler(iHandler, Tag.getTechCodesFromStrings(tagTechnologies)); - mNfcUnlockHandlers.put(unlockHandler, iHandler.asBinder()); + + INfcUnlockHandler.Stub iHandler = new INfcUnlockHandler.Stub() { + @Override + public boolean onUnlockAttempted(Tag tag) throws RemoteException { + return unlockHandler.onUnlockAttempted(tag); + } + }; + + sService.addNfcUnlockHandler(iHandler, + Tag.getTechCodesFromStrings(tagTechnologies)); + mNfcUnlockHandlers.put(unlockHandler, iHandler); } } catch (RemoteException e) { attemptDeadServiceRecovery(e); @@ -1542,8 +1552,7 @@ public final class NfcAdapter { try { synchronized (mLock) { if (mNfcUnlockHandlers.containsKey(unlockHandler)) { - sService.removeNfcUnlockHandler(mNfcUnlockHandlers.get(unlockHandler)); - mNfcUnlockHandlers.remove(unlockHandler); + sService.removeNfcUnlockHandler(mNfcUnlockHandlers.remove(unlockHandler)); } return true; diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java index 10c955e..9d1a7bc 100644 --- a/core/java/android/os/UserManager.java +++ b/core/java/android/os/UserManager.java @@ -499,7 +499,12 @@ public class UserManager { * Sets all the user-wide restrictions for this user. * Requires the MANAGE_USERS permission. * @param restrictions the Bundle containing all the restrictions. + * @deprecated use {@link android.app.admin.DevicePolicyManager#addUserRestriction( + * android.content.ComponentName, String)} or + * {@link android.app.admin.DevicePolicyManager#clearUserRestriction( + * android.content.ComponentName, String)} instead. */ + @Deprecated public void setUserRestrictions(Bundle restrictions) { setUserRestrictions(restrictions, Process.myUserHandle()); } @@ -509,7 +514,12 @@ public class UserManager { * Requires the MANAGE_USERS permission. * @param restrictions the Bundle containing all the restrictions. * @param userHandle the UserHandle of the user for whom to set the restrictions. + * @deprecated use {@link android.app.admin.DevicePolicyManager#addUserRestriction( + * android.content.ComponentName, String)} or + * {@link android.app.admin.DevicePolicyManager#clearUserRestriction( + * android.content.ComponentName, String)} instead. */ + @Deprecated public void setUserRestrictions(Bundle restrictions, UserHandle userHandle) { try { mService.setUserRestrictions(restrictions, userHandle.getIdentifier()); @@ -523,7 +533,12 @@ public class UserManager { * Requires the MANAGE_USERS permission. * @param key the key of the restriction * @param value the value for the restriction + * @deprecated use {@link android.app.admin.DevicePolicyManager#addUserRestriction( + * android.content.ComponentName, String)} or + * {@link android.app.admin.DevicePolicyManager#clearUserRestriction( + * android.content.ComponentName, String)} instead. */ + @Deprecated public void setUserRestriction(String key, boolean value) { Bundle bundle = getUserRestrictions(); bundle.putBoolean(key, value); @@ -537,7 +552,12 @@ public class UserManager { * @param key the key of the restriction * @param value the value for the restriction * @param userHandle the user whose restriction is to be changed. + * @deprecated use {@link android.app.admin.DevicePolicyManager#addUserRestriction( + * android.content.ComponentName, String)} or + * {@link android.app.admin.DevicePolicyManager#clearUserRestriction( + * android.content.ComponentName, String)} instead. */ + @Deprecated public void setUserRestriction(String key, boolean value, UserHandle userHandle) { Bundle bundle = getUserRestrictions(userHandle); bundle.putBoolean(key, value); diff --git a/core/java/android/preference/PreferenceFragment.java b/core/java/android/preference/PreferenceFragment.java index acd7942..e95e6e2 100644 --- a/core/java/android/preference/PreferenceFragment.java +++ b/core/java/android/preference/PreferenceFragment.java @@ -258,6 +258,7 @@ public abstract class PreferenceFragment extends Fragment implements */ public void setPreferenceScreen(PreferenceScreen preferenceScreen) { if (mPreferenceManager.setPreferences(preferenceScreen) && preferenceScreen != null) { + onUnbindPreferences(); mHavePrefs = true; if (mInitDone) { postBindPreferences(); @@ -350,6 +351,10 @@ public abstract class PreferenceFragment extends Fragment implements } /** @hide */ + protected void onUnbindPreferences() { + } + + /** @hide */ public ListView getListView() { ensureList(); return mList; diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java index cc09653..872f911 100644 --- a/core/java/android/service/notification/ZenModeConfig.java +++ b/core/java/android/service/notification/ZenModeConfig.java @@ -73,9 +73,14 @@ public class ZenModeConfig implements Parcelable { private static final String CONDITION_TAG = "condition"; private static final String CONDITION_ATT_COMPONENT = "component"; private static final String CONDITION_ATT_ID = "id"; + private static final String CONDITION_ATT_SUMMARY = "summary"; + private static final String CONDITION_ATT_LINE1 = "line1"; + private static final String CONDITION_ATT_LINE2 = "line2"; + private static final String CONDITION_ATT_ICON = "icon"; + private static final String CONDITION_ATT_STATE = "state"; + private static final String CONDITION_ATT_FLAGS = "flags"; private static final String EXIT_CONDITION_TAG = "exitCondition"; - private static final String EXIT_CONDITION_ATT_ID = "id"; private static final String EXIT_CONDITION_ATT_COMPONENT = "component"; public boolean allowCalls; @@ -83,13 +88,13 @@ public class ZenModeConfig implements Parcelable { public int allowFrom = SOURCE_ANYONE; public String sleepMode; - public int sleepStartHour; - public int sleepStartMinute; + public int sleepStartHour; // 0-23 + public int sleepStartMinute; // 0-59 public int sleepEndHour; public int sleepEndMinute; public ComponentName[] conditionComponents; public Uri[] conditionIds; - public Uri exitConditionId; + public Condition exitCondition; public ComponentName exitConditionComponent; public ZenModeConfig() { } @@ -115,7 +120,7 @@ public class ZenModeConfig implements Parcelable { source.readTypedArray(conditionIds, Uri.CREATOR); } allowFrom = source.readInt(); - exitConditionId = source.readParcelable(null); + exitCondition = source.readParcelable(null); exitConditionComponent = source.readParcelable(null); } @@ -146,7 +151,7 @@ public class ZenModeConfig implements Parcelable { dest.writeInt(0); } dest.writeInt(allowFrom); - dest.writeParcelable(exitConditionId, 0); + dest.writeParcelable(exitCondition, 0); dest.writeParcelable(exitConditionComponent, 0); } @@ -163,7 +168,7 @@ public class ZenModeConfig implements Parcelable { .append(conditionComponents == null ? null : TextUtils.join(",", conditionComponents)) .append(",conditionIds=") .append(conditionIds == null ? null : TextUtils.join(",", conditionIds)) - .append(",exitConditionId=").append(exitConditionId) + .append(",exitCondition=").append(exitCondition) .append(",exitConditionComponent=").append(exitConditionComponent) .append(']').toString(); } @@ -196,7 +201,7 @@ public class ZenModeConfig implements Parcelable { && other.sleepEndMinute == sleepEndMinute && Objects.deepEquals(other.conditionComponents, conditionComponents) && Objects.deepEquals(other.conditionIds, conditionIds) - && Objects.equals(other.exitConditionId, exitConditionId) + && Objects.equals(other.exitCondition, exitCondition) && Objects.equals(other.exitConditionComponent, exitConditionComponent); } @@ -205,7 +210,7 @@ public class ZenModeConfig implements Parcelable { return Objects.hash(allowCalls, allowMessages, allowFrom, sleepMode, sleepStartHour, sleepStartMinute, sleepEndHour, sleepEndMinute, Arrays.hashCode(conditionComponents), Arrays.hashCode(conditionIds), - exitConditionId, exitConditionComponent); + exitCondition, exitConditionComponent); } public boolean isValid() { @@ -294,9 +299,11 @@ public class ZenModeConfig implements Parcelable { conditionIds.add(conditionId); } } else if (EXIT_CONDITION_TAG.equals(tag)) { - rt.exitConditionId = safeUri(parser, EXIT_CONDITION_ATT_ID); - rt.exitConditionComponent = - safeComponentName(parser, EXIT_CONDITION_ATT_COMPONENT); + rt.exitCondition = readConditionXml(parser); + if (rt.exitCondition != null) { + rt.exitConditionComponent = + safeComponentName(parser, EXIT_CONDITION_ATT_COMPONENT); + } } } } @@ -333,16 +340,42 @@ public class ZenModeConfig implements Parcelable { out.endTag(null, CONDITION_TAG); } } - if (exitConditionId != null && exitConditionComponent != null) { + if (exitCondition != null && exitConditionComponent != null) { out.startTag(null, EXIT_CONDITION_TAG); - out.attribute(null, EXIT_CONDITION_ATT_ID, exitConditionId.toString()); out.attribute(null, EXIT_CONDITION_ATT_COMPONENT, exitConditionComponent.flattenToString()); + writeConditionXml(exitCondition, out); out.endTag(null, EXIT_CONDITION_TAG); } out.endTag(null, ZEN_TAG); } + public static Condition readConditionXml(XmlPullParser parser) { + final Uri id = safeUri(parser, CONDITION_ATT_ID); + final String summary = parser.getAttributeValue(null, CONDITION_ATT_SUMMARY); + final String line1 = parser.getAttributeValue(null, CONDITION_ATT_LINE1); + final String line2 = parser.getAttributeValue(null, CONDITION_ATT_LINE2); + final int icon = safeInt(parser, CONDITION_ATT_ICON, -1); + final int state = safeInt(parser, CONDITION_ATT_STATE, -1); + final int flags = safeInt(parser, CONDITION_ATT_FLAGS, -1); + try { + return new Condition(id, summary, line1, line2, icon, state, flags); + } catch (IllegalArgumentException e) { + Slog.w(TAG, "Unable to read condition xml", e); + return null; + } + } + + public static void writeConditionXml(Condition c, XmlSerializer out) throws IOException { + out.attribute(null, CONDITION_ATT_ID, c.id.toString()); + out.attribute(null, CONDITION_ATT_SUMMARY, c.summary); + out.attribute(null, CONDITION_ATT_LINE1, c.line1); + out.attribute(null, CONDITION_ATT_LINE2, c.line2); + out.attribute(null, CONDITION_ATT_ICON, Integer.toString(c.icon)); + out.attribute(null, CONDITION_ATT_STATE, Integer.toString(c.state)); + out.attribute(null, CONDITION_ATT_FLAGS, Integer.toString(c.flags)); + } + public static boolean isValidHour(int val) { return val >= 0 && val < 24; } @@ -403,21 +436,31 @@ public class ZenModeConfig implements Parcelable { } }; - // Built-in countdown conditions, e.g. condition://android/countdown/1399917958951 + public DowntimeInfo toDowntimeInfo() { + final DowntimeInfo downtime = new DowntimeInfo(); + downtime.startHour = sleepStartHour; + downtime.startMinute = sleepStartMinute; + downtime.endHour = sleepEndHour; + downtime.endMinute = sleepEndMinute; + return downtime; + } + + // For built-in conditions + private static final String SYSTEM_AUTHORITY = "android"; - private static final String COUNTDOWN_AUTHORITY = "android"; + // Built-in countdown conditions, e.g. condition://android/countdown/1399917958951 private static final String COUNTDOWN_PATH = "countdown"; public static Uri toCountdownConditionId(long time) { return new Uri.Builder().scheme(Condition.SCHEME) - .authority(COUNTDOWN_AUTHORITY) + .authority(SYSTEM_AUTHORITY) .appendPath(COUNTDOWN_PATH) .appendPath(Long.toString(time)) .build(); } public static long tryParseCountdownConditionId(Uri conditionId) { - if (!Condition.isValidId(conditionId, COUNTDOWN_AUTHORITY)) return 0; + if (!Condition.isValidId(conditionId, SYSTEM_AUTHORITY)) return 0; if (conditionId.getPathSegments().size() != 2 || !COUNTDOWN_PATH.equals(conditionId.getPathSegments().get(0))) return 0; try { @@ -431,4 +474,68 @@ public class ZenModeConfig implements Parcelable { public static boolean isValidCountdownConditionId(Uri conditionId) { return tryParseCountdownConditionId(conditionId) != 0; } + + // Built-in downtime conditions, e.g. condition://android/downtime?start=10.00&end=7.00 + private static final String DOWNTIME_PATH = "downtime"; + + public static Uri toDowntimeConditionId(DowntimeInfo downtime) { + return new Uri.Builder().scheme(Condition.SCHEME) + .authority(SYSTEM_AUTHORITY) + .appendPath(DOWNTIME_PATH) + .appendQueryParameter("start", downtime.startHour + "." + downtime.startMinute) + .appendQueryParameter("end", downtime.endHour + "." + downtime.endMinute) + .build(); + } + + public static DowntimeInfo tryParseDowntimeConditionId(Uri conditionId) { + if (!Condition.isValidId(conditionId, SYSTEM_AUTHORITY) + || conditionId.getPathSegments().size() != 1 + || !DOWNTIME_PATH.equals(conditionId.getPathSegments().get(0))) { + return null; + } + final int[] start = tryParseHourAndMinute(conditionId.getQueryParameter("start")); + final int[] end = tryParseHourAndMinute(conditionId.getQueryParameter("end")); + if (start == null || end == null) return null; + final DowntimeInfo downtime = new DowntimeInfo(); + downtime.startHour = start[0]; + downtime.startMinute = start[1]; + downtime.endHour = end[0]; + downtime.endMinute = end[1]; + return downtime; + } + + private static int[] tryParseHourAndMinute(String value) { + if (TextUtils.isEmpty(value)) return null; + final int i = value.indexOf('.'); + if (i < 1 || i >= value.length() - 1) return null; + final int hour = tryParseInt(value.substring(0, i), -1); + final int minute = tryParseInt(value.substring(i + 1), -1); + return isValidHour(hour) && isValidMinute(minute) ? new int[] { hour, minute } : null; + } + + public static boolean isValidDowntimeConditionId(Uri conditionId) { + return tryParseDowntimeConditionId(conditionId) != null; + } + + public static class DowntimeInfo { + public int startHour; // 0-23 + public int startMinute; // 0-59 + public int endHour; + public int endMinute; + + @Override + public int hashCode() { + return 0; + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof DowntimeInfo)) return false; + final DowntimeInfo other = (DowntimeInfo) o; + return startHour == other.startHour + && startMinute == other.startMinute + && endHour == other.endHour + && endMinute == other.endMinute; + } + } } diff --git a/core/java/android/service/trust/TrustAgentService.java b/core/java/android/service/trust/TrustAgentService.java index 51f07ec..5fe9194 100644 --- a/core/java/android/service/trust/TrustAgentService.java +++ b/core/java/android/service/trust/TrustAgentService.java @@ -69,12 +69,6 @@ public class TrustAgentService extends Service { "[" + getClass().getSimpleName() + "]"; private static final boolean DEBUG = false; - // Temporary workaround to allow current trust agent implementations to continue working. - // This and the code guarded by this should be removed before shipping. - // If true, calls setManagingTrust(true) after onCreate, if it wasn't already set. - // TODO: Remove this once all agents are updated. - private static final boolean SET_MANAGED_FOR_LEGACY_AGENTS = true; - /** * The {@link Intent} that must be declared as handled by the service. */ @@ -130,11 +124,6 @@ public class TrustAgentService extends Service { @Override public void onCreate() { - // TODO: Remove this once all agents are updated. - if (SET_MANAGED_FOR_LEGACY_AGENTS) { - setManagingTrust(true); - } - super.onCreate(); ComponentName component = new ComponentName(this, getClass()); try { @@ -175,7 +164,7 @@ public class TrustAgentService extends Service { * set. * * @param options Option feature bundle. - * @return true if the {@link #TrustAgentService()} supports this feature. + * @return true if the {@link TrustAgentService} supports this feature. */ public boolean onSetTrustAgentFeaturesEnabled(Bundle options) { return false; diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java index a36f06c..7dce348 100644 --- a/core/java/android/text/Layout.java +++ b/core/java/android/text/Layout.java @@ -273,16 +273,22 @@ public abstract class Layout { // Draw all leading margin spans. Adjust left or right according // to the paragraph direction of the line. final int length = spans.length; + boolean useFirstLineMargin = isFirstParaLine; + for (int n = 0; n < length; n++) { + if (spans[n] instanceof LeadingMarginSpan2) { + int count = ((LeadingMarginSpan2) spans[n]).getLeadingMarginLineCount(); + int startLine = getLineForOffset(sp.getSpanStart(spans[n])); + // if there is more than one LeadingMarginSpan2, use + // the count that is greatest + if (i < startLine + count) { + useFirstLineMargin = true; + break; + } + } + } for (int n = 0; n < length; n++) { if (spans[n] instanceof LeadingMarginSpan) { LeadingMarginSpan margin = (LeadingMarginSpan) spans[n]; - boolean useFirstLineMargin = isFirstParaLine; - if (margin instanceof LeadingMarginSpan2) { - int count = ((LeadingMarginSpan2) margin).getLeadingMarginLineCount(); - int startLine = getLineForOffset(sp.getSpanStart(margin)); - useFirstLineMargin = i < startLine + count; - } - if (dir == DIR_RIGHT_TO_LEFT) { margin.drawLeadingMargin(canvas, paint, right, dir, ltop, lbaseline, lbottom, buf, @@ -1535,15 +1541,18 @@ public abstract class Layout { boolean isFirstParaLine = lineStart == 0 || spanned.charAt(lineStart - 1) == '\n'; + boolean useFirstLineMargin = isFirstParaLine; for (int i = 0; i < spans.length; i++) { - LeadingMarginSpan span = spans[i]; - boolean useFirstLineMargin = isFirstParaLine; - if (span instanceof LeadingMarginSpan2) { - int spStart = spanned.getSpanStart(span); + if (spans[i] instanceof LeadingMarginSpan2) { + int spStart = spanned.getSpanStart(spans[i]); int spanLine = getLineForOffset(spStart); - int count = ((LeadingMarginSpan2)span).getLeadingMarginLineCount(); - useFirstLineMargin = line < spanLine + count; + int count = ((LeadingMarginSpan2) spans[i]).getLeadingMarginLineCount(); + // if there is more than one LeadingMarginSpan2, use the count that is greatest + useFirstLineMargin |= line < spanLine + count; } + } + for (int i = 0; i < spans.length; i++) { + LeadingMarginSpan span = spans[i]; margin += span.getLeadingMargin(useFirstLineMargin); } diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java index 4144a75..aecf488 100644 --- a/core/java/android/text/StaticLayout.java +++ b/core/java/android/text/StaticLayout.java @@ -201,13 +201,12 @@ public class StaticLayout extends Layout { restWidth -= sp[i].getLeadingMargin(false); // LeadingMarginSpan2 is odd. The count affects all - // leading margin spans, not just this particular one, - // and start from the top of the span, not the top of the - // paragraph. + // leading margin spans, not just this particular one if (lms instanceof LeadingMarginSpan2) { LeadingMarginSpan2 lms2 = (LeadingMarginSpan2) lms; int lmsFirstLine = getLineForOffset(spanned.getSpanStart(lms2)); - firstWidthLineLimit = lmsFirstLine + lms2.getLeadingMarginLineCount(); + firstWidthLineLimit = Math.max(firstWidthLineLimit, + lmsFirstLine + lms2.getLeadingMarginLineCount()); } } diff --git a/core/java/android/text/style/LeadingMarginSpan.java b/core/java/android/text/style/LeadingMarginSpan.java index 2f429ff..96a7cd9 100644 --- a/core/java/android/text/style/LeadingMarginSpan.java +++ b/core/java/android/text/style/LeadingMarginSpan.java @@ -28,6 +28,9 @@ import android.text.TextUtils; * margin spans on a single paragraph; they will be rendered in order, each * adding its margin to the ones before it. The leading margin is on the right * for lines in a right-to-left paragraph. + * <p> + * LeadingMarginSpans should be attached from the first character to the last + * character of a single paragraph. */ public interface LeadingMarginSpan extends ParagraphStyle @@ -69,18 +72,22 @@ extends ParagraphStyle /** - * An extended version of {@link LeadingMarginSpan}, which allows - * the implementor to specify the number of lines of text to which - * this object is attached that the "first line of paragraph" margin - * width will be applied to. + * An extended version of {@link LeadingMarginSpan}, which allows the + * implementor to specify the number of lines of the paragraph to which + * this object is attached that the "first line of paragraph" margin width + * will be applied to. + * <p> + * There should only be one LeadingMarginSpan2 per paragraph. The leading + * margin line count affects all LeadingMarginSpans in the paragraph, + * adjusting the number of lines to which the first line margin is applied. + * <p> + * As with LeadingMarginSpans, LeadingMarginSpan2s should be attached from + * the beginning to the end of a paragraph. */ public interface LeadingMarginSpan2 extends LeadingMarginSpan, WrapTogetherSpan { /** - * Returns the number of lines of text to which this object is + * Returns the number of lines of the paragraph to which this object is * attached that the "first line" margin will apply to. - * Note that if this returns N, the first N lines of the region, - * not the first N lines of each paragraph, will be given the - * special margin width. */ public int getLeadingMarginLineCount(); }; diff --git a/core/java/android/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java index ec589a5..c7ffedc 100644 --- a/core/java/android/webkit/WebViewFactory.java +++ b/core/java/android/webkit/WebViewFactory.java @@ -72,12 +72,17 @@ public final class WebViewFactory { private static WebViewFactoryProvider sProviderInstance; private static final Object sProviderLock = new Object(); private static boolean sAddressSpaceReserved = false; + private static PackageInfo sPackageInfo; public static String getWebViewPackageName() { return AppGlobals.getInitialApplication().getString( com.android.internal.R.string.config_webViewPackageName); } + public static PackageInfo getLoadedPackageInfo() { + return sPackageInfo; + } + static WebViewFactoryProvider getProvider() { synchronized (sProviderLock) { // For now the main purpose of this function (and the factory abstraction) is to keep @@ -125,9 +130,9 @@ public final class WebViewFactory { try { // First fetch the package info so we can log the webview package version. String packageName = getWebViewPackageName(); - PackageInfo pi = initialApplication.getPackageManager().getPackageInfo(packageName, 0); - Log.i(LOGTAG, "Loading " + packageName + " version " + pi.versionName + - " (code " + pi.versionCode + ")"); + sPackageInfo = initialApplication.getPackageManager().getPackageInfo(packageName, 0); + Log.i(LOGTAG, "Loading " + packageName + " version " + sPackageInfo.versionName + + " (code " + sPackageInfo.versionCode + ")"); // Construct a package context to load the Java code into the current app. Context webViewContext = initialApplication.createPackageContext(packageName, diff --git a/core/java/android/widget/CheckedTextView.java b/core/java/android/widget/CheckedTextView.java index ccd0480..29a6a7d 100644 --- a/core/java/android/widget/CheckedTextView.java +++ b/core/java/android/widget/CheckedTextView.java @@ -53,6 +53,8 @@ public class CheckedTextView extends TextView implements Checkable { private int mBasePadding; private int mCheckMarkWidth; + private int mCheckMarkGravity = Gravity.END; + private boolean mNeedRequestlayout; private static final int[] CHECKED_STATE_SET = { @@ -83,15 +85,17 @@ public class CheckedTextView extends TextView implements Checkable { } mCheckMarkTintMode = Drawable.parseTintMode(a.getInt( - R.styleable.CompoundButton_buttonTintMode, -1), mCheckMarkTintMode); + R.styleable.CheckedTextView_checkMarkTintMode, -1), mCheckMarkTintMode); - if (a.hasValue(R.styleable.CompoundButton_buttonTint)) { - mCheckMarkTintList = a.getColorStateList(R.styleable.CompoundButton_buttonTint); + if (a.hasValue(R.styleable.CheckedTextView_checkMarkTint)) { + mCheckMarkTintList = a.getColorStateList(R.styleable.CheckedTextView_checkMarkTint); mHasCheckMarkTint = true; applyCheckMarkTint(); } + mCheckMarkGravity = a.getInt(R.styleable.CheckedTextView_checkMarkGravity, Gravity.END); + boolean checked = a.getBoolean(R.styleable.CheckedTextView_checked, false); setChecked(checked); @@ -293,7 +297,7 @@ public class CheckedTextView extends TextView implements Checkable { @Override protected void internalSetPadding(int left, int top, int right, int bottom) { super.internalSetPadding(left, top, right, bottom); - setBasePadding(isLayoutRtl()); + setBasePadding(isCheckMarkAtStart()); } @Override @@ -306,7 +310,7 @@ public class CheckedTextView extends TextView implements Checkable { resetPaddingToInitialValues(); int newPadding = (mCheckMarkDrawable != null) ? mCheckMarkWidth + mBasePadding : mBasePadding; - if (isLayoutRtl()) { + if (isCheckMarkAtStart()) { mNeedRequestlayout |= (mPaddingLeft != newPadding); mPaddingLeft = newPadding; } else { @@ -319,14 +323,20 @@ public class CheckedTextView extends TextView implements Checkable { } } - private void setBasePadding(boolean isLayoutRtl) { - if (isLayoutRtl) { + private void setBasePadding(boolean checkmarkAtStart) { + if (checkmarkAtStart) { mBasePadding = mPaddingLeft; } else { mBasePadding = mPaddingRight; } } + private boolean isCheckMarkAtStart() { + final int gravity = Gravity.getAbsoluteGravity(mCheckMarkGravity, getLayoutDirection()); + final int hgrav = gravity & Gravity.HORIZONTAL_GRAVITY_MASK; + return hgrav == Gravity.LEFT; + } + @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); @@ -347,13 +357,13 @@ public class CheckedTextView extends TextView implements Checkable { break; } - final boolean isLayoutRtl = isLayoutRtl(); + final boolean checkMarkAtStart = isCheckMarkAtStart(); final int width = getWidth(); final int top = y; final int bottom = top + height; final int left; final int right; - if (isLayoutRtl) { + if (checkMarkAtStart) { left = mBasePadding; right = left + mCheckMarkWidth; } else { diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index a536b2d..a82fa65 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -1320,8 +1320,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener attrs, com.android.internal.R.styleable.View, defStyleAttr, defStyleRes); boolean focusable = mMovement != null || getKeyListener() != null; - boolean clickable = focusable; - boolean longClickable = focusable; + boolean clickable = focusable || isClickable(); + boolean longClickable = focusable || isLongClickable(); n = a.getIndexCount(); for (int i = 0; i < n; i++) { |
