summaryrefslogtreecommitdiffstats
path: root/core/java/android
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/app/Activity.java1
-rw-r--r--core/java/android/app/ActivityThread.java8
-rw-r--r--core/java/android/app/ActivityTransitionCoordinator.java2
-rw-r--r--core/java/android/app/ActivityTransitionState.java12
-rw-r--r--core/java/android/app/ContextImpl.java4
-rw-r--r--core/java/android/app/EnterTransitionCoordinator.java14
-rw-r--r--core/java/android/app/INotificationManager.aidl2
-rw-r--r--core/java/android/app/KeyguardManager.java46
-rw-r--r--core/java/android/app/LoadedApk.java7
-rw-r--r--core/java/android/content/Intent.java23
-rw-r--r--core/java/android/content/pm/PermissionInfo.java2
-rw-r--r--core/java/android/inputmethodservice/InputMethodService.java5
-rw-r--r--core/java/android/net/LinkProperties.java3
-rw-r--r--core/java/android/nfc/INfcAdapter.aidl2
-rw-r--r--core/java/android/nfc/NfcAdapter.java39
-rw-r--r--core/java/android/os/UserManager.java20
-rw-r--r--core/java/android/preference/PreferenceFragment.java5
-rw-r--r--core/java/android/service/notification/ZenModeConfig.java143
-rw-r--r--core/java/android/service/trust/TrustAgentService.java13
-rw-r--r--core/java/android/text/Layout.java35
-rw-r--r--core/java/android/text/StaticLayout.java7
-rw-r--r--core/java/android/text/style/LeadingMarginSpan.java23
-rw-r--r--core/java/android/webkit/WebViewFactory.java11
-rw-r--r--core/java/android/widget/CheckedTextView.java28
-rw-r--r--core/java/android/widget/TextView.java4
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++) {