diff options
Diffstat (limited to 'core/java')
78 files changed, 1957 insertions, 1526 deletions
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java index 81ee192..b0bad07 100644 --- a/core/java/android/accessibilityservice/AccessibilityService.java +++ b/core/java/android/accessibilityservice/AccessibilityService.java @@ -323,7 +323,7 @@ public abstract class AccessibilityService extends Service { public static final int GLOBAL_ACTION_HOME = 2; /** - * Action to open the recents. + * Action to open the recent apps. */ public static final int GLOBAL_ACTION_RECENTS = 3; @@ -332,6 +332,11 @@ public abstract class AccessibilityService extends Service { */ public static final int GLOBAL_ACTION_NOTIFICATIONS = 4; + /** + * Action to open the quick settings. + */ + public static final int GLOBAL_ACTION_QUICK_SETTINGS = 5; + private static final String LOG_TAG = "AccessibilityService"; interface Callbacks { diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java index c3f57e8..9874b0b 100644 --- a/core/java/android/app/ActivityManagerNative.java +++ b/core/java/android/app/ActivityManagerNative.java @@ -1509,9 +1509,9 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM case DUMP_HEAP_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); String process = data.readString(); + int userId = data.readInt(); boolean managed = data.readInt() != 0; String path = data.readString(); - int userId = data.readInt(); ParcelFileDescriptor fd = data.readInt() != 0 ? data.readFileDescriptor() : null; boolean res = dumpHeap(process, userId, managed, path, fd); @@ -1530,8 +1530,9 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM IBinder resultTo = data.readStrongBinder(); Bundle options = data.readInt() != 0 ? Bundle.CREATOR.createFromParcel(data) : null; + int userId = data.readInt(); int result = startActivities(app, intents, resolvedTypes, resultTo, - options); + options, userId); reply.writeNoException(); reply.writeInt(result); return true; @@ -3708,7 +3709,7 @@ class ActivityManagerProxy implements IActivityManager public int startActivities(IApplicationThread caller, Intent[] intents, String[] resolvedTypes, IBinder resultTo, - Bundle options) throws RemoteException { + Bundle options, int userId) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); @@ -3722,6 +3723,7 @@ class ActivityManagerProxy implements IActivityManager } else { data.writeInt(0); } + data.writeInt(userId); mRemote.transact(START_ACTIVITIES_TRANSACTION, data, reply, 0); reply.readException(); int result = reply.readInt(); diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index aa8ef21..6638433 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -65,6 +65,7 @@ import android.os.RemoteException; import android.os.ServiceManager; import android.os.StrictMode; import android.os.SystemClock; +import android.os.SystemProperties; import android.os.Trace; import android.os.UserHandle; import android.util.AndroidRuntimeException; @@ -1739,6 +1740,11 @@ public final class ActivityThread { public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo, int flags) { + return getPackageInfo(packageName, compatInfo, flags, UserHandle.myUserId()); + } + + public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo, + int flags, int userId) { synchronized (mPackages) { WeakReference<LoadedApk> ref; if ((flags&Context.CONTEXT_INCLUDE_CODE) != 0) { @@ -1767,7 +1773,7 @@ public final class ActivityThread { ApplicationInfo ai = null; try { ai = getPackageManager().getApplicationInfo(packageName, - PackageManager.GET_SHARED_LIBRARY_FILES, UserHandle.myUserId()); + PackageManager.GET_SHARED_LIBRARY_FILES, userId); } catch (RemoteException e) { // Ignore } @@ -2114,9 +2120,7 @@ public final class ActivityThread { + ", dir=" + r.packageInfo.getAppDir()); if (activity != null) { - ContextImpl appContext = new ContextImpl(); - appContext.init(r.packageInfo, r.token, this); - appContext.setOuterContext(activity); + Context appContext = createBaseContextForActivity(r, activity); CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager()); Configuration config = new Configuration(mCompatConfiguration); if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity " @@ -2181,6 +2185,31 @@ public final class ActivityThread { return activity; } + private Context createBaseContextForActivity(ActivityClientRecord r, + final Activity activity) { + ContextImpl appContext = new ContextImpl(); + appContext.init(r.packageInfo, r.token, this); + appContext.setOuterContext(activity); + + // For debugging purposes, if the activity's package name contains the value of + // the "debug.use-second-display" system property as a substring, then show + // its content on a secondary display if there is one. + Context baseContext = appContext; + String pkgName = SystemProperties.get("debug.second-display.pkg"); + if (pkgName != null && !pkgName.isEmpty() + && r.packageInfo.mPackageName.contains(pkgName)) { + DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance(); + for (int displayId : dm.getDisplayIds()) { + if (displayId != Display.DEFAULT_DISPLAY) { + Display display = dm.getRealDisplay(displayId); + baseContext = appContext.createDisplayContext(display); + break; + } + } + } + return baseContext; + } + private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) { // If we are getting ready to gc after going to the background, well // we are back active so skip it. @@ -2682,7 +2711,7 @@ public final class ActivityThread { r.activity.performResume(); EventLog.writeEvent(LOG_ON_RESUME_CALLED, - r.activity.getComponentName().getClassName()); + UserHandle.myUserId(), r.activity.getComponentName().getClassName()); r.paused = false; r.stopped = false; @@ -2950,7 +2979,8 @@ public final class ActivityThread { // Now we are idle. r.activity.mCalled = false; mInstrumentation.callActivityOnPause(r.activity); - EventLog.writeEvent(LOG_ON_PAUSE_CALLED, r.activity.getComponentName().getClassName()); + EventLog.writeEvent(LOG_ON_PAUSE_CALLED, UserHandle.myUserId(), + r.activity.getComponentName().getClassName()); if (!r.activity.mCalled) { throw new SuperNotCalledException( "Activity " + r.intent.getComponent().toShortString() + @@ -3335,7 +3365,7 @@ public final class ActivityThread { try { r.activity.mCalled = false; mInstrumentation.callActivityOnPause(r.activity); - EventLog.writeEvent(LOG_ON_PAUSE_CALLED, + EventLog.writeEvent(LOG_ON_PAUSE_CALLED, UserHandle.myUserId(), r.activity.getComponentName().getClassName()); if (!r.activity.mCalled) { throw new SuperNotCalledException( diff --git a/core/java/android/app/ApplicationErrorReport.java b/core/java/android/app/ApplicationErrorReport.java index ebf4261..954476d 100644 --- a/core/java/android/app/ApplicationErrorReport.java +++ b/core/java/android/app/ApplicationErrorReport.java @@ -158,8 +158,8 @@ public class ApplicationErrorReport implements Parcelable { public static ComponentName getErrorReportReceiver(Context context, String packageName, int appFlags) { // check if error reporting is enabled in secure settings - int enabled = Settings.Secure.getInt(context.getContentResolver(), - Settings.Secure.SEND_ACTION_APP_ERROR, 0); + int enabled = Settings.Global.getInt(context.getContentResolver(), + Settings.Global.SEND_ACTION_APP_ERROR, 0); if (enabled == 0) { return null; } diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java index 18503f6..7431765 100644 --- a/core/java/android/app/ApplicationPackageManager.java +++ b/core/java/android/app/ApplicationPackageManager.java @@ -50,7 +50,6 @@ import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Process; import android.os.RemoteException; -import android.os.UserHandle; import android.util.Log; import android.view.Display; @@ -70,7 +69,7 @@ final class ApplicationPackageManager extends PackageManager { public PackageInfo getPackageInfo(String packageName, int flags) throws NameNotFoundException { try { - PackageInfo pi = mPM.getPackageInfo(packageName, flags, UserHandle.myUserId()); + PackageInfo pi = mPM.getPackageInfo(packageName, flags, mContext.getUserId()); if (pi != null) { return pi; } @@ -200,7 +199,7 @@ final class ApplicationPackageManager extends PackageManager { public ApplicationInfo getApplicationInfo(String packageName, int flags) throws NameNotFoundException { try { - ApplicationInfo ai = mPM.getApplicationInfo(packageName, flags, UserHandle.myUserId()); + ApplicationInfo ai = mPM.getApplicationInfo(packageName, flags, mContext.getUserId()); if (ai != null) { return ai; } @@ -215,7 +214,7 @@ final class ApplicationPackageManager extends PackageManager { public ActivityInfo getActivityInfo(ComponentName className, int flags) throws NameNotFoundException { try { - ActivityInfo ai = mPM.getActivityInfo(className, flags, UserHandle.myUserId()); + ActivityInfo ai = mPM.getActivityInfo(className, flags, mContext.getUserId()); if (ai != null) { return ai; } @@ -230,7 +229,7 @@ final class ApplicationPackageManager extends PackageManager { public ActivityInfo getReceiverInfo(ComponentName className, int flags) throws NameNotFoundException { try { - ActivityInfo ai = mPM.getReceiverInfo(className, flags, UserHandle.myUserId()); + ActivityInfo ai = mPM.getReceiverInfo(className, flags, mContext.getUserId()); if (ai != null) { return ai; } @@ -245,7 +244,7 @@ final class ApplicationPackageManager extends PackageManager { public ServiceInfo getServiceInfo(ComponentName className, int flags) throws NameNotFoundException { try { - ServiceInfo si = mPM.getServiceInfo(className, flags, UserHandle.myUserId()); + ServiceInfo si = mPM.getServiceInfo(className, flags, mContext.getUserId()); if (si != null) { return si; } @@ -260,7 +259,7 @@ final class ApplicationPackageManager extends PackageManager { public ProviderInfo getProviderInfo(ComponentName className, int flags) throws NameNotFoundException { try { - ProviderInfo pi = mPM.getProviderInfo(className, flags, UserHandle.myUserId()); + ProviderInfo pi = mPM.getProviderInfo(className, flags, mContext.getUserId()); if (pi != null) { return pi; } @@ -405,7 +404,7 @@ final class ApplicationPackageManager extends PackageManager { @SuppressWarnings("unchecked") @Override public List<PackageInfo> getInstalledPackages(int flags) { - return getInstalledPackages(flags, UserHandle.myUserId()); + return getInstalledPackages(flags, mContext.getUserId()); } /** @hide */ @@ -431,7 +430,7 @@ final class ApplicationPackageManager extends PackageManager { @SuppressWarnings("unchecked") @Override public List<ApplicationInfo> getInstalledApplications(int flags) { - int userId = UserHandle.getUserId(Process.myUid()); + final int userId = mContext.getUserId(); try { final List<ApplicationInfo> applicationInfos = new ArrayList<ApplicationInfo>(); ApplicationInfo lastItem = null; @@ -451,7 +450,7 @@ final class ApplicationPackageManager extends PackageManager { @Override public ResolveInfo resolveActivity(Intent intent, int flags) { - return resolveActivityAsUser(intent, flags, UserHandle.myUserId()); + return resolveActivityAsUser(intent, flags, mContext.getUserId()); } @Override @@ -470,7 +469,7 @@ final class ApplicationPackageManager extends PackageManager { @Override public List<ResolveInfo> queryIntentActivities(Intent intent, int flags) { - return queryIntentActivitiesAsUser(intent, flags, UserHandle.myUserId()); + return queryIntentActivitiesAsUser(intent, flags, mContext.getUserId()); } /** @hide Same as above but for a specific user */ @@ -514,7 +513,7 @@ final class ApplicationPackageManager extends PackageManager { try { return mPM.queryIntentActivityOptions(caller, specifics, specificTypes, intent, intent.resolveTypeIfNeeded(resolver), - flags, UserHandle.myUserId()); + flags, mContext.getUserId()); } catch (RemoteException e) { throw new RuntimeException("Package manager has died", e); } @@ -538,7 +537,7 @@ final class ApplicationPackageManager extends PackageManager { @Override public List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags) { - return queryBroadcastReceivers(intent, flags, UserHandle.myUserId()); + return queryBroadcastReceivers(intent, flags, mContext.getUserId()); } @Override @@ -548,7 +547,7 @@ final class ApplicationPackageManager extends PackageManager { intent, intent.resolveTypeIfNeeded(mContext.getContentResolver()), flags, - UserHandle.myUserId()); + mContext.getUserId()); } catch (RemoteException e) { throw new RuntimeException("Package manager has died", e); } @@ -569,14 +568,14 @@ final class ApplicationPackageManager extends PackageManager { @Override public List<ResolveInfo> queryIntentServices(Intent intent, int flags) { - return queryIntentServicesAsUser(intent, flags, UserHandle.myUserId()); + return queryIntentServicesAsUser(intent, flags, mContext.getUserId()); } @Override public ProviderInfo resolveContentProvider(String name, int flags) { try { - return mPM.resolveContentProvider(name, flags, UserHandle.myUserId()); + return mPM.resolveContentProvider(name, flags, mContext.getUserId()); } catch (RemoteException e) { throw new RuntimeException("Package manager has died", e); } @@ -759,6 +758,28 @@ final class ApplicationPackageManager extends PackageManager { getApplicationInfo(appPackageName, 0)); } + /** @hide */ + @Override + public Resources getResourcesForApplicationAsUser(String appPackageName, int userId) + throws NameNotFoundException { + if (userId < 0) { + throw new IllegalArgumentException( + "Call does not support special user #" + userId); + } + if ("system".equals(appPackageName)) { + return mContext.mMainThread.getSystemContext().getResources(); + } + try { + ApplicationInfo ai = mPM.getApplicationInfo(appPackageName, 0, userId); + if (ai != null) { + return getResourcesForApplication(ai); + } + } catch (RemoteException e) { + throw new RuntimeException("Package manager has died", e); + } + throw new NameNotFoundException("Package " + appPackageName + " doesn't exist"); + } + int mCachedSafeMode = -1; @Override public boolean isSafeMode() { try { @@ -1103,7 +1124,7 @@ final class ApplicationPackageManager extends PackageManager { public void clearApplicationUserData(String packageName, IPackageDataObserver observer) { try { - mPM.clearApplicationUserData(packageName, observer, UserHandle.myUserId()); + mPM.clearApplicationUserData(packageName, observer, mContext.getUserId()); } catch (RemoteException e) { // Should never happen! } @@ -1176,7 +1197,7 @@ final class ApplicationPackageManager extends PackageManager { public void addPreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity) { try { - mPM.addPreferredActivity(filter, match, set, activity, UserHandle.myUserId()); + mPM.addPreferredActivity(filter, match, set, activity, mContext.getUserId()); } catch (RemoteException e) { // Should never happen! } @@ -1226,7 +1247,7 @@ final class ApplicationPackageManager extends PackageManager { public void setComponentEnabledSetting(ComponentName componentName, int newState, int flags) { try { - mPM.setComponentEnabledSetting(componentName, newState, flags, UserHandle.myUserId()); + mPM.setComponentEnabledSetting(componentName, newState, flags, mContext.getUserId()); } catch (RemoteException e) { // Should never happen! } @@ -1235,7 +1256,7 @@ final class ApplicationPackageManager extends PackageManager { @Override public int getComponentEnabledSetting(ComponentName componentName) { try { - return mPM.getComponentEnabledSetting(componentName, UserHandle.myUserId()); + return mPM.getComponentEnabledSetting(componentName, mContext.getUserId()); } catch (RemoteException e) { // Should never happen! } @@ -1246,7 +1267,7 @@ final class ApplicationPackageManager extends PackageManager { public void setApplicationEnabledSetting(String packageName, int newState, int flags) { try { - mPM.setApplicationEnabledSetting(packageName, newState, flags, UserHandle.myUserId()); + mPM.setApplicationEnabledSetting(packageName, newState, flags, mContext.getUserId()); } catch (RemoteException e) { // Should never happen! } @@ -1255,7 +1276,7 @@ final class ApplicationPackageManager extends PackageManager { @Override public int getApplicationEnabledSetting(String packageName) { try { - return mPM.getApplicationEnabledSetting(packageName, UserHandle.myUserId()); + return mPM.getApplicationEnabledSetting(packageName, mContext.getUserId()); } catch (RemoteException e) { // Should never happen! } diff --git a/core/java/android/app/BackStackRecord.java b/core/java/android/app/BackStackRecord.java index 96814b7..1b1d341 100644 --- a/core/java/android/app/BackStackRecord.java +++ b/core/java/android/app/BackStackRecord.java @@ -20,6 +20,7 @@ import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; import android.util.Log; +import android.util.LogWriter; import java.io.FileDescriptor; import java.io.PrintWriter; @@ -94,11 +95,12 @@ final class BackStackState implements Parcelable { public BackStackRecord instantiate(FragmentManagerImpl fm) { BackStackRecord bse = new BackStackRecord(fm); int pos = 0; + int num = 0; while (pos < mOps.length) { BackStackRecord.Op op = new BackStackRecord.Op(); op.cmd = mOps[pos++]; if (FragmentManagerImpl.DEBUG) Log.v(FragmentManagerImpl.TAG, - "BSE " + bse + " set base fragment #" + mOps[pos]); + "Instantiate " + bse + " op #" + num + " base fragment #" + mOps[pos]); int findex = mOps[pos++]; if (findex >= 0) { Fragment f = fm.mActive.get(findex); @@ -115,12 +117,13 @@ final class BackStackState implements Parcelable { op.removed = new ArrayList<Fragment>(N); for (int i=0; i<N; i++) { if (FragmentManagerImpl.DEBUG) Log.v(FragmentManagerImpl.TAG, - "BSE " + bse + " set remove fragment #" + mOps[pos]); + "Instantiate " + bse + " set remove fragment #" + mOps[pos]); Fragment r = fm.mActive.get(mOps[pos++]); op.removed.add(r); } } bse.addOp(op); + num++; } bse.mTransition = mTransition; bse.mTransitionStyle = mTransitionStyle; @@ -168,7 +171,7 @@ final class BackStackState implements Parcelable { */ final class BackStackRecord extends FragmentTransaction implements FragmentManager.BackStackEntry, Runnable { - static final String TAG = "BackStackEntry"; + static final String TAG = FragmentManagerImpl.TAG; final FragmentManagerImpl mManager; @@ -206,46 +209,69 @@ final class BackStackRecord extends FragmentTransaction implements boolean mAllowAddToBackStack = true; String mName; boolean mCommitted; - int mIndex; + int mIndex = -1; int mBreadCrumbTitleRes; CharSequence mBreadCrumbTitleText; int mBreadCrumbShortTitleRes; CharSequence mBreadCrumbShortTitleText; - public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) { - writer.print(prefix); writer.print("mName="); writer.print(mName); - writer.print(" mIndex="); writer.print(mIndex); - writer.print(" mCommitted="); writer.println(mCommitted); - if (mTransition != FragmentTransaction.TRANSIT_NONE) { - writer.print(prefix); writer.print("mTransition=#"); - writer.print(Integer.toHexString(mTransition)); - writer.print(" mTransitionStyle=#"); - writer.println(Integer.toHexString(mTransitionStyle)); - } - if (mEnterAnim != 0 || mExitAnim !=0) { - writer.print(prefix); writer.print("mEnterAnim=#"); - writer.print(Integer.toHexString(mEnterAnim)); - writer.print(" mExitAnim=#"); - writer.println(Integer.toHexString(mExitAnim)); - } - if (mPopEnterAnim != 0 || mPopExitAnim !=0) { - writer.print(prefix); writer.print("mPopEnterAnim=#"); - writer.print(Integer.toHexString(mPopEnterAnim)); - writer.print(" mPopExitAnim=#"); - writer.println(Integer.toHexString(mPopExitAnim)); + @Override + public String toString() { + StringBuilder sb = new StringBuilder(128); + sb.append("BackStackEntry{"); + sb.append(Integer.toHexString(System.identityHashCode(this))); + if (mIndex >= 0) { + sb.append(" #"); + sb.append(mIndex); } - if (mBreadCrumbTitleRes != 0 || mBreadCrumbTitleText != null) { - writer.print(prefix); writer.print("mBreadCrumbTitleRes=#"); - writer.print(Integer.toHexString(mBreadCrumbTitleRes)); - writer.print(" mBreadCrumbTitleText="); - writer.println(mBreadCrumbTitleText); + if (mName != null) { + sb.append(" "); + sb.append(mName); } - if (mBreadCrumbShortTitleRes != 0 || mBreadCrumbShortTitleText != null) { - writer.print(prefix); writer.print("mBreadCrumbShortTitleRes=#"); - writer.print(Integer.toHexString(mBreadCrumbShortTitleRes)); - writer.print(" mBreadCrumbShortTitleText="); - writer.println(mBreadCrumbShortTitleText); + sb.append("}"); + return sb.toString(); + } + + public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) { + dump(prefix, writer, true); + } + + void dump(String prefix, PrintWriter writer, boolean full) { + if (full) { + writer.print(prefix); writer.print("mName="); writer.print(mName); + writer.print(" mIndex="); writer.print(mIndex); + writer.print(" mCommitted="); writer.println(mCommitted); + if (mTransition != FragmentTransaction.TRANSIT_NONE) { + writer.print(prefix); writer.print("mTransition=#"); + writer.print(Integer.toHexString(mTransition)); + writer.print(" mTransitionStyle=#"); + writer.println(Integer.toHexString(mTransitionStyle)); + } + if (mEnterAnim != 0 || mExitAnim !=0) { + writer.print(prefix); writer.print("mEnterAnim=#"); + writer.print(Integer.toHexString(mEnterAnim)); + writer.print(" mExitAnim=#"); + writer.println(Integer.toHexString(mExitAnim)); + } + if (mPopEnterAnim != 0 || mPopExitAnim !=0) { + writer.print(prefix); writer.print("mPopEnterAnim=#"); + writer.print(Integer.toHexString(mPopEnterAnim)); + writer.print(" mPopExitAnim=#"); + writer.println(Integer.toHexString(mPopExitAnim)); + } + if (mBreadCrumbTitleRes != 0 || mBreadCrumbTitleText != null) { + writer.print(prefix); writer.print("mBreadCrumbTitleRes=#"); + writer.print(Integer.toHexString(mBreadCrumbTitleRes)); + writer.print(" mBreadCrumbTitleText="); + writer.println(mBreadCrumbTitleText); + } + if (mBreadCrumbShortTitleRes != 0 || mBreadCrumbShortTitleText != null) { + writer.print(prefix); writer.print("mBreadCrumbShortTitleRes=#"); + writer.print(Integer.toHexString(mBreadCrumbShortTitleRes)); + writer.print(" mBreadCrumbShortTitleText="); + writer.println(mBreadCrumbShortTitleText); + } } if (mHead != null) { @@ -254,21 +280,34 @@ final class BackStackRecord extends FragmentTransaction implements Op op = mHead; int num = 0; while (op != null) { - writer.print(prefix); writer.print(" Op #"); writer.print(num); - writer.println(":"); - writer.print(innerPrefix); writer.print("cmd="); writer.print(op.cmd); - writer.print(" fragment="); writer.println(op.fragment); - if (op.enterAnim != 0 || op.exitAnim != 0) { - writer.print(prefix); writer.print("enterAnim=#"); - writer.print(Integer.toHexString(op.enterAnim)); - writer.print(" exitAnim=#"); - writer.println(Integer.toHexString(op.exitAnim)); + String cmdStr; + switch (op.cmd) { + case OP_NULL: cmdStr="NULL"; break; + case OP_ADD: cmdStr="ADD"; break; + case OP_REPLACE: cmdStr="REPLACE"; break; + case OP_REMOVE: cmdStr="REMOVE"; break; + case OP_HIDE: cmdStr="HIDE"; break; + case OP_SHOW: cmdStr="SHOW"; break; + case OP_DETACH: cmdStr="DETACH"; break; + case OP_ATTACH: cmdStr="ATTACH"; break; + default: cmdStr="cmd=" + op.cmd; break; } - if (op.popEnterAnim != 0 || op.popExitAnim != 0) { - writer.print(prefix); writer.print("popEnterAnim=#"); - writer.print(Integer.toHexString(op.popEnterAnim)); - writer.print(" popExitAnim=#"); - writer.println(Integer.toHexString(op.popExitAnim)); + writer.print(prefix); writer.print(" Op #"); writer.print(num); + writer.print(": "); writer.print(cmdStr); + writer.print(" "); writer.println(op.fragment); + if (full) { + if (op.enterAnim != 0 || op.exitAnim != 0) { + writer.print(innerPrefix); writer.print("enterAnim=#"); + writer.print(Integer.toHexString(op.enterAnim)); + writer.print(" exitAnim=#"); + writer.println(Integer.toHexString(op.exitAnim)); + } + if (op.popEnterAnim != 0 || op.popExitAnim != 0) { + writer.print(innerPrefix); writer.print("popEnterAnim=#"); + writer.print(Integer.toHexString(op.popEnterAnim)); + writer.print(" popExitAnim=#"); + writer.println(Integer.toHexString(op.popExitAnim)); + } } if (op.removed != null && op.removed.size() > 0) { for (int i=0; i<op.removed.size(); i++) { @@ -276,14 +315,17 @@ final class BackStackRecord extends FragmentTransaction implements if (op.removed.size() == 1) { writer.print("Removed: "); } else { - writer.println("Removed:"); - writer.print(innerPrefix); writer.print(" #"); writer.print(num); + if (i == 0) { + writer.println("Removed:"); + } + writer.print(innerPrefix); writer.print(" #"); writer.print(i); writer.print(": "); } writer.println(op.removed.get(i)); } } op = op.next; + num++; } } } @@ -538,7 +580,12 @@ final class BackStackRecord extends FragmentTransaction implements int commitInternal(boolean allowStateLoss) { if (mCommitted) throw new IllegalStateException("commit already called"); - if (FragmentManagerImpl.DEBUG) Log.v(TAG, "Commit: " + this); + if (FragmentManagerImpl.DEBUG) { + Log.v(TAG, "Commit: " + this); + LogWriter logw = new LogWriter(Log.VERBOSE, TAG); + PrintWriter pw = new PrintWriter(logw); + dump(" ", null, pw, null); + } mCommitted = true; if (mAddToBackStack) { mIndex = mManager.allocBackStackIndex(this); @@ -641,7 +688,12 @@ final class BackStackRecord extends FragmentTransaction implements } public void popFromBackStack(boolean doStateMove) { - if (FragmentManagerImpl.DEBUG) Log.v(TAG, "popFromBackStack: " + this); + if (FragmentManagerImpl.DEBUG) { + Log.v(TAG, "popFromBackStack: " + this); + LogWriter logw = new LogWriter(Log.VERBOSE, TAG); + PrintWriter pw = new PrintWriter(logw); + dump(" ", null, pw, null); + } bumpBackStackNesting(-1); diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index a6ec9b6..c41405b 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -965,6 +965,20 @@ class ContextImpl extends Context { startActivities(intents, null); } + /** @hide */ + @Override + public void startActivitiesAsUser(Intent[] intents, Bundle options, UserHandle userHandle) { + if ((intents[0].getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) { + throw new AndroidRuntimeException( + "Calling startActivities() from outside of an Activity " + + " context requires the FLAG_ACTIVITY_NEW_TASK flag on first Intent." + + " Is this really what you want?"); + } + mMainThread.getInstrumentation().execStartActivitiesAsUser( + getOuterContext(), mMainThread.getApplicationThread(), null, + (Activity)null, intents, options, userHandle.getIdentifier()); + } + @Override public void startActivities(Intent[] intents, Bundle options) { if ((intents[0].getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) { @@ -1015,7 +1029,7 @@ class ContextImpl extends Context { ActivityManagerNative.getDefault().broadcastIntent( mMainThread.getApplicationThread(), intent, resolvedType, null, Activity.RESULT_OK, null, null, null, false, false, - UserHandle.myUserId()); + getUserId()); } catch (RemoteException e) { } } @@ -1028,7 +1042,7 @@ class ContextImpl extends Context { ActivityManagerNative.getDefault().broadcastIntent( mMainThread.getApplicationThread(), intent, resolvedType, null, Activity.RESULT_OK, null, null, receiverPermission, false, false, - UserHandle.myUserId()); + getUserId()); } catch (RemoteException e) { } } @@ -1042,7 +1056,7 @@ class ContextImpl extends Context { ActivityManagerNative.getDefault().broadcastIntent( mMainThread.getApplicationThread(), intent, resolvedType, null, Activity.RESULT_OK, null, null, receiverPermission, true, false, - UserHandle.myUserId()); + getUserId()); } catch (RemoteException e) { } } @@ -1075,7 +1089,7 @@ class ContextImpl extends Context { ActivityManagerNative.getDefault().broadcastIntent( mMainThread.getApplicationThread(), intent, resolvedType, rd, initialCode, initialData, initialExtras, receiverPermission, - true, false, UserHandle.myUserId()); + true, false, getUserId()); } catch (RemoteException e) { } } @@ -1146,7 +1160,7 @@ class ContextImpl extends Context { ActivityManagerNative.getDefault().broadcastIntent( mMainThread.getApplicationThread(), intent, resolvedType, null, Activity.RESULT_OK, null, null, null, false, true, - UserHandle.myUserId()); + getUserId()); } catch (RemoteException e) { } } @@ -1179,7 +1193,7 @@ class ContextImpl extends Context { ActivityManagerNative.getDefault().broadcastIntent( mMainThread.getApplicationThread(), intent, resolvedType, rd, initialCode, initialData, initialExtras, null, - true, true, UserHandle.myUserId()); + true, true, getUserId()); } catch (RemoteException e) { } } @@ -1194,7 +1208,7 @@ class ContextImpl extends Context { try { intent.setAllowFds(false); ActivityManagerNative.getDefault().unbroadcastIntent( - mMainThread.getApplicationThread(), intent, UserHandle.myUserId()); + mMainThread.getApplicationThread(), intent, getUserId()); } catch (RemoteException e) { } } @@ -1267,7 +1281,7 @@ class ContextImpl extends Context { @Override public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler) { - return registerReceiverInternal(receiver, UserHandle.myUserId(), + return registerReceiverInternal(receiver, getUserId(), filter, broadcastPermission, scheduler, getOuterContext()); } @@ -1323,12 +1337,12 @@ class ContextImpl extends Context { @Override public ComponentName startService(Intent service) { - return startServiceAsUser(service, Process.myUserHandle()); + return startServiceAsUser(service, mUser); } @Override public boolean stopService(Intent service) { - return stopServiceAsUser(service, Process.myUserHandle()); + return stopServiceAsUser(service, mUser); } @Override @@ -1432,7 +1446,7 @@ class ContextImpl extends Context { arguments.setAllowFds(false); } return ActivityManagerNative.getDefault().startInstrumentation( - className, profileFile, 0, arguments, null, UserHandle.myUserId()); + className, profileFile, 0, arguments, null, getUserId()); } catch (RemoteException e) { // System has crashed, nothing we can do. } @@ -1693,7 +1707,8 @@ class ContextImpl extends Context { } LoadedApk pi = - mMainThread.getPackageInfo(packageName, mResources.getCompatibilityInfo(), flags); + mMainThread.getPackageInfo(packageName, mResources.getCompatibilityInfo(), flags, + user.getIdentifier()); if (pi != null) { ContextImpl c = new ContextImpl(); c.mRestricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED; @@ -1777,6 +1792,11 @@ class ContextImpl extends Context { return file; } + /** {@hide} */ + public int getUserId() { + return mUser.getIdentifier(); + } + static ContextImpl createSystemContext(ActivityThread mainThread) { final ContextImpl context = new ContextImpl(); context.init(Resources.getSystem(), mainThread, Process.myUserHandle()); diff --git a/core/java/android/app/DownloadManager.java b/core/java/android/app/DownloadManager.java index 0b1c524..6cf4dd0 100644 --- a/core/java/android/app/DownloadManager.java +++ b/core/java/android/app/DownloadManager.java @@ -1098,8 +1098,8 @@ public class DownloadManager { */ public static Long getMaxBytesOverMobile(Context context) { try { - return Settings.Secure.getLong(context.getContentResolver(), - Settings.Secure.DOWNLOAD_MAX_BYTES_OVER_MOBILE); + return Settings.Global.getLong(context.getContentResolver(), + Settings.Global.DOWNLOAD_MAX_BYTES_OVER_MOBILE); } catch (SettingNotFoundException exc) { return null; } @@ -1116,8 +1116,8 @@ public class DownloadManager { */ public static Long getRecommendedMaxBytesOverMobile(Context context) { try { - return Settings.Secure.getLong(context.getContentResolver(), - Settings.Secure.DOWNLOAD_RECOMMENDED_MAX_BYTES_OVER_MOBILE); + return Settings.Global.getLong(context.getContentResolver(), + Settings.Global.DOWNLOAD_RECOMMENDED_MAX_BYTES_OVER_MOBILE); } catch (SettingNotFoundException exc) { return null; } diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java index 7f11437..e983299 100644 --- a/core/java/android/app/FragmentManager.java +++ b/core/java/android/app/FragmentManager.java @@ -22,6 +22,7 @@ import android.animation.AnimatorListenerAdapter; import android.content.res.Configuration; import android.content.res.TypedArray; import android.os.Bundle; +import android.os.Debug; import android.os.Handler; import android.os.Looper; import android.os.Parcel; @@ -771,12 +772,12 @@ final class FragmentManagerImpl extends FragmentManager { void moveToState(Fragment f, int newState, int transit, int transitionStyle, boolean keepActive) { - //if (DEBUG) Log.v(TAG, "moveToState: " + f - // + " oldState=" + f.mState + " newState=" + newState - // + " mRemoving=" + f.mRemoving + " Callers=" + Debug.getCallers(5)); + if (DEBUG && false) Log.v(TAG, "moveToState: " + f + + " oldState=" + f.mState + " newState=" + newState + + " mRemoving=" + f.mRemoving + " Callers=" + Debug.getCallers(5)); // Fragments that are not currently added will sit in the onCreate() state. - if (!f.mAdded && newState > Fragment.CREATED) { + if ((!f.mAdded || f.mDetached) && newState > Fragment.CREATED) { newState = Fragment.CREATED; } if (f.mRemoving && newState > f.mState) { @@ -1112,6 +1113,9 @@ final class FragmentManagerImpl extends FragmentManager { if (DEBUG) Log.v(TAG, "add: " + fragment); makeActive(fragment); if (!fragment.mDetached) { + if (mAdded.contains(fragment)) { + throw new IllegalStateException("Fragment already added: " + fragment); + } mAdded.add(fragment); fragment.mAdded = true; fragment.mRemoving = false; @@ -1128,6 +1132,14 @@ final class FragmentManagerImpl extends FragmentManager { if (DEBUG) Log.v(TAG, "remove: " + fragment + " nesting=" + fragment.mBackStackNesting); final boolean inactive = !fragment.isInBackStack(); if (!fragment.mDetached || inactive) { + if (false) { + // Would be nice to catch a bad remove here, but we need + // time to test this to make sure we aren't crashes cases + // where it is not a problem. + if (!mAdded.contains(fragment)) { + throw new IllegalStateException("Fragment not added: " + fragment); + } + } if (mAdded != null) { mAdded.remove(fragment); } @@ -1200,6 +1212,7 @@ final class FragmentManagerImpl extends FragmentManager { if (fragment.mAdded) { // We are not already in back stack, so need to remove the fragment. if (mAdded != null) { + if (DEBUG) Log.v(TAG, "remove from detach: " + fragment); mAdded.remove(fragment); } if (fragment.mHasMenu && fragment.mMenuVisible) { @@ -1219,6 +1232,10 @@ final class FragmentManagerImpl extends FragmentManager { if (mAdded == null) { mAdded = new ArrayList<Fragment>(); } + if (mAdded.contains(fragment)) { + throw new IllegalStateException("Fragment already added: " + fragment); + } + if (DEBUG) Log.v(TAG, "add from attach: " + fragment); mAdded.add(fragment); fragment.mAdded = true; if (fragment.mHasMenu && fragment.mMenuVisible) { @@ -1717,19 +1734,18 @@ final class FragmentManagerImpl extends FragmentManager { FragmentState fs = fms.mActive[i]; if (fs != null) { Fragment f = fs.instantiate(mActivity, mParent); - if (DEBUG) Log.v(TAG, "restoreAllState: adding #" + i + ": " + f); + if (DEBUG) Log.v(TAG, "restoreAllState: active #" + i + ": " + f); mActive.add(f); // Now that the fragment is instantiated (or came from being // retained above), clear mInstance in case we end up re-restoring // from this FragmentState again. fs.mInstance = null; } else { - if (DEBUG) Log.v(TAG, "restoreAllState: adding #" + i + ": (null)"); mActive.add(null); if (mAvailIndices == null) { mAvailIndices = new ArrayList<Integer>(); } - if (DEBUG) Log.v(TAG, "restoreAllState: adding avail #" + i); + if (DEBUG) Log.v(TAG, "restoreAllState: avail #" + i); mAvailIndices.add(i); } } @@ -1760,7 +1776,10 @@ final class FragmentManagerImpl extends FragmentManager { "No instantiated fragment for index #" + fms.mAdded[i])); } f.mAdded = true; - if (DEBUG) Log.v(TAG, "restoreAllState: making added #" + i + ": " + f); + if (DEBUG) Log.v(TAG, "restoreAllState: added #" + i + ": " + f); + if (mAdded.contains(f)) { + throw new IllegalStateException("Already added!"); + } mAdded.add(f); } } else { @@ -1772,8 +1791,13 @@ final class FragmentManagerImpl extends FragmentManager { mBackStack = new ArrayList<BackStackRecord>(fms.mBackStack.length); for (int i=0; i<fms.mBackStack.length; i++) { BackStackRecord bse = fms.mBackStack[i].instantiate(this); - if (DEBUG) Log.v(TAG, "restoreAllState: adding bse #" + i + if (DEBUG) { + Log.v(TAG, "restoreAllState: back stack #" + i + " (index " + bse.mIndex + "): " + bse); + LogWriter logw = new LogWriter(Log.VERBOSE, TAG); + PrintWriter pw = new PrintWriter(logw); + bse.dump(" ", pw, false); + } mBackStack.add(bse); if (bse.mIndex >= 0) { setBackStackIndex(bse.mIndex, bse); diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java index 2b2679e..9454636 100644 --- a/core/java/android/app/IActivityManager.java +++ b/core/java/android/app/IActivityManager.java @@ -311,7 +311,7 @@ public interface IActivityManager extends IInterface { public int startActivities(IApplicationThread caller, Intent[] intents, String[] resolvedTypes, IBinder resultTo, - Bundle options) throws RemoteException; + Bundle options, int userId) throws RemoteException; public int getFrontActivityScreenCompatMode() throws RemoteException; public void setFrontActivityScreenCompatMode(int mode) throws RemoteException; diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java index ee4e964..e0856ae 100644 --- a/core/java/android/app/Instrumentation.java +++ b/core/java/android/app/Instrumentation.java @@ -1430,6 +1430,21 @@ public class Instrumentation { */ public void execStartActivities(Context who, IBinder contextThread, IBinder token, Activity target, Intent[] intents, Bundle options) { + execStartActivitiesAsUser(who, contextThread, token, target, intents, options, + UserHandle.myUserId()); + } + + /** + * Like {@link #execStartActivity(Context, IBinder, IBinder, Activity, Intent, int)}, + * but accepts an array of activities to be started. Note that active + * {@link ActivityMonitor} objects only match against the first activity in + * the array. + * + * {@hide} + */ + public void execStartActivitiesAsUser(Context who, IBinder contextThread, + IBinder token, Activity target, Intent[] intents, Bundle options, + int userId) { IApplicationThread whoThread = (IApplicationThread) contextThread; if (mActivityMonitors != null) { synchronized (mSync) { @@ -1453,7 +1468,8 @@ public class Instrumentation { resolvedTypes[i] = intents[i].resolveTypeIfNeeded(who.getContentResolver()); } int result = ActivityManagerNative.getDefault() - .startActivities(whoThread, intents, resolvedTypes, token, options); + .startActivities(whoThread, intents, resolvedTypes, token, options, + userId); checkStartActivityResult(result, intents[0]); } catch (RemoteException e) { } diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java index c095280..0acad75 100644 --- a/core/java/android/app/NotificationManager.java +++ b/core/java/android/app/NotificationManager.java @@ -124,6 +124,9 @@ public class NotificationManager int[] idOut = new int[1]; INotificationManager service = getService(); String pkg = mContext.getPackageName(); + if (notification.sound != null) { + notification.sound = notification.sound.getCanonicalUri(); + } if (localLOGV) Log.v(TAG, pkg + ": notify(" + id + ", " + notification + ")"); try { service.enqueueNotificationWithTag(pkg, tag, id, notification, idOut, @@ -143,6 +146,9 @@ public class NotificationManager int[] idOut = new int[1]; INotificationManager service = getService(); String pkg = mContext.getPackageName(); + if (notification.sound != null) { + notification.sound = notification.sound.getCanonicalUri(); + } if (localLOGV) Log.v(TAG, pkg + ": notify(" + id + ", " + notification + ")"); try { service.enqueueNotificationWithTag(pkg, tag, id, notification, idOut, diff --git a/core/java/android/app/StatusBarManager.java b/core/java/android/app/StatusBarManager.java index dd9f337..3d656c7 100644 --- a/core/java/android/app/StatusBarManager.java +++ b/core/java/android/app/StatusBarManager.java @@ -97,13 +97,13 @@ public class StatusBarManager { } /** - * Expand the status bar. + * Expand the notifications panel. */ - public void expand() { + public void expandNotificationsPanel() { try { final IStatusBarService svc = getService(); if (svc != null) { - svc.expand(); + svc.expandNotificationsPanel(); } } catch (RemoteException ex) { // system process is dead anyway. @@ -112,13 +112,28 @@ public class StatusBarManager { } /** - * Collapse the status bar. + * Collapse the notifications and settings panels. */ - public void collapse() { + public void collapsePanels() { try { final IStatusBarService svc = getService(); if (svc != null) { - svc.collapse(); + svc.collapsePanels(); + } + } catch (RemoteException ex) { + // system process is dead anyway. + throw new RuntimeException(ex); + } + } + + /** + * Expand the settings panel. + */ + public void expandSettingsPanel() { + try { + final IStatusBarService svc = getService(); + if (svc != null) { + svc.expandSettingsPanel(); } } catch (RemoteException ex) { // system process is dead anyway. diff --git a/core/java/android/app/TaskStackBuilder.java b/core/java/android/app/TaskStackBuilder.java index cadf5e4..9d5bcc6 100644 --- a/core/java/android/app/TaskStackBuilder.java +++ b/core/java/android/app/TaskStackBuilder.java @@ -23,6 +23,7 @@ import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.os.Bundle; +import android.os.UserHandle; import android.util.Log; import java.util.ArrayList; @@ -128,7 +129,11 @@ public class TaskStackBuilder { if (parent != null) { // We have the actual parent intent, build the rest from static metadata // then add the direct parent intent to the end. - addParentStack(parent.getComponent()); + ComponentName target = parent.getComponent(); + if (target == null) { + target = parent.resolveActivity(mSourceContext.getPackageManager()); + } + addParentStack(target); addNextIntent(parent); } return this; @@ -205,18 +210,26 @@ public class TaskStackBuilder { /** * Start the task stack constructed by this builder. - * - * @param options Additional options for how the Activity should be started. - * See {@link android.content.Context#startActivity(Intent, Bundle) - * Context.startActivity(Intent, Bundle)} for more details. + * @hide */ - public void startActivities(Bundle options) { + public void startActivities(Bundle options, UserHandle userHandle) { if (mIntents.isEmpty()) { throw new IllegalStateException( "No intents added to TaskStackBuilder; cannot startActivities"); } - mSourceContext.startActivities(getIntents(), options); + mSourceContext.startActivitiesAsUser(getIntents(), options, userHandle); + } + + /** + * Start the task stack constructed by this builder. + * + * @param options Additional options for how the Activity should be started. + * See {@link android.content.Context#startActivity(Intent, Bundle) + * Context.startActivity(Intent, Bundle)} for more details. + */ + public void startActivities(Bundle options) { + startActivities(options, new UserHandle(UserHandle.myUserId())); } /** diff --git a/core/java/android/app/backup/FullBackup.java b/core/java/android/app/backup/FullBackup.java index d7f1c9f..f859599 100644 --- a/core/java/android/app/backup/FullBackup.java +++ b/core/java/android/app/backup/FullBackup.java @@ -64,7 +64,9 @@ public class FullBackup { /** * Copy data from a socket to the given File location on permanent storage. The - * modification time and access mode of the resulting file will be set if desired. + * modification time and access mode of the resulting file will be set if desired, + * although group/all rwx modes will be stripped: the restored file will not be + * accessible from outside the target application even if the original file was. * If the {@code type} parameter indicates that the result should be a directory, * the socket parameter may be {@code null}; even if it is valid, no data will be * read from it in this case. @@ -79,8 +81,9 @@ public class FullBackup { * @param type Must be either {@link BackupAgent#TYPE_FILE} for ordinary file data * or {@link BackupAgent#TYPE_DIRECTORY} for a directory. * @param mode Unix-style file mode (as used by the chmod(2) syscall) to be set on - * the output file or directory. If this parameter is negative then neither - * the mode nor the mtime parameters will be used. + * the output file or directory. group/all rwx modes are stripped even if set + * in this parameter. If this parameter is negative then neither + * the mode nor the mtime values will be applied to the restored file. * @param mtime A timestamp in the standard Unix epoch that will be imposed as the * last modification time of the output file. if the {@code mode} parameter is * negative then this parameter will be ignored. @@ -105,8 +108,6 @@ public class FullBackup { if (!parent.exists()) { // in practice this will only be for the default semantic directories, // and using the default mode for those is appropriate. - // TODO: support the edge case of apps that have adjusted the - // permissions on these core directories parent.mkdirs(); } out = new FileOutputStream(outFile); @@ -146,6 +147,8 @@ public class FullBackup { // Now twiddle the state to match the backup, assuming all went well if (mode >= 0 && outFile != null) { try { + // explicitly prevent emplacement of files accessible by outside apps + mode &= 0700; Libcore.os.chmod(outFile.getPath(), (int)mode); } catch (ErrnoException e) { e.rethrowAsIOException(); diff --git a/core/java/android/appwidget/AppWidgetHost.java b/core/java/android/appwidget/AppWidgetHost.java index 185fb5a..cb61a71 100644 --- a/core/java/android/appwidget/AppWidgetHost.java +++ b/core/java/android/appwidget/AppWidgetHost.java @@ -21,6 +21,7 @@ import java.util.HashMap; import android.app.ActivityThread; import android.content.Context; +import android.os.Binder; import android.os.Handler; import android.os.IBinder; import android.os.Looper; @@ -57,6 +58,9 @@ public class AppWidgetHost { class Callbacks extends IAppWidgetHost.Stub { public void updateAppWidget(int appWidgetId, RemoteViews views) { + if (isLocalBinder() && views != null) { + views = views.clone(); + } Message msg = mHandler.obtainMessage(HANDLE_UPDATE); msg.arg1 = appWidgetId; msg.obj = views; @@ -64,6 +68,9 @@ public class AppWidgetHost { } public void providerChanged(int appWidgetId, AppWidgetProviderInfo info) { + if (isLocalBinder() && info != null) { + info = info.clone(); + } Message msg = mHandler.obtainMessage(HANDLE_PROVIDER_CHANGED); msg.arg1 = appWidgetId; msg.obj = info; @@ -225,6 +232,10 @@ public class AppWidgetHost { throw new SecurityException("Disallowed call for uid " + uid); } + private boolean isLocalBinder() { + return Process.myPid() == Binder.getCallingPid(); + } + /** * Stop listening to changes for this AppWidget. */ diff --git a/core/java/android/appwidget/AppWidgetProviderInfo.java b/core/java/android/appwidget/AppWidgetProviderInfo.java index 5ef3d39..5074480 100644 --- a/core/java/android/appwidget/AppWidgetProviderInfo.java +++ b/core/java/android/appwidget/AppWidgetProviderInfo.java @@ -281,6 +281,28 @@ public class AppWidgetProviderInfo implements Parcelable { out.writeInt(this.widgetFeatures); } + @Override + public AppWidgetProviderInfo clone() { + AppWidgetProviderInfo that = new AppWidgetProviderInfo(); + that.provider = this.provider == null ? null : this.provider.clone(); + that.minWidth = this.minWidth; + that.minHeight = this.minHeight; + that.minResizeWidth = this.minResizeHeight; + that.minResizeHeight = this.minResizeHeight; + that.updatePeriodMillis = this.updatePeriodMillis; + that.initialLayout = that.initialLayout; + that.initialKeyguardLayout = this.initialKeyguardLayout; + that.configure = this.configure == null ? null : this.configure.clone(); + that.label = this.label == null ? null : this.label.substring(0); + that.icon = this.icon; + that.previewImage = this.previewImage; + that.autoAdvanceViewId = this.autoAdvanceViewId; + that.resizeMode = this.resizeMode; + that.widgetCategory = this.widgetCategory; + that.widgetFeatures = this.widgetFeatures; + return that; + } + public int describeContents() { return 0; } diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 9162d29..201b43f 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -178,7 +178,7 @@ public abstract class Context { * Flag for {@link #bindService}: indicates that the client application * binding to this service considers the service to be more important than * the app itself. When set, the platform will try to have the out of - * memory kill the app before it kills the service it is bound to, though + * memory killer kill the app before it kills the service it is bound to, though * this is not guaranteed to be the case. */ public static final int BIND_ABOVE_CLIENT = 0x0008; @@ -219,6 +219,19 @@ public abstract class Context { public static final int BIND_ADJUST_WITH_ACTIVITY = 0x0080; /** + * @hide An idea that is not yet implemented. + * Flag for {@link #bindService}: If binding from an activity, consider + * this service to be visible like the binding activity is. That is, + * it will be treated as something more important to keep around than + * invisible background activities. This will impact the number of + * recent activities the user can switch between without having them + * restart. There is no guarantee this will be respected, as the system + * tries to balance such requests from one app vs. the importantance of + * keeping other apps around. + */ + public static final int BIND_VISIBLE = 0x0100; + + /** * Flag for {@link #bindService}: Don't consider the bound service to be * visible, even if the caller is visible. * @hide @@ -974,6 +987,36 @@ public abstract class Context { public abstract void startActivities(Intent[] intents, Bundle options); /** + * @hide + * Launch multiple new activities. This is generally the same as calling + * {@link #startActivity(Intent)} for the first Intent in the array, + * that activity during its creation calling {@link #startActivity(Intent)} + * for the second entry, etc. Note that unlike that approach, generally + * none of the activities except the last in the array will be created + * at this point, but rather will be created when the user first visits + * them (due to pressing back from the activity on top). + * + * <p>This method throws {@link ActivityNotFoundException} + * if there was no Activity found for <em>any</em> given Intent. In this + * case the state of the activity stack is undefined (some Intents in the + * list may be on it, some not), so you probably want to avoid such situations. + * + * @param intents An array of Intents to be started. + * @param options Additional options for how the Activity should be started. + * @param userHandle The user for whom to launch the activities + * See {@link android.content.Context#startActivity(Intent, Bundle) + * Context.startActivity(Intent, Bundle)} for more details. + * + * @throws ActivityNotFoundException + * + * @see {@link #startActivities(Intent[])} + * @see PackageManager#resolveActivity + */ + public void startActivitiesAsUser(Intent[] intents, Bundle options, UserHandle userHandle) { + throw new RuntimeException("Not implemented. Must override in a subclass."); + } + + /** * Same as {@link #startIntentSender(IntentSender, Intent, int, int, int, Bundle)} * with no options specified. * diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java index d824f1e..84ad667 100644 --- a/core/java/android/content/ContextWrapper.java +++ b/core/java/android/content/ContextWrapper.java @@ -311,6 +311,12 @@ public class ContextWrapper extends Context { mBase.startActivities(intents, options); } + /** @hide */ + @Override + public void startActivitiesAsUser(Intent[] intents, Bundle options, UserHandle userHandle) { + mBase.startActivitiesAsUser(intents, options, userHandle); + } + @Override public void startIntentSender(IntentSender intent, Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags) diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index b9518b8..c301c5c 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -1305,6 +1305,14 @@ public class Intent implements Parcelable, Cloneable { = "android.intent.extra.REFERRER"; /** + * Used as an int extra field with {@link #ACTION_INSTALL_PACKAGE} and + * {@link} #ACTION_VIEW} to indicate the uid of the package that initiated the install + * @hide + */ + public static final String EXTRA_ORIGINATING_UID + = "android.intent.extra.ORIGINATING_UID"; + + /** * Used as a boolean extra field with {@link #ACTION_INSTALL_PACKAGE} to install a * package. Tells the installer UI to skip the confirmation with the user * if the .apk is replacing an existing one. diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java index 4257e0e..564a804 100644 --- a/core/java/android/content/SyncManager.java +++ b/core/java/android/content/SyncManager.java @@ -203,6 +203,12 @@ public class SyncManager implements OnAccountsUpdateListener { } }; + private BroadcastReceiver mAccountsUpdatedReceiver = new BroadcastReceiver() { + public void onReceive(Context context, Intent intent) { + onAccountsUpdated(null); + } + }; + private final PowerManager mPowerManager; // Use this as a random offset to seed all periodic syncs @@ -456,8 +462,11 @@ public class SyncManager implements OnAccountsUpdateListener { }); if (!factoryTest) { - AccountManager.get(mContext).addOnAccountsUpdatedListener(SyncManager.this, - mSyncHandler, false /* updateImmediately */); + // Register for account list updates for all users + mContext.registerReceiverAsUser(mAccountsUpdatedReceiver, + UserHandle.ALL, + new IntentFilter(AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION), + null, null); // do this synchronously to ensure we have the accounts before this call returns onAccountsUpdated(null); } @@ -768,8 +777,8 @@ public class SyncManager implements OnAccountsUpdateListener { } // Cap the delay - long maxSyncRetryTimeInSeconds = Settings.Secure.getLong(mContext.getContentResolver(), - Settings.Secure.SYNC_MAX_RETRY_DELAY_IN_SECONDS, + long maxSyncRetryTimeInSeconds = Settings.Global.getLong(mContext.getContentResolver(), + Settings.Global.SYNC_MAX_RETRY_DELAY_IN_SECONDS, DEFAULT_MAX_SYNC_RETRY_TIME_IN_SECONDS); if (newDelayInMs > maxSyncRetryTimeInSeconds * 1000) { newDelayInMs = maxSyncRetryTimeInSeconds * 1000; diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 291726a..8ba1988 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -2341,6 +2341,10 @@ public abstract class PackageManager { public abstract Resources getResourcesForApplication(String appPackageName) throws NameNotFoundException; + /** @hide */ + public abstract Resources getResourcesForApplicationAsUser(String appPackageName, int userId) + throws NameNotFoundException; + /** * Retrieve overall information about an application package defined * in a package archive file diff --git a/core/java/android/content/pm/VerificationParams.java b/core/java/android/content/pm/VerificationParams.java index 6454de0..22e1a85 100644 --- a/core/java/android/content/pm/VerificationParams.java +++ b/core/java/android/content/pm/VerificationParams.java @@ -27,6 +27,9 @@ import android.os.Parcelable; * @hide */ public class VerificationParams implements Parcelable { + /** A constant used to indicate that a uid value is not present. */ + public static final int NO_UID = -1; + /** What we print out first when toString() is called. */ private static final String TO_STRING_PREFIX = "VerificationParams{"; @@ -39,6 +42,9 @@ public class VerificationParams implements Parcelable { /** HTTP referrer URI associated with the originatingURI. */ private final Uri mReferrer; + /** UID of the application that the install request originated from. */ + private final int mOriginatingUid; + /** UID of application requesting the install */ private int mInstallerUid; @@ -57,16 +63,19 @@ public class VerificationParams implements Parcelable { * from. May be {@code null}. * @param referrer HTTP referrer URI associated with the originatingURI. * May be {@code null}. + * @param originatingUid UID of the application that the install request originated + * from, or NO_UID if not present * @param manifestDigest an object that holds the digest of the package * which can be used to verify ownership. May be {@code null}. */ public VerificationParams(Uri verificationURI, Uri originatingURI, Uri referrer, - ManifestDigest manifestDigest) { + int originatingUid, ManifestDigest manifestDigest) { mVerificationURI = verificationURI; mOriginatingURI = originatingURI; mReferrer = referrer; + mOriginatingUid = originatingUid; mManifestDigest = manifestDigest; - mInstallerUid = -1; + mInstallerUid = NO_UID; } public Uri getVerificationURI() { @@ -81,11 +90,16 @@ public class VerificationParams implements Parcelable { return mReferrer; } + /** return NO_UID if not available */ + public int getOriginatingUid() { + return mOriginatingUid; + } + public ManifestDigest getManifestDigest() { return mManifestDigest; } - /** @return -1 when not set */ + /** @return NO_UID when not set */ public int getInstallerUid() { return mInstallerUid; } @@ -111,31 +125,39 @@ public class VerificationParams implements Parcelable { final VerificationParams other = (VerificationParams) o; - if (mVerificationURI == null && other.mVerificationURI != null) { - return false; - } - if (!mVerificationURI.equals(other.mVerificationURI)) { + if (mVerificationURI == null) { + if (other.mVerificationURI != null) { + return false; + } + } else if (!mVerificationURI.equals(other.mVerificationURI)) { return false; } - if (mOriginatingURI == null && other.mOriginatingURI != null) { - return false; - } - if (!mOriginatingURI.equals(other.mOriginatingURI)) { + if (mOriginatingURI == null) { + if (other.mOriginatingURI != null) { + return false; + } + } else if (!mOriginatingURI.equals(other.mOriginatingURI)) { return false; } - if (mReferrer == null && other.mReferrer != null) { - return false; - } - if (!mReferrer.equals(other.mReferrer)) { + if (mReferrer == null) { + if (other.mReferrer != null) { + return false; + } + } else if (!mReferrer.equals(other.mReferrer)) { return false; } - if (mManifestDigest == null && other.mManifestDigest != null) { + if (mOriginatingUid != other.mOriginatingUid) { return false; } - if (mManifestDigest != null && !mManifestDigest.equals(other.mManifestDigest)) { + + if (mManifestDigest == null) { + if (other.mManifestDigest != null) { + return false; + } + } else if (!mManifestDigest.equals(other.mManifestDigest)) { return false; } @@ -150,11 +172,12 @@ public class VerificationParams implements Parcelable { public int hashCode() { int hash = 3; - hash += 5 * (mVerificationURI==null?1:mVerificationURI.hashCode()); - hash += 7 * (mOriginatingURI==null?1:mOriginatingURI.hashCode()); - hash += 11 * (mReferrer==null?1:mReferrer.hashCode()); - hash += 13 * (mManifestDigest==null?1:mManifestDigest.hashCode()); - hash += 17 * mInstallerUid; + hash += 5 * (mVerificationURI == null ? 1 : mVerificationURI.hashCode()); + hash += 7 * (mOriginatingURI == null ? 1 : mOriginatingURI.hashCode()); + hash += 11 * (mReferrer == null ? 1 : mReferrer.hashCode()); + hash += 13 * mOriginatingUid; + hash += 17 * (mManifestDigest == null ? 1 : mManifestDigest.hashCode()); + hash += 19 * mInstallerUid; return hash; } @@ -169,6 +192,8 @@ public class VerificationParams implements Parcelable { sb.append(mOriginatingURI.toString()); sb.append(",mReferrer="); sb.append(mReferrer.toString()); + sb.append(",mOriginatingUid="); + sb.append(mOriginatingUid); sb.append(",mManifestDigest="); sb.append(mManifestDigest.toString()); sb.append(",mInstallerUid="); @@ -183,6 +208,7 @@ public class VerificationParams implements Parcelable { dest.writeParcelable(mVerificationURI, 0); dest.writeParcelable(mOriginatingURI, 0); dest.writeParcelable(mReferrer, 0); + dest.writeInt(mOriginatingUid); dest.writeParcelable(mManifestDigest, 0); dest.writeInt(mInstallerUid); } @@ -192,6 +218,7 @@ public class VerificationParams implements Parcelable { mVerificationURI = source.readParcelable(Uri.class.getClassLoader()); mOriginatingURI = source.readParcelable(Uri.class.getClassLoader()); mReferrer = source.readParcelable(Uri.class.getClassLoader()); + mOriginatingUid = source.readInt(); mManifestDigest = source.readParcelable(ManifestDigest.class.getClassLoader()); mInstallerUid = source.readInt(); } diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java index 375d788..1e8671b 100644 --- a/core/java/android/hardware/Camera.java +++ b/core/java/android/hardware/Camera.java @@ -1161,25 +1161,28 @@ public class Camera { public native final void setDisplayOrientation(int degrees); /** - * Enable or disable the default shutter sound when taking a picture. + * <p>Enable or disable the default shutter sound when taking a picture.</p> * - * By default, the camera plays the system-defined camera shutter sound when - * {@link #takePicture} is called. Using this method, the shutter sound can - * be disabled. It is strongly recommended that an alternative shutter sound - * is played in the {@link ShutterCallback} when the system shutter sound is - * disabled. + * <p>By default, the camera plays the system-defined camera shutter sound + * when {@link #takePicture} is called. Using this method, the shutter sound + * can be disabled. It is strongly recommended that an alternative shutter + * sound is played in the {@link ShutterCallback} when the system shutter + * sound is disabled.</p> * - * Note that devices may not always allow control of the camera shutter - * sound. If the shutter sound cannot be controlled, this method will return - * false. + * <p>Note that devices may not always allow disabling the camera shutter + * sound. If the shutter sound state cannot be set to the desired value, + * this method will return false. {@link CameraInfo#canDisableShutterSound} + * can be used to determine whether the device will allow the shutter sound + * to be disabled.</p> * * @param enabled whether the camera should play the system shutter sound * when {@link #takePicture takePicture} is called. - * @return true if the shutter sound state was successfully changed. False - * if the shutter sound cannot be controlled; in this case, the - * application should not play its own shutter sound since the - * system shutter sound will play when a picture is taken. + * @return {@code true} if the shutter sound state was successfully + * changed. {@code false} if the shutter sound state could not be + * changed. {@code true} is also returned if shutter sound playback + * is already set to the requested state. * @see #takePicture + * @see CameraInfo#canDisableShutterSound * @see ShutterCallback */ public native final boolean enableShutterSound(boolean enabled); diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java index 58a0f13..28e320b 100644 --- a/core/java/android/hardware/display/DisplayManager.java +++ b/core/java/android/hardware/display/DisplayManager.java @@ -46,9 +46,7 @@ public final class DisplayManager { * The status is provided as a {@link WifiDisplayStatus} object in the * {@link #EXTRA_WIFI_DISPLAY_STATUS} extra. * </p><p> - * This broadcast is only sent to registered receivers with the - * {@link android.Manifest.permission#CONFIGURE_WIFI_DISPLAY} permission and can - * only be sent by the system. + * This broadcast is only sent to registered receivers and can only be sent by the system. * </p> * @hide */ @@ -163,6 +161,9 @@ public final class DisplayManager { * <p> * Automatically remembers the display after a successful connection, if not * already remembered. + * </p><p> + * Requires {@link android.Manifest.permission#CONFIGURE_WIFI_DISPLAY} to connect + * to unknown displays. No permissions are required to connect to already known displays. * </p> * * @param deviceAddress The MAC address of the device to which we should connect. @@ -187,6 +188,8 @@ public final class DisplayManager { * The display must already be remembered for this call to succeed. In other words, * we must already have successfully connected to the display at least once and then * not forgotten it. + * </p><p> + * Requires {@link android.Manifest.permission#CONFIGURE_WIFI_DISPLAY}. * </p> * * @param deviceAddress The MAC address of the device to rename. @@ -202,6 +205,8 @@ public final class DisplayManager { * Forgets a previously remembered Wifi display. * <p> * Automatically disconnects from the display if currently connected to it. + * </p><p> + * Requires {@link android.Manifest.permission#CONFIGURE_WIFI_DISPLAY}. * </p> * * @param deviceAddress The MAC address of the device to forget. diff --git a/core/java/android/hardware/display/IDisplayManager.aidl b/core/java/android/hardware/display/IDisplayManager.aidl index 4b6fb53..79aad78 100644 --- a/core/java/android/hardware/display/IDisplayManager.aidl +++ b/core/java/android/hardware/display/IDisplayManager.aidl @@ -28,13 +28,14 @@ interface IDisplayManager { void registerCallback(in IDisplayManagerCallback callback); - // Requires CONFIGURE_WIFI_DISPLAY permission. + // No permissions required. void scanWifiDisplays(); - // Requires CONFIGURE_WIFI_DISPLAY permission. + // Requires CONFIGURE_WIFI_DISPLAY permission to connect to an unknown device. + // No permissions required to connect to a known device. void connectWifiDisplay(String address); - // Requires CONFIGURE_WIFI_DISPLAY permission. + // No permissions required. void disconnectWifiDisplay(); // Requires CONFIGURE_WIFI_DISPLAY permission. @@ -43,6 +44,6 @@ interface IDisplayManager { // Requires CONFIGURE_WIFI_DISPLAY permission. void forgetWifiDisplay(String address); - // Requires CONFIGURE_WIFI_DISPLAY permission. + // No permissions required. WifiDisplayStatus getWifiDisplayStatus(); } diff --git a/core/java/android/net/CaptivePortalTracker.java b/core/java/android/net/CaptivePortalTracker.java index 24dc898..9b11094 100644 --- a/core/java/android/net/CaptivePortalTracker.java +++ b/core/java/android/net/CaptivePortalTracker.java @@ -89,12 +89,12 @@ public class CaptivePortalTracker extends StateMachine { filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); mContext.registerReceiver(mReceiver, filter); - mServer = Settings.Secure.getString(mContext.getContentResolver(), - Settings.Secure.CAPTIVE_PORTAL_SERVER); + mServer = Settings.Global.getString(mContext.getContentResolver(), + Settings.Global.CAPTIVE_PORTAL_SERVER); if (mServer == null) mServer = DEFAULT_SERVER; - mIsCaptivePortalCheckEnabled = Settings.Secure.getInt(mContext.getContentResolver(), - Settings.Secure.CAPTIVE_PORTAL_DETECTION_ENABLED, 1) == 1; + mIsCaptivePortalCheckEnabled = Settings.Global.getInt(mContext.getContentResolver(), + Settings.Global.CAPTIVE_PORTAL_DETECTION_ENABLED, 1) == 1; addState(mDefaultState); addState(mNoActiveNetworkState, mDefaultState); diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index a570473..6ff1a33 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -330,6 +330,14 @@ public class ConnectivityManager { public static final int DEFAULT_NETWORK_PREFERENCE = TYPE_WIFI; + /** + * Default value for {@link Settings.Global#CONNECTIVITY_CHANGE_DELAY} in + * milliseconds. + * + * @hide + */ + public static final int CONNECTIVITY_CHANGE_DELAY_DEFAULT = 3000; + private final IConnectivityManager mService; public static boolean isNetworkTypeValid(int networkType) { diff --git a/core/java/android/net/DnsPinger.java b/core/java/android/net/DnsPinger.java index 11acabe..66f0fd0 100644 --- a/core/java/android/net/DnsPinger.java +++ b/core/java/android/net/DnsPinger.java @@ -295,8 +295,8 @@ public final class DnsPinger extends Handler { } private InetAddress getDefaultDns() { - String dns = Settings.Secure.getString(mContext.getContentResolver(), - Settings.Secure.DEFAULT_DNS_SERVER); + String dns = Settings.Global.getString(mContext.getContentResolver(), + Settings.Global.DEFAULT_DNS_SERVER); if (dns == null || dns.length() == 0) { dns = mContext.getResources().getString( com.android.internal.R.string.config_default_dns_server); diff --git a/core/java/android/net/Uri.java b/core/java/android/net/Uri.java index 3b990e3..cc6903d 100644 --- a/core/java/android/net/Uri.java +++ b/core/java/android/net/Uri.java @@ -16,10 +16,13 @@ package android.net; +import android.os.Environment; import android.os.Parcel; import android.os.Parcelable; +import android.os.Environment.UserEnvironment; import android.util.Log; import java.io.File; +import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.nio.charset.Charsets; @@ -2288,4 +2291,39 @@ public abstract class Uri implements Parcelable, Comparable<Uri> { builder = builder.appendEncodedPath(pathSegment); return builder.build(); } + + /** + * If this {@link Uri} is {@code file://}, then resolve and return its + * canonical path. Also fixes legacy emulated storage paths so they are + * usable across user boundaries. Should always be called from the app + * process before sending elsewhere. + * + * @hide + */ + public Uri getCanonicalUri() { + if ("file".equals(getScheme())) { + final String canonicalPath; + try { + canonicalPath = new File(getPath()).getCanonicalPath(); + } catch (IOException e) { + return this; + } + + if (Environment.isExternalStorageEmulated()) { + final String legacyPath = Environment.getLegacyExternalStorageDirectory() + .toString(); + + // Splice in user-specific path when legacy path is found + if (canonicalPath.startsWith(legacyPath)) { + return Uri.fromFile(new File( + Environment.getExternalStorageDirectory().toString(), + canonicalPath.substring(legacyPath.length() + 1))); + } + } + + return Uri.fromFile(new File(canonicalPath)); + } else { + return this; + } + } } diff --git a/core/java/android/nfc/Tag.java b/core/java/android/nfc/Tag.java index f9b765c..f2cd232 100644 --- a/core/java/android/nfc/Tag.java +++ b/core/java/android/nfc/Tag.java @@ -24,6 +24,7 @@ import android.nfc.tech.Ndef; import android.nfc.tech.NdefFormatable; import android.nfc.tech.NfcA; import android.nfc.tech.NfcB; +import android.nfc.tech.NfcBarcode; import android.nfc.tech.NfcF; import android.nfc.tech.NfcV; import android.nfc.tech.TagTechnology; @@ -184,6 +185,9 @@ public final class Tag implements Parcelable { case TagTechnology.NFC_V: strings[i] = NfcV.class.getName(); break; + case TagTechnology.NFC_BARCODE: + strings[i] = NfcBarcode.class.getName(); + break; default: throw new IllegalArgumentException("Unknown tech type " + techList[i]); } diff --git a/core/java/android/nfc/tech/Ndef.java b/core/java/android/nfc/tech/Ndef.java index a31cb9c..64aa299 100644 --- a/core/java/android/nfc/tech/Ndef.java +++ b/core/java/android/nfc/tech/Ndef.java @@ -140,8 +140,8 @@ public final class Ndef extends BasicTagTechnology { * * <p>Does not cause any RF activity and does not block. * - * @param tag an MIFARE Classic compatible tag - * @return MIFARE Classic object + * @param tag an NDEF compatible tag + * @return Ndef object */ public static Ndef get(Tag tag) { if (!tag.hasTech(TagTechnology.NDEF)) return null; diff --git a/core/java/android/nfc/tech/NfcBarcode.java b/core/java/android/nfc/tech/NfcBarcode.java new file mode 100644 index 0000000..3149857 --- /dev/null +++ b/core/java/android/nfc/tech/NfcBarcode.java @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.nfc.tech; + +import android.nfc.Tag; +import android.os.Bundle; +import android.os.RemoteException; + +/** + * Provides access to tags containing just a barcode. + * + * <p>Acquire an {@link NfcBarcode} object using {@link #get}. + * + */ +public final class NfcBarcode extends BasicTagTechnology { + + /** Kovio Tags */ + public static final int TYPE_KOVIO = 1; + public static final int TYPE_UNKNOWN = -1; + + /** @hide */ + public static final String EXTRA_BARCODE_TYPE = "barcodetype"; + + private int mType; + + /** + * Get an instance of {@link NfcBarcode} for the given tag. + * + * <p>Returns null if {@link NfcBarcode} was not enumerated in {@link Tag#getTechList}. + * + * <p>Does not cause any RF activity and does not block. + * + * @param tag an NfcBarcode compatible tag + * @return NfcBarcode object + */ + public static NfcBarcode get(Tag tag) { + if (!tag.hasTech(TagTechnology.NFC_BARCODE)) return null; + try { + return new NfcBarcode(tag); + } catch (RemoteException e) { + return null; + } + } + + /** + * Internal constructor, to be used by NfcAdapter + * @hide + */ + public NfcBarcode(Tag tag) throws RemoteException { + super(tag, TagTechnology.NFC_BARCODE); + Bundle extras = tag.getTechExtras(TagTechnology.NFC_BARCODE); + if (extras != null) { + mType = extras.getInt(EXTRA_BARCODE_TYPE); + } else { + throw new NullPointerException("NfcBarcode tech extras are null."); + } + } + + /** + * Returns the NFC Barcode tag type. + * + * <p>Currently only one of {@link #TYPE_KOVIO} or {@link #TYPE_UNKNOWN}. + * + * <p>Does not cause any RF activity and does not block. + * + * @return the NFC Barcode tag type + */ + public int getType() { + return mType; + } + + /** + * Returns the barcode of an NfcBarcode tag. + * + * <p>Does not cause any RF activity and does not block. + * + * @return a byte array containing the barcode + */ + public byte[] getBarcode() { + switch (mType) { + case TYPE_KOVIO: + // For Kovio tags the barcode matches the ID + return mTag.getId(); + default: + return null; + } + } +} diff --git a/core/java/android/nfc/tech/TagTechnology.java b/core/java/android/nfc/tech/TagTechnology.java index be5cbd2..3493ea7 100644 --- a/core/java/android/nfc/tech/TagTechnology.java +++ b/core/java/android/nfc/tech/TagTechnology.java @@ -148,6 +148,15 @@ public interface TagTechnology extends Closeable { public static final int MIFARE_ULTRALIGHT = 9; /** + * This technology is an instance of {@link NfcBarcode}. + * <p>Support for this technology type is optional. If a stack doesn't support this technology + * type tags using it must still be discovered and present the lower level radio interface + * technologies in use. + * @hide + */ + public static final int NFC_BARCODE = 10; + + /** * Get the {@link Tag} object backing this {@link TagTechnology} object. * @return the {@link Tag} backing this {@link TagTechnology} object. */ diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java index 364004b..3315566 100644 --- a/core/java/android/os/Environment.java +++ b/core/java/android/os/Environment.java @@ -31,6 +31,7 @@ public class Environment { private static final String TAG = "Environment"; private static final String ENV_EXTERNAL_STORAGE = "EXTERNAL_STORAGE"; + private static final String ENV_EMULATED_STORAGE_SOURCE = "EMULATED_STORAGE_SOURCE"; private static final String ENV_EMULATED_STORAGE_TARGET = "EMULATED_STORAGE_TARGET"; private static final String ENV_MEDIA_STORAGE = "MEDIA_STORAGE"; @@ -109,8 +110,6 @@ public class Environment { // /storage/emulated/0 mExternalStorage = buildPath(emulatedBase, rawUserId); - // /storage/emulated/obb - mExternalStorageAndroidObb = buildPath(emulatedBase, "obb"); // /data/media/0 mMediaStorage = buildPath(mediaBase, rawUserId); @@ -123,12 +122,11 @@ public class Environment { // /storage/sdcard0 mExternalStorage = new File(rawExternalStorage); - // /storage/sdcard0/Android/obb - mExternalStorageAndroidObb = buildPath(mExternalStorage, DIRECTORY_ANDROID, "obb"); // /data/media mMediaStorage = new File(rawMediaStorage); } + mExternalStorageAndroidObb = buildPath(mExternalStorage, DIRECTORY_ANDROID, "obb"); mExternalStorageAndroidData = buildPath(mExternalStorage, DIRECTORY_ANDROID, "data"); mExternalStorageAndroidMedia = buildPath(mExternalStorage, DIRECTORY_ANDROID, "media"); } @@ -137,6 +135,10 @@ public class Environment { return mExternalStorage; } + public File getExternalStorageObbDirectory() { + return mExternalStorageAndroidObb; + } + public File getExternalStoragePublicDirectory(String type) { return new File(mExternalStorage, type); } @@ -305,6 +307,23 @@ public class Environment { return new File(System.getenv(ENV_EXTERNAL_STORAGE)); } + /** {@hide} */ + public static File getLegacyExternalStorageObbDirectory() { + return buildPath(getLegacyExternalStorageDirectory(), DIRECTORY_ANDROID, "obb"); + } + + /** {@hide} */ + public static File getEmulatedStorageSource(int userId) { + // /mnt/shell/emulated/0 + return new File(System.getenv(ENV_EMULATED_STORAGE_SOURCE), String.valueOf(userId)); + } + + /** {@hide} */ + public static File getEmulatedStorageObbSource() { + // /mnt/shell/emulated/obb + return new File(System.getenv(ENV_EMULATED_STORAGE_SOURCE), "obb"); + } + /** * Standard directory in which to place any audio files that should be * in the regular list of music for the user. diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl index 7aee644..eec19cb 100644 --- a/core/java/android/os/IPowerManager.aidl +++ b/core/java/android/os/IPowerManager.aidl @@ -34,6 +34,7 @@ interface IPowerManager void userActivity(long time, int event, int flags); void wakeUp(long time); void goToSleep(long time, int reason); + void nap(long time); boolean isScreenOn(); void reboot(String reason); diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java index cc2c002..58372f4 100644 --- a/core/java/android/os/PowerManager.java +++ b/core/java/android/os/PowerManager.java @@ -426,7 +426,7 @@ public final class PowerManager { * </p> * * @param when The time of the user activity, in the {@link SystemClock#uptimeMillis()} - * time base. This timestamp is used to correctly order the user activity with + * time base. This timestamp is used to correctly order the user activity request with * other power management functions. It should be set * to the timestamp of the input event that caused the user activity. * @param noChangeLights If true, does not cause the keyboard backlight to turn on @@ -457,7 +457,7 @@ public final class PowerManager { * * @param time The time when the request to go to sleep was issued, in the * {@link SystemClock#uptimeMillis()} time base. This timestamp is used to correctly - * order the user activity with other power management functions. It should be set + * order the go to sleep request with other power management functions. It should be set * to the timestamp of the input event that caused the request to go to sleep. * * @see #userActivity @@ -481,7 +481,7 @@ public final class PowerManager { * * @param time The time when the request to wake up was issued, in the * {@link SystemClock#uptimeMillis()} time base. This timestamp is used to correctly - * order the user activity with other power management functions. It should be set + * order the wake up request with other power management functions. It should be set * to the timestamp of the input event that caused the request to wake up. * * @see #userActivity @@ -495,6 +495,34 @@ public final class PowerManager { } /** + * Forces the device to start napping. + * <p> + * If the device is currently awake, starts dreaming, otherwise does nothing. + * When the dream ends or if the dream cannot be started, the device will + * either wake up or go to sleep depending on whether there has been recent + * user activity. + * </p><p> + * Requires the {@link android.Manifest.permission#DEVICE_POWER} permission. + * </p> + * + * @param time The time when the request to nap was issued, in the + * {@link SystemClock#uptimeMillis()} time base. This timestamp is used to correctly + * order the nap request with other power management functions. It should be set + * to the timestamp of the input event that caused the request to nap. + * + * @see #wakeUp + * @see #goToSleep + * + * @hide + */ + public void nap(long time) { + try { + mService.nap(time); + } catch (RemoteException e) { + } + } + + /** * Sets the brightness of the backlights (screen, keyboard, button). * <p> * Requires the {@link android.Manifest.permission#DEVICE_POWER} permission. diff --git a/core/java/android/os/SystemClock.java b/core/java/android/os/SystemClock.java index a54c25b..c9adf45 100644 --- a/core/java/android/os/SystemClock.java +++ b/core/java/android/os/SystemClock.java @@ -50,7 +50,7 @@ package android.os; * interval does not span device sleep. Most methods that accept a * timestamp value currently expect the {@link #uptimeMillis} clock. * - * <li> <p> {@link #elapsedRealtime} and {@link #elapsedRealtimeNano} + * <li> <p> {@link #elapsedRealtime} and {@link #elapsedRealtimeNanos} * return the time since the system was booted, and include deep sleep. * This clock is guaranteed to be monotonic, and continues to tick even * when the CPU is in power saving modes, so is the recommend basis @@ -157,7 +157,7 @@ public final class SystemClock { * * @return elapsed nanoseconds since boot. */ - public static native long elapsedRealtimeNano(); + public static native long elapsedRealtimeNanos(); /** * Returns milliseconds running in the current thread. diff --git a/core/java/android/os/UserHandle.aidl b/core/java/android/os/UserHandle.aidl new file mode 100644 index 0000000..4892d32 --- /dev/null +++ b/core/java/android/os/UserHandle.aidl @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2012, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.os; + +parcelable UserHandle; diff --git a/core/java/android/os/storage/IMountService.java b/core/java/android/os/storage/IMountService.java index 0b16316..fc18617 100644 --- a/core/java/android/os/storage/IMountService.java +++ b/core/java/android/os/storage/IMountService.java @@ -489,13 +489,14 @@ public interface IMountService extends IInterface { * IObbActionListener to inform it of the terminal state of the * call. */ - public void mountObb(String filename, String key, IObbActionListener token, int nonce) - throws RemoteException { + public void mountObb(String rawPath, String canonicalPath, String key, + IObbActionListener token, int nonce) throws RemoteException { Parcel _data = Parcel.obtain(); Parcel _reply = Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); - _data.writeString(filename); + _data.writeString(rawPath); + _data.writeString(canonicalPath); _data.writeString(key); _data.writeStrongBinder((token != null ? token.asBinder() : null)); _data.writeInt(nonce); @@ -514,13 +515,14 @@ public interface IMountService extends IInterface { * IObbActionListener to inform it of the terminal state of the * call. */ - public void unmountObb(String filename, boolean force, IObbActionListener token, - int nonce) throws RemoteException { + public void unmountObb( + String rawPath, boolean force, IObbActionListener token, int nonce) + throws RemoteException { Parcel _data = Parcel.obtain(); Parcel _reply = Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); - _data.writeString(filename); + _data.writeString(rawPath); _data.writeInt((force ? 1 : 0)); _data.writeStrongBinder((token != null ? token.asBinder() : null)); _data.writeInt(nonce); @@ -536,13 +538,13 @@ public interface IMountService extends IInterface { * Checks whether the specified Opaque Binary Blob (OBB) is mounted * somewhere. */ - public boolean isObbMounted(String filename) throws RemoteException { + public boolean isObbMounted(String rawPath) throws RemoteException { Parcel _data = Parcel.obtain(); Parcel _reply = Parcel.obtain(); boolean _result; try { _data.writeInterfaceToken(DESCRIPTOR); - _data.writeString(filename); + _data.writeString(rawPath); mRemote.transact(Stub.TRANSACTION_isObbMounted, _data, _reply, 0); _reply.readException(); _result = 0 != _reply.readInt(); @@ -556,13 +558,13 @@ public interface IMountService extends IInterface { /** * Gets the path to the mounted Opaque Binary Blob (OBB). */ - public String getMountedObbPath(String filename) throws RemoteException { + public String getMountedObbPath(String rawPath) throws RemoteException { Parcel _data = Parcel.obtain(); Parcel _reply = Parcel.obtain(); String _result; try { _data.writeInterfaceToken(DESCRIPTOR); - _data.writeString(filename); + _data.writeString(rawPath); mRemote.transact(Stub.TRANSACTION_getMountedObbPath, _data, _reply, 0); _reply.readException(); _result = _reply.readString(); @@ -1042,15 +1044,14 @@ public interface IMountService extends IInterface { } case TRANSACTION_mountObb: { data.enforceInterface(DESCRIPTOR); - String filename; - filename = data.readString(); - String key; - key = data.readString(); + final String rawPath = data.readString(); + final String canonicalPath = data.readString(); + final String key = data.readString(); IObbActionListener observer; observer = IObbActionListener.Stub.asInterface(data.readStrongBinder()); int nonce; nonce = data.readInt(); - mountObb(filename, key, observer, nonce); + mountObb(rawPath, canonicalPath, key, observer, nonce); reply.writeNoException(); return true; } @@ -1194,7 +1195,7 @@ public interface IMountService extends IInterface { /** * Gets the path to the mounted Opaque Binary Blob (OBB). */ - public String getMountedObbPath(String filename) throws RemoteException; + public String getMountedObbPath(String rawPath) throws RemoteException; /** * Gets an Array of currently known secure container IDs @@ -1220,7 +1221,7 @@ public interface IMountService extends IInterface { * Checks whether the specified Opaque Binary Blob (OBB) is mounted * somewhere. */ - public boolean isObbMounted(String filename) throws RemoteException; + public boolean isObbMounted(String rawPath) throws RemoteException; /* * Returns true if the specified container is mounted @@ -1243,8 +1244,8 @@ public interface IMountService extends IInterface { * MountService will call back to the supplied IObbActionListener to inform * it of the terminal state of the call. */ - public void mountObb(String filename, String key, IObbActionListener token, int nonce) - throws RemoteException; + public void mountObb(String rawPath, String canonicalPath, String key, + IObbActionListener token, int nonce) throws RemoteException; /* * Mount a secure container with the specified key and owner UID. Returns an @@ -1287,7 +1288,7 @@ public interface IMountService extends IInterface { * MountService will call back to the supplied IObbActionListener to inform * it of the terminal state of the call. */ - public void unmountObb(String filename, boolean force, IObbActionListener token, int nonce) + public void unmountObb(String rawPath, boolean force, IObbActionListener token, int nonce) throws RemoteException; /* diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java index 54c8709..862a95c 100644 --- a/core/java/android/os/storage/StorageManager.java +++ b/core/java/android/os/storage/StorageManager.java @@ -28,6 +28,10 @@ import android.os.ServiceManager; import android.util.Log; import android.util.SparseArray; +import com.android.internal.util.Preconditions; + +import java.io.File; +import java.io.IOException; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.List; @@ -443,25 +447,23 @@ public class StorageManager * That is, shared UID applications can attempt to mount any other * application's OBB that shares its UID. * - * @param filename the path to the OBB file + * @param rawPath the path to the OBB file * @param key secret used to encrypt the OBB; may be <code>null</code> if no * encryption was used on the OBB. * @param listener will receive the success or failure of the operation * @return whether the mount call was successfully queued or not */ - public boolean mountObb(String filename, String key, OnObbStateChangeListener listener) { - if (filename == null) { - throw new IllegalArgumentException("filename cannot be null"); - } - - if (listener == null) { - throw new IllegalArgumentException("listener cannot be null"); - } + public boolean mountObb(String rawPath, String key, OnObbStateChangeListener listener) { + Preconditions.checkNotNull(rawPath, "rawPath cannot be null"); + Preconditions.checkNotNull(listener, "listener cannot be null"); try { + final String canonicalPath = new File(rawPath).getCanonicalPath(); final int nonce = mObbActionListener.addListener(listener); - mMountService.mountObb(filename, key, mObbActionListener, nonce); + mMountService.mountObb(rawPath, canonicalPath, key, mObbActionListener, nonce); return true; + } catch (IOException e) { + throw new IllegalArgumentException("Failed to resolve path: " + rawPath, e); } catch (RemoteException e) { Log.e(TAG, "Failed to mount OBB", e); } @@ -483,24 +485,19 @@ public class StorageManager * application's OBB that shares its UID. * <p> * - * @param filename path to the OBB file + * @param rawPath path to the OBB file * @param force whether to kill any programs using this in order to unmount * it * @param listener will receive the success or failure of the operation * @return whether the unmount call was successfully queued or not */ - public boolean unmountObb(String filename, boolean force, OnObbStateChangeListener listener) { - if (filename == null) { - throw new IllegalArgumentException("filename cannot be null"); - } - - if (listener == null) { - throw new IllegalArgumentException("listener cannot be null"); - } + public boolean unmountObb(String rawPath, boolean force, OnObbStateChangeListener listener) { + Preconditions.checkNotNull(rawPath, "rawPath cannot be null"); + Preconditions.checkNotNull(listener, "listener cannot be null"); try { final int nonce = mObbActionListener.addListener(listener); - mMountService.unmountObb(filename, force, mObbActionListener, nonce); + mMountService.unmountObb(rawPath, force, mObbActionListener, nonce); return true; } catch (RemoteException e) { Log.e(TAG, "Failed to mount OBB", e); @@ -512,16 +509,14 @@ public class StorageManager /** * Check whether an Opaque Binary Blob (OBB) is mounted or not. * - * @param filename path to OBB image + * @param rawPath path to OBB image * @return true if OBB is mounted; false if not mounted or on error */ - public boolean isObbMounted(String filename) { - if (filename == null) { - throw new IllegalArgumentException("filename cannot be null"); - } + public boolean isObbMounted(String rawPath) { + Preconditions.checkNotNull(rawPath, "rawPath cannot be null"); try { - return mMountService.isObbMounted(filename); + return mMountService.isObbMounted(rawPath); } catch (RemoteException e) { Log.e(TAG, "Failed to check if OBB is mounted", e); } @@ -534,17 +529,15 @@ public class StorageManager * give you the path to where you can obtain access to the internals of the * OBB. * - * @param filename path to OBB image + * @param rawPath path to OBB image * @return absolute path to mounted OBB image data or <code>null</code> if * not mounted or exception encountered trying to read status */ - public String getMountedObbPath(String filename) { - if (filename == null) { - throw new IllegalArgumentException("filename cannot be null"); - } + public String getMountedObbPath(String rawPath) { + Preconditions.checkNotNull(rawPath, "rawPath cannot be null"); try { - return mMountService.getMountedObbPath(filename); + return mMountService.getMountedObbPath(rawPath); } catch (RemoteException e) { Log.e(TAG, "Failed to find mounted path for OBB", e); } diff --git a/core/java/android/provider/CalendarContract.java b/core/java/android/provider/CalendarContract.java index fd0324b..af6e88e9 100644 --- a/core/java/android/provider/CalendarContract.java +++ b/core/java/android/provider/CalendarContract.java @@ -1245,6 +1245,12 @@ public final class CalendarContract { */ public static final String CUSTOM_APP_URI = "customAppUri"; + /** + * The UID for events added from the RFC 2445 iCalendar format. + * Column name. + * <P>Type: TEXT</P> + */ + public static final String UID_2445 = "uid2445"; } /** @@ -1382,6 +1388,7 @@ public final class CalendarContract { DatabaseUtils.cursorIntToContentValuesIfPresent(cursor, cv, GUESTS_CAN_SEE_GUESTS); DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, CUSTOM_APP_PACKAGE); DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, CUSTOM_APP_URI); + DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, UID_2445); DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, ORGANIZER); DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, IS_ORGANIZER); DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, _SYNC_ID); @@ -1587,6 +1594,7 @@ public final class CalendarContract { * <li>{@link #GUESTS_CAN_SEE_GUESTS}</li> * <li>{@link #CUSTOM_APP_PACKAGE}</li> * <li>{@link #CUSTOM_APP_URI}</li> + * <li>{@link #UID_2445}</li> * </ul> * The following Events columns are writable only by a sync adapter * <ul> diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java index 54a2273..b3ab385 100755 --- a/core/java/android/provider/ContactsContract.java +++ b/core/java/android/provider/ContactsContract.java @@ -37,6 +37,7 @@ import android.graphics.Rect; import android.net.Uri; import android.os.Bundle; import android.os.RemoteException; +import android.os.UserHandle; import android.text.TextUtils; import android.util.DisplayMetrics; import android.util.Pair; @@ -7744,7 +7745,7 @@ public final class ContactsContract { intent.setSourceBounds(target); intent.putExtra(EXTRA_MODE, mode); intent.putExtra(EXTRA_EXCLUDE_MIMES, excludeMimes); - context.startActivity(intent); + context.startActivityAsUser(intent, new UserHandle(UserHandle.USER_CURRENT)); } } diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index f41e12c..550713d 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -32,16 +32,19 @@ import android.content.res.Configuration; import android.content.res.Resources; import android.database.Cursor; import android.database.SQLException; +import android.net.ConnectivityManager; import android.net.Uri; import android.net.wifi.WifiManager; import android.os.BatteryManager; import android.os.Bundle; +import android.os.DropBoxManager; import android.os.IBinder; import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemProperties; import android.os.UserHandle; +import android.os.Build.VERSION_CODES; import android.speech.tts.TextToSpeech; import android.text.TextUtils; import android.util.AndroidException; @@ -764,10 +767,6 @@ public final class Settings { return true; } - public boolean putString(ContentResolver cr, String name, String value) { - return putStringForUser(cr, name, value, UserHandle.myUserId()); - } - public String getStringForUser(ContentResolver cr, String name, final int userHandle) { final boolean isSelf = (userHandle == UserHandle.myUserId()); if (isSelf) { @@ -803,7 +802,7 @@ public final class Settings { if (mCallGetCommand != null) { try { Bundle args = null; - if (userHandle != UserHandle.myUserId()) { + if (!isSelf) { args = new Bundle(); args.putInt(CALL_METHOD_USER_KEY, userHandle); } @@ -855,10 +854,6 @@ public final class Settings { if (c != null) c.close(); } } - - public String getString(ContentResolver cr, String name) { - return getStringForUser(cr, name, UserHandle.myUserId()); - } } /** @@ -869,8 +864,17 @@ public final class Settings { public static final class System extends NameValueTable { public static final String SYS_PROP_SETTING_VERSION = "sys.settings_system_version"; - // Populated lazily, guarded by class object: - private static NameValueCache sNameValueCache = null; + /** + * The content:// style URL for this table + */ + public static final Uri CONTENT_URI = + Uri.parse("content://" + AUTHORITY + "/system"); + + private static final NameValueCache sNameValueCache = new NameValueCache( + SYS_PROP_SETTING_VERSION, + CONTENT_URI, + CALL_METHOD_GET_SYSTEM, + CALL_METHOD_PUT_SYSTEM); private static final HashSet<String> MOVED_TO_SECURE; static { @@ -916,6 +920,7 @@ public final class Settings { MOVED_TO_GLOBAL.add(Global.DEVICE_PROVISIONED); MOVED_TO_GLOBAL.add(Global.INSTALL_NON_MARKET_APPS); MOVED_TO_GLOBAL.add(Global.USB_MASS_STORAGE_ENABLED); + MOVED_TO_GLOBAL.add(Global.HTTP_PROXY); // these are moving directly from system to global MOVED_TO_GLOBAL.add(Settings.Global.AIRPLANE_MODE_ON); @@ -937,28 +942,18 @@ public final class Settings { MOVED_TO_GLOBAL.add(Settings.Global.MODE_RINGER); } - private static void lazyInitCache() { - if (sNameValueCache == null) { - sNameValueCache = new NameValueCache( - SYS_PROP_SETTING_VERSION + '_' + UserHandle.myUserId(), - CONTENT_URI, - CALL_METHOD_GET_SYSTEM, - CALL_METHOD_PUT_SYSTEM); - } - } - /** * Look up a name in the database. * @param resolver to access the database with * @param name to look up in the table * @return the corresponding value, or null if not present */ - public synchronized static String getString(ContentResolver resolver, String name) { + public static String getString(ContentResolver resolver, String name) { return getStringForUser(resolver, name, UserHandle.myUserId()); } /** @hide */ - public synchronized static String getStringForUser(ContentResolver resolver, String name, + public static String getStringForUser(ContentResolver resolver, String name, int userHandle) { if (MOVED_TO_SECURE.contains(name)) { Log.w(TAG, "Setting " + name + " has moved from android.provider.Settings.System" @@ -970,7 +965,6 @@ public final class Settings { + " to android.provider.Settings.Global, returning read-only value."); return Global.getStringForUser(resolver, name, userHandle); } - lazyInitCache(); return sNameValueCache.getStringForUser(resolver, name, userHandle); } @@ -998,7 +992,6 @@ public final class Settings { + " to android.provider.Settings.Global, value is unchanged."); return false; } - lazyInitCache(); return sNameValueCache.putStringForUser(resolver, name, value, userHandle); } @@ -1368,12 +1361,6 @@ public final class Settings { } /** - * The content:// style URL for this table - */ - public static final Uri CONTENT_URI = - Uri.parse("content://" + AUTHORITY + "/system"); - - /** * @deprecated Use {@link android.provider.Settings.Global#STAY_ON_WHILE_PLUGGED_IN} instead */ @Deprecated @@ -1504,47 +1491,64 @@ public final class Settings { @Deprecated public static final String MODE_RINGER = Global.MODE_RINGER; - //TODO: deprecate static IP constants /** * Whether to use static IP and other static network attributes. * <p> * Set to 1 for true and 0 for false. + * + * @deprecated Use {@link WifiManager} instead */ + @Deprecated public static final String WIFI_USE_STATIC_IP = "wifi_use_static_ip"; /** * The static IP address. * <p> * Example: "192.168.1.51" + * + * @deprecated Use {@link WifiManager} instead */ + @Deprecated public static final String WIFI_STATIC_IP = "wifi_static_ip"; /** * If using static IP, the gateway's IP address. * <p> * Example: "192.168.1.1" + * + * @deprecated Use {@link WifiManager} instead */ + @Deprecated public static final String WIFI_STATIC_GATEWAY = "wifi_static_gateway"; /** * If using static IP, the net mask. * <p> * Example: "255.255.255.0" + * + * @deprecated Use {@link WifiManager} instead */ + @Deprecated public static final String WIFI_STATIC_NETMASK = "wifi_static_netmask"; /** * If using static IP, the primary DNS's IP address. * <p> * Example: "192.168.1.1" + * + * @deprecated Use {@link WifiManager} instead */ + @Deprecated public static final String WIFI_STATIC_DNS1 = "wifi_static_dns1"; /** * If using static IP, the secondary DNS's IP address. * <p> * Example: "192.168.1.2" + * + * @deprecated Use {@link WifiManager} instead */ + @Deprecated public static final String WIFI_STATIC_DNS2 = "wifi_static_dns2"; @@ -2343,10 +2347,10 @@ public final class Settings { public static final String DEVICE_PROVISIONED = Global.DEVICE_PROVISIONED; /** - * @deprecated Use {@link android.provider.Settings.Secure#HTTP_PROXY} instead + * @deprecated Use {@link android.provider.Settings.Global#HTTP_PROXY} instead */ @Deprecated - public static final String HTTP_PROXY = Secure.HTTP_PROXY; + public static final String HTTP_PROXY = Global.HTTP_PROXY; /** * @deprecated Use {@link android.provider.Settings.Global#INSTALL_NON_MARKET_APPS} instead @@ -2549,8 +2553,18 @@ public final class Settings { public static final class Secure extends NameValueTable { public static final String SYS_PROP_SETTING_VERSION = "sys.settings_secure_version"; + /** + * The content:// style URL for this table + */ + public static final Uri CONTENT_URI = + Uri.parse("content://" + AUTHORITY + "/secure"); + // Populated lazily, guarded by class object: - private static NameValueCache sNameValueCache = null; + private static final NameValueCache sNameValueCache = new NameValueCache( + SYS_PROP_SETTING_VERSION, + CONTENT_URI, + CALL_METHOD_GET_SECURE, + CALL_METHOD_PUT_SECURE); private static ILockSettings sLockSettings = null; @@ -2640,10 +2654,8 @@ public final class Settings { MOVED_TO_GLOBAL.add(Settings.Global.WIFI_SAVED_STATE); MOVED_TO_GLOBAL.add(Settings.Global.WIFI_SUPPLICANT_SCAN_INTERVAL_MS); MOVED_TO_GLOBAL.add(Settings.Global.WIFI_SUSPEND_OPTIMIZATIONS_ENABLED); - MOVED_TO_GLOBAL.add(Settings.Global.WIFI_WATCHDOG_NUM_ARP_PINGS); MOVED_TO_GLOBAL.add(Settings.Global.WIFI_WATCHDOG_ON); MOVED_TO_GLOBAL.add(Settings.Global.WIFI_WATCHDOG_POOR_NETWORK_TEST_ENABLED); - MOVED_TO_GLOBAL.add(Settings.Global.WIFI_WATCHDOG_RSSI_FETCH_INTERVAL_MS); MOVED_TO_GLOBAL.add(Settings.Global.WIMAX_NETWORKS_AVAILABLE_NOTIFICATION_ON); MOVED_TO_GLOBAL.add(Settings.Global.PACKAGE_VERIFIER_ENABLE); MOVED_TO_GLOBAL.add(Settings.Global.PACKAGE_VERIFIER_TIMEOUT); @@ -2652,16 +2664,37 @@ public final class Settings { MOVED_TO_GLOBAL.add(Settings.Global.DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS); MOVED_TO_GLOBAL.add(Settings.Global.GPRS_REGISTER_CHECK_PERIOD_MS); MOVED_TO_GLOBAL.add(Settings.Global.WTF_IS_FATAL); - } - - private static void lazyInitCache() { - if (sNameValueCache == null) { - sNameValueCache = new NameValueCache( - SYS_PROP_SETTING_VERSION + '_' + UserHandle.myUserId(), - CONTENT_URI, - CALL_METHOD_GET_SECURE, - CALL_METHOD_PUT_SECURE); - } + MOVED_TO_GLOBAL.add(Settings.Global.BATTERY_DISCHARGE_DURATION_THRESHOLD); + MOVED_TO_GLOBAL.add(Settings.Global.BATTERY_DISCHARGE_THRESHOLD); + MOVED_TO_GLOBAL.add(Settings.Global.SEND_ACTION_APP_ERROR); + MOVED_TO_GLOBAL.add(Settings.Global.DROPBOX_AGE_SECONDS); + MOVED_TO_GLOBAL.add(Settings.Global.DROPBOX_MAX_FILES); + MOVED_TO_GLOBAL.add(Settings.Global.DROPBOX_QUOTA_KB); + MOVED_TO_GLOBAL.add(Settings.Global.DROPBOX_QUOTA_PERCENT); + MOVED_TO_GLOBAL.add(Settings.Global.DROPBOX_RESERVE_PERCENT); + MOVED_TO_GLOBAL.add(Settings.Global.DROPBOX_TAG_PREFIX); + MOVED_TO_GLOBAL.add(Settings.Global.ERROR_LOGCAT_PREFIX); + MOVED_TO_GLOBAL.add(Settings.Global.SYS_FREE_STORAGE_LOG_INTERVAL); + MOVED_TO_GLOBAL.add(Settings.Global.DISK_FREE_CHANGE_REPORTING_THRESHOLD); + MOVED_TO_GLOBAL.add(Settings.Global.SYS_STORAGE_THRESHOLD_PERCENTAGE); + MOVED_TO_GLOBAL.add(Settings.Global.SYS_STORAGE_THRESHOLD_MAX_BYTES); + MOVED_TO_GLOBAL.add(Settings.Global.SYS_STORAGE_FULL_THRESHOLD_BYTES); + MOVED_TO_GLOBAL.add(Settings.Global.SYNC_MAX_RETRY_DELAY_IN_SECONDS); + MOVED_TO_GLOBAL.add(Settings.Global.CONNECTIVITY_CHANGE_DELAY); + MOVED_TO_GLOBAL.add(Settings.Global.CAPTIVE_PORTAL_DETECTION_ENABLED); + MOVED_TO_GLOBAL.add(Settings.Global.CAPTIVE_PORTAL_SERVER); + MOVED_TO_GLOBAL.add(Settings.Global.NSD_ON); + MOVED_TO_GLOBAL.add(Settings.Global.SET_INSTALL_LOCATION); + MOVED_TO_GLOBAL.add(Settings.Global.DEFAULT_INSTALL_LOCATION); + MOVED_TO_GLOBAL.add(Settings.Global.INET_CONDITION_DEBOUNCE_UP_DELAY); + MOVED_TO_GLOBAL.add(Settings.Global.INET_CONDITION_DEBOUNCE_DOWN_DELAY); + MOVED_TO_GLOBAL.add(Settings.Global.READ_EXTERNAL_STORAGE_ENFORCED_DEFAULT); + MOVED_TO_GLOBAL.add(Settings.Global.HTTP_PROXY); + MOVED_TO_GLOBAL.add(Settings.Global.GLOBAL_HTTP_PROXY_HOST); + MOVED_TO_GLOBAL.add(Settings.Global.GLOBAL_HTTP_PROXY_PORT); + MOVED_TO_GLOBAL.add(Settings.Global.GLOBAL_HTTP_PROXY_EXCLUSION_LIST); + MOVED_TO_GLOBAL.add(Settings.Global.SET_GLOBAL_HTTP_PROXY); + MOVED_TO_GLOBAL.add(Settings.Global.DEFAULT_DNS_SERVER); } /** @@ -2670,12 +2703,12 @@ public final class Settings { * @param name to look up in the table * @return the corresponding value, or null if not present */ - public synchronized static String getString(ContentResolver resolver, String name) { + public static String getString(ContentResolver resolver, String name) { return getStringForUser(resolver, name, UserHandle.myUserId()); } /** @hide */ - public synchronized static String getStringForUser(ContentResolver resolver, String name, + public static String getStringForUser(ContentResolver resolver, String name, int userHandle) { if (MOVED_TO_GLOBAL.contains(name)) { Log.w(TAG, "Setting " + name + " has moved from android.provider.Settings.Secure" @@ -2683,21 +2716,23 @@ public final class Settings { return Global.getStringForUser(resolver, name, userHandle); } - if (sLockSettings == null) { - sLockSettings = ILockSettings.Stub.asInterface( - (IBinder) ServiceManager.getService("lock_settings")); - sIsSystemProcess = Process.myUid() == Process.SYSTEM_UID; - } - if (sLockSettings != null && !sIsSystemProcess - && MOVED_TO_LOCK_SETTINGS.contains(name)) { - try { - return sLockSettings.getString(name, "0", userHandle); - } catch (RemoteException re) { - // Fall through + if (MOVED_TO_LOCK_SETTINGS.contains(name)) { + synchronized (Secure.class) { + if (sLockSettings == null) { + sLockSettings = ILockSettings.Stub.asInterface( + (IBinder) ServiceManager.getService("lock_settings")); + sIsSystemProcess = Process.myUid() == Process.SYSTEM_UID; + } + } + if (sLockSettings != null && !sIsSystemProcess) { + try { + return sLockSettings.getString(name, "0", userHandle); + } catch (RemoteException re) { + // Fall through + } } } - lazyInitCache(); return sNameValueCache.getStringForUser(resolver, name, userHandle); } @@ -2720,7 +2755,6 @@ public final class Settings { + " to android.provider.Settings.Global"); return Global.putStringForUser(resolver, name, value, userHandle); } - lazyInitCache(); return sNameValueCache.putStringForUser(resolver, name, value, userHandle); } @@ -3001,12 +3035,6 @@ public final class Settings { } /** - * The content:// style URL for this table - */ - public static final Uri CONTENT_URI = - Uri.parse("content://" + AUTHORITY + "/secure"); - - /** * @deprecated Use {@link android.provider.Settings.Global#DEVELOPMENT_SETTINGS_ENABLED} * instead */ @@ -3076,6 +3104,7 @@ public final class Settings { /** * @deprecated Use {@link android.provider.Settings.Global#DATA_ROAMING} instead */ + @Deprecated public static final String DATA_ROAMING = Global.DATA_ROAMING; /** @@ -3127,45 +3156,13 @@ public final class Settings { public static final String DISABLED_SYSTEM_INPUT_METHODS = "disabled_system_input_methods"; /** - * Host name and port for global http proxy. Uses ':' seperator for between host and port - * TODO - deprecate in favor of global_http_proxy_host, etc - */ - public static final String HTTP_PROXY = "http_proxy"; - - /** - * Host name for global http proxy. Set via ConnectivityManager. - * @hide - */ - public static final String GLOBAL_HTTP_PROXY_HOST = "global_http_proxy_host"; - - /** - * Integer host port for global http proxy. Set via ConnectivityManager. - * @hide - */ - public static final String GLOBAL_HTTP_PROXY_PORT = "global_http_proxy_port"; - - /** - * Exclusion list for global proxy. This string contains a list of comma-separated - * domains where the global proxy does not apply. Domains should be listed in a comma- - * separated list. Example of acceptable formats: ".domain1.com,my.domain2.com" - * Use ConnectivityManager to set/get. - * @hide - */ - public static final String GLOBAL_HTTP_PROXY_EXCLUSION_LIST = - "global_http_proxy_exclusion_list"; - - /** - * Enables the UI setting to allow the user to specify the global HTTP proxy - * and associated exclusion list. - * @hide - */ - public static final String SET_GLOBAL_HTTP_PROXY = "set_global_http_proxy"; - - /** - * Setting for default DNS in case nobody suggests one - * @hide + * Host name and port for global http proxy. Uses ':' seperator for + * between host and port. + * + * @deprecated Use {@link Global#HTTP_PROXY} */ - public static final String DEFAULT_DNS_SERVER = "default_dns_server"; + @Deprecated + public static final String HTTP_PROXY = Global.HTTP_PROXY; /** * @deprecated Use {@link android.provider.Settings.Global#INSTALL_NON_MARKET_APPS} instead @@ -3237,27 +3234,6 @@ public final class Settings { "lock_screen_owner_info_enabled"; /** - * @deprecated Use {@link android.provider.Settings.Global#DISPLAY_SIZE_FORCED} instead - * @hide - */ - @Deprecated - public static final String DISPLAY_SIZE_FORCED = Global.DISPLAY_SIZE_FORCED; - - /** - * @deprecated Use {@link android.provider.Settings.Global#DISPLAY_DENSITY_FORCED} instead - * @hide - */ - @Deprecated - public static final String DISPLAY_DENSITY_FORCED = Global.DISPLAY_DENSITY_FORCED; - - /** - * @deprecated Use {@link android.provider.Settings.Global#ASSISTED_GPS_ENABLED} instead - * @hide - */ - @Deprecated - public static final String ASSISTED_GPS_ENABLED = Global.ASSISTED_GPS_ENABLED; - - /** * The Logging ID (a unique 64-bit value) as a hex string. * Used as a pseudonymous identifier for logging. * @deprecated This identifier is poorly initialized and has @@ -3273,44 +3249,6 @@ public final class Settings { public static final String NETWORK_PREFERENCE = Global.NETWORK_PREFERENCE; /** - * @deprecated Use {@link android.provider.Settings.Global#TETHER_SUPPORTED} instead - * @hide - */ - @Deprecated - public static final String TETHER_SUPPORTED = Global.TETHER_SUPPORTED; - - /** - * @deprecated Use {@link android.provider.Settings.Global#TETHER_DUN_REQUIRED} instead - * @hide - */ - @Deprecated - public static final String TETHER_DUN_REQUIRED = Global.TETHER_DUN_REQUIRED; - - /** - * @deprecated Use {@link android.provider.Settings.Global#TETHER_DUN_REQUIRED} instead - * @hide - */ - @Deprecated - public static final String TETHER_DUN_APN = Global.TETHER_DUN_APN; - - /** - * @deprecated Use {@link android.provider.Settings.Global#DATA_ACTIVITY_TIMEOUT_MOBILE} - * instead - * @hide - */ - @Deprecated - public static final String DATA_ACTIVITY_TIMEOUT_MOBILE = - Global.DATA_ACTIVITY_TIMEOUT_MOBILE; - - /** - * @deprecated Use {@link android.provider.Settings.Global#DATA_ACTIVITY_TIMEOUT_MOBILE} - * instead - * @hide - */ - @Deprecated - public static final String DATA_ACTIVITY_TIMEOUT_WIFI = Global.DATA_ACTIVITY_TIMEOUT_WIFI; - - /** * No longer supported. */ public static final String PARENTAL_CONTROL_ENABLED = "parental_control_enabled"; @@ -3326,13 +3264,6 @@ public final class Settings { public static final String PARENTAL_CONTROL_REDIRECT_URL = "parental_control_redirect_url"; /** - * @deprecated Use {@link android.provider.Settings.Global#SAMPLING_PROFILER_MS} instead - * @hide - */ - @Deprecated - public static final String SAMPLING_PROFILER_MS = Global.SAMPLING_PROFILER_MS; - - /** * Settings classname to launch when Settings is clicked from All * Applications. Needed because of user testing between the old * and new Settings apps. @@ -3369,7 +3300,7 @@ public final class Settings { "enabled_accessibility_services"; /** - * List of the accessibility services to which the user has graned + * List of the accessibility services to which the user has granted * permission to put the device into touch exploration mode. * * @hide @@ -3388,7 +3319,7 @@ public final class Settings { * <p> * Note: The JavaScript based screen-reader is served by the * Google infrastructure and enable users with disabilities to - * efficiantly navigate in and explore web content. + * efficiently navigate in and explore web content. * </p> * <p> * This property represents a boolean value. @@ -3400,7 +3331,7 @@ public final class Settings { /** * The URL for the injected JavaScript based screen-reader used - * for providing accessiblity of content in WebView. + * for providing accessibility of content in WebView. * <p> * Note: The JavaScript based screen-reader is served by the * Google infrastructure and enable users with disabilities to @@ -3584,13 +3515,6 @@ public final class Settings { @Deprecated public static final String WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON = Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON; - /** - * @deprecated Moved to Global namespace - * {@hide} - */ - @Deprecated - public static final String WIMAX_NETWORKS_AVAILABLE_NOTIFICATION_ON = - Global.WIMAX_NETWORKS_AVAILABLE_NOTIFICATION_ON; /** * @deprecated Use {@link android.provider.Settings.Global#WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY} @@ -3601,15 +3525,6 @@ public final class Settings { Global.WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY; /** - * @deprecated Use {@link android.provider.Settings.Global#WIFI_COUNTRY_CODE} - * instead. - * @hide - */ - @Deprecated - public static final String WIFI_COUNTRY_CODE = Global.WIFI_COUNTRY_CODE; - - - /** * @deprecated Use {@link android.provider.Settings.Global#WIFI_NUM_OPEN_NETWORKS_KEPT} * instead. */ @@ -3625,40 +3540,9 @@ public final class Settings { public static final String WIFI_ON = Global.WIFI_ON; /** - * Used to save the Wifi_ON state prior to tethering. - * This state will be checked to restore Wifi after - * the user turns off tethering. - * - * @hide - * @deprecated moved to Global - */ - @Deprecated - public static final String WIFI_SAVED_STATE = Global.WIFI_SAVED_STATE; - - /** - * AP SSID - * - * @hide - */ - public static final String WIFI_AP_SSID = "wifi_ap_ssid"; - - /** - * AP security - * - * @hide - */ - public static final String WIFI_AP_SECURITY = "wifi_ap_security"; - - /** - * AP passphrase - * - * @hide - */ - public static final String WIFI_AP_PASSWD = "wifi_ap_passwd"; - - /** * The acceptable packet loss percentage (range 0 - 100) before trying * another AP on the same network. + * @deprecated This setting is not used. */ @Deprecated public static final String WIFI_WATCHDOG_ACCEPTABLE_PACKET_LOSS_PERCENTAGE = @@ -3667,12 +3551,14 @@ public final class Settings { /** * The number of access points required for a network in order for the * watchdog to monitor it. + * @deprecated This setting is not used. */ @Deprecated public static final String WIFI_WATCHDOG_AP_COUNT = "wifi_watchdog_ap_count"; /** * The delay between background checks. + * @deprecated This setting is not used. */ @Deprecated public static final String WIFI_WATCHDOG_BACKGROUND_CHECK_DELAY_MS = @@ -3681,6 +3567,7 @@ public final class Settings { /** * Whether the Wi-Fi watchdog is enabled for background checking even * after it thinks the user has connected to a good access point. + * @deprecated This setting is not used. */ @Deprecated public static final String WIFI_WATCHDOG_BACKGROUND_CHECK_ENABLED = @@ -3688,6 +3575,7 @@ public final class Settings { /** * The timeout for a background ping + * @deprecated This setting is not used. */ @Deprecated public static final String WIFI_WATCHDOG_BACKGROUND_CHECK_TIMEOUT_MS = @@ -3698,6 +3586,7 @@ public final class Settings { * fail. Again, if these fail, they will *not* be used in packet loss * calculation. For example, one network always seemed to time out for * the first couple pings, so this is set to 3 by default. + * @deprecated This setting is not used. */ @Deprecated public static final String WIFI_WATCHDOG_INITIAL_IGNORED_PING_COUNT = @@ -3708,91 +3597,46 @@ public final class Settings { * If this number is reached, the watchdog will no longer monitor the * initial connection state for the network. This is a safeguard for * networks containing multiple APs whose DNS does not respond to pings. + * @deprecated This setting is not used. */ @Deprecated public static final String WIFI_WATCHDOG_MAX_AP_CHECKS = "wifi_watchdog_max_ap_checks"; /** - * Whether the Wi-Fi watchdog is enabled. + * @deprecated Use {@link android.provider.Settings.Global#WIFI_WATCHDOG_ON} instead */ + @Deprecated public static final String WIFI_WATCHDOG_ON = "wifi_watchdog_on"; /** * A comma-separated list of SSIDs for which the Wi-Fi watchdog should be enabled. + * @deprecated This setting is not used. */ @Deprecated public static final String WIFI_WATCHDOG_WATCH_LIST = "wifi_watchdog_watch_list"; /** * The number of pings to test if an access point is a good connection. + * @deprecated This setting is not used. */ @Deprecated public static final String WIFI_WATCHDOG_PING_COUNT = "wifi_watchdog_ping_count"; /** * The delay between pings. + * @deprecated This setting is not used. */ @Deprecated public static final String WIFI_WATCHDOG_PING_DELAY_MS = "wifi_watchdog_ping_delay_ms"; /** * The timeout per ping. + * @deprecated This setting is not used. */ @Deprecated public static final String WIFI_WATCHDOG_PING_TIMEOUT_MS = "wifi_watchdog_ping_timeout_ms"; /** - * ms delay before rechecking an 'online' wifi connection when it is thought to be unstable. - * @hide - */ - public static final String WIFI_WATCHDOG_ARP_CHECK_INTERVAL_MS = - "wifi_watchdog_arp_interval_ms"; - - /** - * ms delay interval between rssi polling when the signal is known to be weak - * @hide - */ - public static final String WIFI_WATCHDOG_RSSI_FETCH_INTERVAL_MS = - "wifi_watchdog_rssi_fetch_interval_ms"; - - - /** - * Number of ARP pings per check. - * @hide - */ - public static final String WIFI_WATCHDOG_NUM_ARP_PINGS = "wifi_watchdog_num_arp_pings"; - - /** - * Minimum number of responses to the arp pings to consider the test 'successful'. - * @hide - */ - public static final String WIFI_WATCHDOG_MIN_ARP_RESPONSES = - "wifi_watchdog_min_arp_responses"; - - /** - * Timeout on ARP pings - * @hide - */ - public static final String WIFI_WATCHDOG_ARP_PING_TIMEOUT_MS = - "wifi_watchdog_arp_ping_timeout_ms"; - - /** - * Setting to turn off poor network avoidance on Wi-Fi. Feature is enabled by default and - * the setting needs to be set to 0 to disable it. - * @hide - */ - public static final String WIFI_WATCHDOG_POOR_NETWORK_TEST_ENABLED = - "wifi_watchdog_poor_network_test_enabled"; - - /** - * Setting to turn on suspend optimizations at screen off on Wi-Fi. Enabled by default and - * needs to be set to 0 to disable it. - * @hide - */ - public static final String WIFI_SUSPEND_OPTIMIZATIONS_ENABLED = - "wifi_suspend_optimizations_enabled"; - - /** * @deprecated Use * {@link android.provider.Settings.Global#WIFI_MAX_DHCP_RETRY_COUNT} instead */ @@ -3800,52 +3644,21 @@ public final class Settings { public static final String WIFI_MAX_DHCP_RETRY_COUNT = Global.WIFI_MAX_DHCP_RETRY_COUNT; /** - * The operational wifi frequency band - * Set to one of {@link WifiManager#WIFI_FREQUENCY_BAND_AUTO}, - * {@link WifiManager#WIFI_FREQUENCY_BAND_5GHZ} or - * {@link WifiManager#WIFI_FREQUENCY_BAND_2GHZ} - * - * @hide - */ - public static final String WIFI_FREQUENCY_BAND = "wifi_frequency_band"; - - /** - * The Wi-Fi peer-to-peer device name - * @hide - */ - public static final String WIFI_P2P_DEVICE_NAME = "wifi_p2p_device_name"; - - /** - * Setting to turn off captive portal detection. Feature is enabled by default and - * the setting needs to be set to 0 to disable it. - * @hide - */ - public static final String CAPTIVE_PORTAL_DETECTION_ENABLED = - "captive_portal_detection_enabled"; - - /** - * The server used for captive portal detection upon a new conection. A 204 response - * code from the server is used for validation. - * @hide - */ - public static final String CAPTIVE_PORTAL_SERVER = "captive_portal_server"; - - /** - * Maximum amount of time in milliseconds to hold a wakelock while waiting for mobile - * data connectivity to be established after a disconnect from Wi-Fi. + * @deprecated Use + * {@link android.provider.Settings.Global#WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS} instead */ + @Deprecated public static final String WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS = - "wifi_mobile_data_transition_wakelock_timeout_ms"; - - /** - * Whether network service discovery is enabled. - * @hide - */ - public static final String NSD_ON = "nsd_on"; + Global.WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS; /** - * Whether background data usage is allowed by the user. See - * ConnectivityManager for more info. + * Whether background data usage is allowed. + * + * @deprecated As of {@link VERSION_CODES#ICE_CREAM_SANDWICH}, + * availability of background data depends on several + * combined factors. When background data is unavailable, + * {@link ConnectivityManager#getActiveNetworkInfo()} will + * now appear disconnected. */ @Deprecated public static final String BACKGROUND_DATA = "background_data"; @@ -3858,27 +3671,6 @@ public final class Settings { = "allowed_geolocation_origins"; /** - * @deprecated Use {@link android.provider.Settings.Global#MOBILE_DATA} instead - * @hide - */ - @Deprecated - public static final String MOBILE_DATA = Global.MOBILE_DATA; - - /** - * @deprecated Use {@link android.provider.Settings.Global#CDMA_ROAMING_MODE} instead - * @hide - */ - @Deprecated - public static final String CDMA_ROAMING_MODE = Global.CDMA_ROAMING_MODE; - - /** - * @deprecated Use {@link android.provider.Settings.Global#CDMA_ROAMING_MODE} instead - * @hide - */ - @Deprecated - public static final String CDMA_SUBSCRIPTION_MODE = Global.CDMA_SUBSCRIPTION_MODE; - - /** * The preferred network mode 7 = Global * 6 = EvDo only * 5 = CDMA w/o EvDo @@ -3902,14 +3694,6 @@ public final class Settings { public static final String PREFERRED_TTY_MODE = "preferred_tty_mode"; - - /** - * @deprecated Use {@link android.provider.Settings.Global#CDMA_CELL_BROADCAST_SMS} instead - * @hide - */ - @Deprecated - public static final String CDMA_CELL_BROADCAST_SMS = Global.CDMA_CELL_BROADCAST_SMS; - /** * The cdma subscription 0 = Subscription from RUIM, when available * 1 = Subscription from NV @@ -3935,18 +3719,6 @@ public final class Settings { public static final String TTY_MODE_ENABLED = "tty_mode_enabled"; /** - * The number of milliseconds to delay before sending out Connectivyt Change broadcasts - * @hide - */ - public static final String CONNECTIVITY_CHANGE_DELAY = "connectivity_change_delay"; - - /** - * Default value for CONNECTIVITY_CHANGE_DELAY in milliseconds. - * @hide - */ - public static final int CONNECTIVITY_CHANGE_DELAY_DEFAULT = 3000; - - /** * Controls whether settings backup is enabled. * Type: int ( 0 = disabled, 1 = enabled ) * @hide @@ -3982,398 +3754,17 @@ public final class Settings { public static final String LAST_SETUP_SHOWN = "last_setup_shown"; /** - * How frequently (in seconds) to check the memory status of the - * device. - * @hide - */ - public static final String MEMCHECK_INTERVAL = "memcheck_interval"; - - /** - * Max frequency (in seconds) to log memory check stats, in realtime - * seconds. This allows for throttling of logs when the device is - * running for large amounts of time. - * @hide - */ - public static final String MEMCHECK_LOG_REALTIME_INTERVAL = - "memcheck_log_realtime_interval"; - - /** - * Boolean indicating whether rebooting due to system memory checks - * is enabled. - * @hide - */ - public static final String MEMCHECK_SYSTEM_ENABLED = "memcheck_system_enabled"; - - /** - * How many bytes the system process must be below to avoid scheduling - * a soft reboot. This reboot will happen when it is next determined - * to be a good time. - * @hide - */ - public static final String MEMCHECK_SYSTEM_SOFT_THRESHOLD = "memcheck_system_soft"; - - /** - * How many bytes the system process must be below to avoid scheduling - * a hard reboot. This reboot will happen immediately. - * @hide - */ - public static final String MEMCHECK_SYSTEM_HARD_THRESHOLD = "memcheck_system_hard"; - - /** - * How many bytes the phone process must be below to avoid scheduling - * a soft restart. This restart will happen when it is next determined - * to be a good time. - * @hide - */ - public static final String MEMCHECK_PHONE_SOFT_THRESHOLD = "memcheck_phone_soft"; - - /** - * How many bytes the phone process must be below to avoid scheduling - * a hard restart. This restart will happen immediately. - * @hide - */ - public static final String MEMCHECK_PHONE_HARD_THRESHOLD = "memcheck_phone_hard"; - - /** - * Boolean indicating whether restarting the phone process due to - * memory checks is enabled. - * @hide - */ - public static final String MEMCHECK_PHONE_ENABLED = "memcheck_phone_enabled"; - - /** - * First time during the day it is okay to kill processes - * or reboot the device due to low memory situations. This number is - * in seconds since midnight. - * @hide - */ - public static final String MEMCHECK_EXEC_START_TIME = "memcheck_exec_start_time"; - - /** - * Last time during the day it is okay to kill processes - * or reboot the device due to low memory situations. This number is - * in seconds since midnight. - * @hide - */ - public static final String MEMCHECK_EXEC_END_TIME = "memcheck_exec_end_time"; - - /** - * How long the screen must have been off in order to kill processes - * or reboot. This number is in seconds. A value of -1 means to - * entirely disregard whether the screen is on. - * @hide - */ - public static final String MEMCHECK_MIN_SCREEN_OFF = "memcheck_min_screen_off"; - - /** - * How much time there must be until the next alarm in order to kill processes - * or reboot. This number is in seconds. Note: this value must be - * smaller than {@link #MEMCHECK_RECHECK_INTERVAL} or else it will - * always see an alarm scheduled within its time. - * @hide - */ - public static final String MEMCHECK_MIN_ALARM = "memcheck_min_alarm"; - - /** - * How frequently to check whether it is a good time to restart things, - * if the device is in a bad state. This number is in seconds. Note: - * this value must be larger than {@link #MEMCHECK_MIN_ALARM} or else - * the alarm to schedule the recheck will always appear within the - * minimum "do not execute now" time. - * @hide - */ - public static final String MEMCHECK_RECHECK_INTERVAL = "memcheck_recheck_interval"; - - /** - * How frequently (in DAYS) to reboot the device. If 0, no reboots - * will occur. - * @hide - */ - public static final String REBOOT_INTERVAL = "reboot_interval"; - - /** - * First time during the day it is okay to force a reboot of the - * device (if REBOOT_INTERVAL is set). This number is - * in seconds since midnight. - * @hide - */ - public static final String REBOOT_START_TIME = "reboot_start_time"; - - /** - * The window of time (in seconds) after each REBOOT_INTERVAL in which - * a reboot can be executed. If 0, a reboot will always be executed at - * exactly the given time. Otherwise, it will only be executed if - * the device is idle within the window. - * @hide - */ - public static final String REBOOT_WINDOW = "reboot_window"; - - /** - * Threshold values for the duration and level of a discharge cycle, under - * which we log discharge cycle info. - * @hide - */ - public static final String BATTERY_DISCHARGE_DURATION_THRESHOLD = - "battery_discharge_duration_threshold"; - /** @hide */ - public static final String BATTERY_DISCHARGE_THRESHOLD = "battery_discharge_threshold"; - - /** - * Flag for allowing ActivityManagerService to send ACTION_APP_ERROR intents - * on application crashes and ANRs. If this is disabled, the crash/ANR dialog - * will never display the "Report" button. - * Type: int ( 0 = disallow, 1 = allow ) - * @hide - */ - public static final String SEND_ACTION_APP_ERROR = "send_action_app_error"; - - /** - * @deprecated Use {@link android.provider.Settings.Global#WTF_IS_FATAL} instead - * @hide - */ - @Deprecated - public static final String WTF_IS_FATAL = Global.WTF_IS_FATAL; - - /** - * Maximum age of entries kept by {@link com.android.internal.os.IDropBoxManagerService}. - * @hide - */ - public static final String DROPBOX_AGE_SECONDS = - "dropbox_age_seconds"; - /** - * Maximum number of entry files which {@link com.android.internal.os.IDropBoxManagerService} will keep around. - * @hide - */ - public static final String DROPBOX_MAX_FILES = - "dropbox_max_files"; - /** - * Maximum amount of disk space used by {@link com.android.internal.os.IDropBoxManagerService} no matter what. - * @hide - */ - public static final String DROPBOX_QUOTA_KB = - "dropbox_quota_kb"; - /** - * Percent of free disk (excluding reserve) which {@link com.android.internal.os.IDropBoxManagerService} will use. - * @hide - */ - public static final String DROPBOX_QUOTA_PERCENT = - "dropbox_quota_percent"; - /** - * Percent of total disk which {@link com.android.internal.os.IDropBoxManagerService} will never dip into. - * @hide - */ - public static final String DROPBOX_RESERVE_PERCENT = - "dropbox_reserve_percent"; - /** - * Prefix for per-tag dropbox disable/enable settings. - * @hide - */ - public static final String DROPBOX_TAG_PREFIX = - "dropbox:"; - /** - * Lines of logcat to include with system crash/ANR/etc. reports, - * as a prefix of the dropbox tag of the report type. - * For example, "logcat_for_system_server_anr" controls the lines - * of logcat captured with system server ANR reports. 0 to disable. - * @hide - */ - public static final String ERROR_LOGCAT_PREFIX = - "logcat_for_"; - - - /** - * Screen timeout in milliseconds corresponding to the - * PowerManager's POKE_LOCK_SHORT_TIMEOUT flag (i.e. the fastest - * possible screen timeout behavior.) - * @hide - */ - public static final String SHORT_KEYLIGHT_DELAY_MS = - "short_keylight_delay_ms"; - - /** - * The interval in minutes after which the amount of free storage left on the - * device is logged to the event log - * @hide - */ - public static final String SYS_FREE_STORAGE_LOG_INTERVAL = - "sys_free_storage_log_interval"; - - /** - * Threshold for the amount of change in disk free space required to report the amount of - * free space. Used to prevent spamming the logs when the disk free space isn't changing - * frequently. - * @hide - */ - public static final String DISK_FREE_CHANGE_REPORTING_THRESHOLD = - "disk_free_change_reporting_threshold"; - - - /** - * Minimum percentage of free storage on the device that is used to determine if - * the device is running low on storage. The default is 10. - * <p>Say this value is set to 10, the device is considered running low on storage - * if 90% or more of the device storage is filled up. - * @hide - */ - public static final String SYS_STORAGE_THRESHOLD_PERCENTAGE = - "sys_storage_threshold_percentage"; - - /** - * Maximum byte size of the low storage threshold. This is to ensure - * that {@link #SYS_STORAGE_THRESHOLD_PERCENTAGE} does not result in - * an overly large threshold for large storage devices. Currently this - * must be less than 2GB. This default is 500MB. - * @hide - */ - public static final String SYS_STORAGE_THRESHOLD_MAX_BYTES = - "sys_storage_threshold_max_bytes"; - - /** - * Minimum bytes of free storage on the device before the data - * partition is considered full. By default, 1 MB is reserved - * to avoid system-wide SQLite disk full exceptions. - * @hide - */ - public static final String SYS_STORAGE_FULL_THRESHOLD_BYTES = - "sys_storage_full_threshold_bytes"; - - /** * The interval in milliseconds after which Wi-Fi is considered idle. * When idle, it is possible for the device to be switched from Wi-Fi to * the mobile data network. * @hide - * @deprecated Moved to Global + * @deprecated Use {@link android.provider.Settings.Global#WIFI_IDLE_MS} + * instead. */ @Deprecated public static final String WIFI_IDLE_MS = Global.WIFI_IDLE_MS; /** - * The interval in milliseconds to issue wake up scans when wifi needs - * to connect. This is necessary to connect to an access point when - * device is on the move and the screen is off. - * @hide - * @deprecated Moved to Global - */ - @Deprecated - public static final String WIFI_FRAMEWORK_SCAN_INTERVAL_MS = - Global.WIFI_FRAMEWORK_SCAN_INTERVAL_MS; - - /** - * The interval in milliseconds to scan as used by the wifi supplicant - * @hide - * @deprecated Moved to Global - */ - @Deprecated - public static final String WIFI_SUPPLICANT_SCAN_INTERVAL_MS = - Global.WIFI_SUPPLICANT_SCAN_INTERVAL_MS; - - /** - * @deprecated Moved to Settings.Global - * @hide - */ - @Deprecated - public static final String PDP_WATCHDOG_POLL_INTERVAL_MS = - Global.PDP_WATCHDOG_POLL_INTERVAL_MS; - - /** - * @deprecated Moved to Settings.Global - * @hide - */ - @Deprecated - public static final String PDP_WATCHDOG_LONG_POLL_INTERVAL_MS = - Global.PDP_WATCHDOG_LONG_POLL_INTERVAL_MS; - - /** - * @deprecated Moved to Settings.Global - * @hide - */ - @Deprecated - public static final String PDP_WATCHDOG_ERROR_POLL_INTERVAL_MS = - Global.PDP_WATCHDOG_ERROR_POLL_INTERVAL_MS; - - /** - * @deprecated Moved to Settings.Global - * @hide - */ - @Deprecated - public static final String PDP_WATCHDOG_TRIGGER_PACKET_COUNT = - Global.PDP_WATCHDOG_TRIGGER_PACKET_COUNT; - - /** - * @deprecated Moved to Settings.Global - * @hide - */ - @Deprecated - public static final String PDP_WATCHDOG_ERROR_POLL_COUNT = - Global.PDP_WATCHDOG_ERROR_POLL_COUNT; - - /** - * @deprecated Moved to Settings.Global - * @hide - */ - @Deprecated - public static final String PDP_WATCHDOG_MAX_PDP_RESET_FAIL_COUNT = - Global.PDP_WATCHDOG_MAX_PDP_RESET_FAIL_COUNT; - - /** - * @deprecated Moved to Settings.Global - * @hide - */ - @Deprecated - public static final String DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS = - Global.DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS; - - /** - * @deprecated Moved to Settings.Global - * @hide - */ - @Deprecated - public static final String DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS = - Global.DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS; - - /** - * @deprecated Moved to Settings.Global - * @hide - */ - @Deprecated - public static final String GPRS_REGISTER_CHECK_PERIOD_MS = - Global.GPRS_REGISTER_CHECK_PERIOD_MS; - - /** - * @deprecated Use {@link android.provider.Settings.Global#NITZ_UPDATE_SPACING} instead - * @hide - */ - public static final String NITZ_UPDATE_SPACING = Global.NITZ_UPDATE_SPACING; - - /** - * @deprecated Use {@link android.provider.Settings.Global#NITZ_UPDATE_SPACING} instead - * @hide - */ - public static final String NITZ_UPDATE_DIFF = Global.NITZ_UPDATE_DIFF; - - /** - * The maximum reconnect delay for short network outages or when the network is suspended - * due to phone use. - * @hide - */ - public static final String SYNC_MAX_RETRY_DELAY_IN_SECONDS = - "sync_max_retry_delay_in_seconds"; - - /** - * @deprecated Use {@link Settings.Global#SMS_OUTGOING_CHECK_INTERVAL_MS} instead. - * @hide - */ - public static final String SMS_OUTGOING_CHECK_INTERVAL_MS = - Global.SMS_OUTGOING_CHECK_INTERVAL_MS; - - /** - * @deprecated Use {@link Settings.Global#SMS_OUTGOING_CHECK_MAX_COUNT} instead. - * @hide - */ - public static final String SMS_OUTGOING_CHECK_MAX_COUNT = - Global.SMS_OUTGOING_CHECK_MAX_COUNT; - - /** * The global search provider chosen by the user (if multiple global * search providers are installed). This will be the provider returned * by {@link SearchManager#getGlobalSearchActivity()} if it's still @@ -4593,127 +3984,6 @@ public final class Settings { public static final String UI_NIGHT_MODE = "ui_night_mode"; /** - * Let user pick default install location. - * @hide - */ - public static final String SET_INSTALL_LOCATION = "set_install_location"; - - /** - * Default install location value. - * 0 = auto, let system decide - * 1 = internal - * 2 = sdcard - * @hide - */ - public static final String DEFAULT_INSTALL_LOCATION = "default_install_location"; - - /** - * @deprecated Use {@link android.provider.Settings.Global#THROTTLE_POLLING_SEC} instead - * @hide - */ - @Deprecated - public static final String THROTTLE_POLLING_SEC = Global.THROTTLE_POLLING_SEC; - - /** - * @deprecated Use {@link android.provider.Settings.Global#THROTTLE_THRESHOLD_BYTES} instead - * @hide - */ - @Deprecated - public static final String THROTTLE_THRESHOLD_BYTES = Global.THROTTLE_THRESHOLD_BYTES; - - /** - * @deprecated Use {@link android.provider.Settings.Global#THROTTLE_VALUE_KBITSPS} instead - * @hide - */ - @Deprecated - public static final String THROTTLE_VALUE_KBITSPS = Global.THROTTLE_VALUE_KBITSPS; - - /** - * @deprecated Use {@link android.provider.Settings.Global#THROTTLE_VALUE_KBITSPS} instead - * @hide - */ - @Deprecated - public static final String THROTTLE_RESET_DAY = Global.THROTTLE_RESET_DAY; - - /** - * @deprecated Use {@link android.provider.Settings.Global#THROTTLE_NOTIFICATION_TYPE} instead - * @hide - */ - @Deprecated - public static final String THROTTLE_NOTIFICATION_TYPE = Global.THROTTLE_NOTIFICATION_TYPE; - - /** - * @deprecated Use {@link android.provider.Settings.Global#THROTTLE_HELP_URI} instead - * @hide - */ - @Deprecated - public static final String THROTTLE_HELP_URI = Global.THROTTLE_HELP_URI; - - /** - * @deprecated Use {@link android.provider.Settings.Global#THROTTLE_MAX_NTP_CACHE_AGE_SEC} instead - * @hide - */ - @Deprecated - public static final String THROTTLE_MAX_NTP_CACHE_AGE_SEC = - Global.THROTTLE_MAX_NTP_CACHE_AGE_SEC; - - /** - * @deprecated Use {@link android.provider.Settings.Global#DOWNLOAD_MAX_BYTES_OVER_MOBILE} instead - * @hide - */ - @Deprecated - public static final String DOWNLOAD_MAX_BYTES_OVER_MOBILE = - Global.DOWNLOAD_MAX_BYTES_OVER_MOBILE; - - /** - * @deprecated Use {@link android.provider.Settings.Global#DOWNLOAD_RECOMMENDED_MAX_BYTES_OVER_MOBILE} instead - * @hide - */ - @Deprecated - public static final String DOWNLOAD_RECOMMENDED_MAX_BYTES_OVER_MOBILE = - Global.DOWNLOAD_RECOMMENDED_MAX_BYTES_OVER_MOBILE; - - /** - * ms during which to consume extra events related to Inet connection condition - * after a transtion to fully-connected - * @hide - */ - public static final String INET_CONDITION_DEBOUNCE_UP_DELAY = - "inet_condition_debounce_up_delay"; - - /** - * ms during which to consume extra events related to Inet connection condtion - * after a transtion to partly-connected - * @hide - */ - public static final String INET_CONDITION_DEBOUNCE_DOWN_DELAY = - "inet_condition_debounce_down_delay"; - - /** - * @deprecated Use {@link android.provider.Settings.Global#SETUP_PREPAID_DATA_SERVICE_URL} instead - * @hide - */ - @Deprecated - public static final String SETUP_PREPAID_DATA_SERVICE_URL = - Global.SETUP_PREPAID_DATA_SERVICE_URL; - - /** - * @deprecated Use {@link android.provider.Settings.Global#SETUP_PREPAID_DETECTION_TARGET_URL} instead - * @hide - */ - @Deprecated - public static final String SETUP_PREPAID_DETECTION_TARGET_URL = - Global.SETUP_PREPAID_DETECTION_TARGET_URL; - - /** - * @deprecated Use {@link android.provider.Settings.Global#SETUP_PREPAID_DETECTION_REDIR_HOST} instead - * @hide - */ - @Deprecated - public static final String SETUP_PREPAID_DETECTION_REDIR_HOST = - Global.SETUP_PREPAID_DETECTION_REDIR_HOST; - - /** * Whether screensavers are enabled. * @hide */ @@ -4748,149 +4018,6 @@ public final class Settings { */ public static final String SCREENSAVER_DEFAULT_COMPONENT = "screensaver_default_component"; - /** @deprecated The NETSTATS_* symbols live in Settings.Global.* now - * {@hide} */ - @Deprecated - public static final String NETSTATS_ENABLED = Global.NETSTATS_ENABLED; - /** @deprecated The NETSTATS_* symbols live in Settings.Global.* now - * {@hide} */ - @Deprecated - public static final String NETSTATS_POLL_INTERVAL = Global.NETSTATS_POLL_INTERVAL; - /** @deprecated The NETSTATS_* symbols live in Settings.Global.* now - * {@hide} */ - @Deprecated - public static final String NETSTATS_TIME_CACHE_MAX_AGE = Global.NETSTATS_TIME_CACHE_MAX_AGE; - /** @deprecated The NETSTATS_* symbols live in Settings.Global.* now - * {@hide} */ - @Deprecated - public static final String NETSTATS_GLOBAL_ALERT_BYTES = Global.NETSTATS_GLOBAL_ALERT_BYTES; - /** @deprecated The NETSTATS_* symbols live in Settings.Global.* now - * {@hide} */ - @Deprecated - public static final String NETSTATS_SAMPLE_ENABLED = Global.NETSTATS_SAMPLE_ENABLED; - /** @deprecated The NETSTATS_* symbols live in Settings.Global.* now - * {@hide} */ - @Deprecated - public static final String NETSTATS_REPORT_XT_OVER_DEV = Global.NETSTATS_REPORT_XT_OVER_DEV; - - /** @deprecated The NETSTATS_* symbols live in Settings.Global.* now - * {@hide} */ - @Deprecated - public static final String NETSTATS_DEV_BUCKET_DURATION = Global.NETSTATS_DEV_BUCKET_DURATION; - /** @deprecated The NETSTATS_* symbols live in Settings.Global.* now - * {@hide} */ - @Deprecated - public static final String NETSTATS_DEV_PERSIST_BYTES = Global.NETSTATS_DEV_PERSIST_BYTES; - /** @deprecated The NETSTATS_* symbols live in Settings.Global.* now - * {@hide} */ - @Deprecated - public static final String NETSTATS_DEV_ROTATE_AGE = Global.NETSTATS_DEV_ROTATE_AGE; - /** @deprecated The NETSTATS_* symbols live in Settings.Global.* now - * {@hide} */ - @Deprecated - public static final String NETSTATS_DEV_DELETE_AGE = Global.NETSTATS_DEV_DELETE_AGE; - - /** @deprecated The NETSTATS_* symbols live in Settings.Global.* now - * {@hide} */ - @Deprecated - public static final String NETSTATS_UID_BUCKET_DURATION = Global.NETSTATS_UID_BUCKET_DURATION; - /** @deprecated The NETSTATS_* symbols live in Settings.Global.* now - * {@hide} */ - @Deprecated - public static final String NETSTATS_UID_PERSIST_BYTES = Global.NETSTATS_UID_PERSIST_BYTES; - /** @deprecated The NETSTATS_* symbols live in Settings.Global.* now - * {@hide} */ - @Deprecated - public static final String NETSTATS_UID_ROTATE_AGE = Global.NETSTATS_UID_ROTATE_AGE; - /** @deprecated The NETSTATS_* symbols live in Settings.Global.* now - * {@hide} */ - @Deprecated - public static final String NETSTATS_UID_DELETE_AGE = Global.NETSTATS_UID_DELETE_AGE; - - /** @deprecated The NETSTATS_* symbols live in Settings.Global.* now - * {@hide} */ - @Deprecated - public static final String NETSTATS_UID_TAG_BUCKET_DURATION = Global.NETSTATS_UID_TAG_BUCKET_DURATION; - /** @deprecated The NETSTATS_* symbols live in Settings.Global.* now - * {@hide} */ - @Deprecated - public static final String NETSTATS_UID_TAG_PERSIST_BYTES = Global.NETSTATS_UID_TAG_PERSIST_BYTES; - /** @deprecated The NETSTATS_* symbols live in Settings.Global.* now - * {@hide} */ - @Deprecated - public static final String NETSTATS_UID_TAG_ROTATE_AGE = Global.NETSTATS_UID_TAG_ROTATE_AGE; - /** @deprecated The NETSTATS_* symbols live in Settings.Global.* now - * {@hide} */ - @Deprecated - public static final String NETSTATS_UID_TAG_DELETE_AGE = Global.NETSTATS_UID_TAG_DELETE_AGE; - - /** Preferred NTP server. {@hide} - * @deprecated moved to Settings.Global */ - public static final String NTP_SERVER = Global.NTP_SERVER; - - /** Timeout in milliseconds to wait for NTP server. {@hide} - * @deprecated moved to Settings.Global */ - public static final String NTP_TIMEOUT = Global.NTP_TIMEOUT; - - /** Autofill server address (Used in WebView/browser). - * @deprecated moved to Settings.Global - * {@hide} */ - public static final String WEB_AUTOFILL_QUERY_URL = Global.WEB_AUTOFILL_QUERY_URL; - - /** - * Whether the package manager should send package verification broadcasts for verifiers to - * review apps prior to installation. - * @deprecated moved to Settings.Global - * 1 = request apps to be verified prior to installation, if a verifier exists. - * 0 = do not verify apps before installation - * {@hide} - */ - @Deprecated - public static final String PACKAGE_VERIFIER_ENABLE = "package_verifier_enable"; - - /** Timeout for package verification. - * @deprecated moved to Settings.Global - * {@hide} */ - @Deprecated - public static final String PACKAGE_VERIFIER_TIMEOUT = "verifier_timeout"; - - /** Default response code for package verification. - * @deprecated moved to Settings.Global - * {@hide} */ - @Deprecated - public static final String PACKAGE_VERIFIER_DEFAULT_RESPONSE = "verifier_default_response"; - - /** {@hide} */ - public static final String - READ_EXTERNAL_STORAGE_ENFORCED_DEFAULT = "read_external_storage_enforced_default"; - - /** - * Duration in milliseconds before pre-authorized URIs for the contacts - * provider should expire. - * @hide - */ - public static final String CONTACTS_PREAUTH_URI_EXPIRATION = - "contacts_preauth_uri_expiration"; - - /** - * Overlay display devices setting. - * The associated value is a specially formatted string that describes the - * size and density of simulated secondary display devices. - * <p> - * Format: {width}x{height}/{dpi};... - * </p><p> - * Example: - * <ul> - * <li><code>1280x720/213</code>: make one overlay that is 1280x720 at 213dpi.</li> - * <li><code>1920x1080/320;1280x720/213</code>: make two overlays, the first - * at 1080p and the second at 720p.</li> - * <li>If the value is empty, then no overlay display devices are created.</li> - * </ul></p> - * - * @hide - */ - public static final String OVERLAY_DISPLAY_DEVICES = "overlay_display_devices"; - /** * This are the settings to be backed up. * @@ -4983,6 +4110,15 @@ public final class Settings { public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/global"); /** + * Setting whether the global gesture for enabling accessibility is enabled. + * If this gesture is enabled the user will be able to perfrom it to enable + * the accessibility state without visiting the settings app. + * @hide + */ + public static final String ENABLE_ACCESSIBILITY_GLOBAL_GESTURE_ENABLED = + "enable_accessibility_global_gesture_enabled"; + + /** * Whether Airplane Mode is on. */ public static final String AIRPLANE_MODE_ON = "airplane_mode_on"; @@ -5667,19 +4803,6 @@ public final class Settings { public static final String WIFI_WATCHDOG_ON = "wifi_watchdog_on"; /** - * ms delay interval between rssi polling when the signal is known to be weak - * @hide - */ - public static final String WIFI_WATCHDOG_RSSI_FETCH_INTERVAL_MS = - "wifi_watchdog_rssi_fetch_interval_ms"; - - /** - * Number of ARP pings per check. - * @hide - */ - public static final String WIFI_WATCHDOG_NUM_ARP_PINGS = "wifi_watchdog_num_arp_pings"; - - /** * Setting to turn off poor network avoidance on Wi-Fi. Feature is enabled by default and * the setting needs to be set to 0 to disable it. * @hide @@ -5763,19 +4886,287 @@ public final class Settings { */ public static final String MODE_RINGER = "mode_ringer"; + /** + * Overlay display devices setting. + * The associated value is a specially formatted string that describes the + * size and density of simulated secondary display devices. + * <p> + * Format: {width}x{height}/{dpi};... + * </p><p> + * Example: + * <ul> + * <li><code>1280x720/213</code>: make one overlay that is 1280x720 at 213dpi.</li> + * <li><code>1920x1080/320;1280x720/213</code>: make two overlays, the first + * at 1080p and the second at 720p.</li> + * <li>If the value is empty, then no overlay display devices are created.</li> + * </ul></p> + * + * @hide + */ + public static final String OVERLAY_DISPLAY_DEVICES = "overlay_display_devices"; + + /** + * Threshold values for the duration and level of a discharge cycle, + * under which we log discharge cycle info. + * + * @hide + */ + public static final String + BATTERY_DISCHARGE_DURATION_THRESHOLD = "battery_discharge_duration_threshold"; + + /** @hide */ + public static final String BATTERY_DISCHARGE_THRESHOLD = "battery_discharge_threshold"; + + /** + * Flag for allowing ActivityManagerService to send ACTION_APP_ERROR + * intents on application crashes and ANRs. If this is disabled, the + * crash/ANR dialog will never display the "Report" button. + * <p> + * Type: int (0 = disallow, 1 = allow) + * + * @hide + */ + public static final String SEND_ACTION_APP_ERROR = "send_action_app_error"; + + /** + * Maximum age of entries kept by {@link DropBoxManager}. + * + * @hide + */ + public static final String DROPBOX_AGE_SECONDS = "dropbox_age_seconds"; + + /** + * Maximum number of entry files which {@link DropBoxManager} will keep + * around. + * + * @hide + */ + public static final String DROPBOX_MAX_FILES = "dropbox_max_files"; + + /** + * Maximum amount of disk space used by {@link DropBoxManager} no matter + * what. + * + * @hide + */ + public static final String DROPBOX_QUOTA_KB = "dropbox_quota_kb"; + + /** + * Percent of free disk (excluding reserve) which {@link DropBoxManager} + * will use. + * + * @hide + */ + public static final String DROPBOX_QUOTA_PERCENT = "dropbox_quota_percent"; + + /** + * Percent of total disk which {@link DropBoxManager} will never dip + * into. + * + * @hide + */ + public static final String DROPBOX_RESERVE_PERCENT = "dropbox_reserve_percent"; + + /** + * Prefix for per-tag dropbox disable/enable settings. + * + * @hide + */ + public static final String DROPBOX_TAG_PREFIX = "dropbox:"; + + /** + * Lines of logcat to include with system crash/ANR/etc. reports, as a + * prefix of the dropbox tag of the report type. For example, + * "logcat_for_system_server_anr" controls the lines of logcat captured + * with system server ANR reports. 0 to disable. + * + * @hide + */ + public static final String ERROR_LOGCAT_PREFIX = "logcat_for_"; + + /** + * The interval in minutes after which the amount of free storage left + * on the device is logged to the event log + * + * @hide + */ + public static final String SYS_FREE_STORAGE_LOG_INTERVAL = "sys_free_storage_log_interval"; + + /** + * Threshold for the amount of change in disk free space required to + * report the amount of free space. Used to prevent spamming the logs + * when the disk free space isn't changing frequently. + * + * @hide + */ + public static final String + DISK_FREE_CHANGE_REPORTING_THRESHOLD = "disk_free_change_reporting_threshold"; + + /** + * Minimum percentage of free storage on the device that is used to + * determine if the device is running low on storage. The default is 10. + * <p> + * Say this value is set to 10, the device is considered running low on + * storage if 90% or more of the device storage is filled up. + * + * @hide + */ + public static final String + SYS_STORAGE_THRESHOLD_PERCENTAGE = "sys_storage_threshold_percentage"; + + /** + * Maximum byte size of the low storage threshold. This is to ensure + * that {@link #SYS_STORAGE_THRESHOLD_PERCENTAGE} does not result in an + * overly large threshold for large storage devices. Currently this must + * be less than 2GB. This default is 500MB. + * + * @hide + */ + public static final String + SYS_STORAGE_THRESHOLD_MAX_BYTES = "sys_storage_threshold_max_bytes"; + + /** + * Minimum bytes of free storage on the device before the data partition + * is considered full. By default, 1 MB is reserved to avoid system-wide + * SQLite disk full exceptions. + * + * @hide + */ + public static final String + SYS_STORAGE_FULL_THRESHOLD_BYTES = "sys_storage_full_threshold_bytes"; + + /** + * The maximum reconnect delay for short network outages or when the + * network is suspended due to phone use. + * + * @hide + */ + public static final String + SYNC_MAX_RETRY_DELAY_IN_SECONDS = "sync_max_retry_delay_in_seconds"; + + /** + * The number of milliseconds to delay before sending out + * {@link ConnectivityManager#CONNECTIVITY_ACTION} broadcasts. + * + * @hide + */ + public static final String CONNECTIVITY_CHANGE_DELAY = "connectivity_change_delay"; + + /** + * Setting to turn off captive portal detection. Feature is enabled by + * default and the setting needs to be set to 0 to disable it. + * + * @hide + */ + public static final String + CAPTIVE_PORTAL_DETECTION_ENABLED = "captive_portal_detection_enabled"; + + /** + * The server used for captive portal detection upon a new conection. A + * 204 response code from the server is used for validation. + * + * @hide + */ + public static final String CAPTIVE_PORTAL_SERVER = "captive_portal_server"; + + /** + * Whether network service discovery is enabled. + * + * @hide + */ + public static final String NSD_ON = "nsd_on"; + + /** + * Let user pick default install location. + * + * @hide + */ + public static final String SET_INSTALL_LOCATION = "set_install_location"; + + /** + * Default install location value. + * 0 = auto, let system decide + * 1 = internal + * 2 = sdcard + * @hide + */ + public static final String DEFAULT_INSTALL_LOCATION = "default_install_location"; + + /** + * ms during which to consume extra events related to Inet connection + * condition after a transtion to fully-connected + * + * @hide + */ + public static final String + INET_CONDITION_DEBOUNCE_UP_DELAY = "inet_condition_debounce_up_delay"; + + /** + * ms during which to consume extra events related to Inet connection + * condtion after a transtion to partly-connected + * + * @hide + */ + public static final String + INET_CONDITION_DEBOUNCE_DOWN_DELAY = "inet_condition_debounce_down_delay"; + + /** {@hide} */ + public static final String + READ_EXTERNAL_STORAGE_ENFORCED_DEFAULT = "read_external_storage_enforced_default"; + + /** + * Host name and port for global http proxy. Uses ':' seperator for + * between host and port. + */ + public static final String HTTP_PROXY = "http_proxy"; + + /** + * Host name for global http proxy. Set via ConnectivityManager. + * + * @hide + */ + public static final String GLOBAL_HTTP_PROXY_HOST = "global_http_proxy_host"; + + /** + * Integer host port for global http proxy. Set via ConnectivityManager. + * + * @hide + */ + public static final String GLOBAL_HTTP_PROXY_PORT = "global_http_proxy_port"; + + /** + * Exclusion list for global proxy. This string contains a list of + * comma-separated domains where the global proxy does not apply. + * Domains should be listed in a comma- separated list. Example of + * acceptable formats: ".domain1.com,my.domain2.com" Use + * ConnectivityManager to set/get. + * + * @hide + */ + public static final String + GLOBAL_HTTP_PROXY_EXCLUSION_LIST = "global_http_proxy_exclusion_list"; + + /** + * Enables the UI setting to allow the user to specify the global HTTP + * proxy and associated exclusion list. + * + * @hide + */ + public static final String SET_GLOBAL_HTTP_PROXY = "set_global_http_proxy"; + + /** + * Setting for default DNS in case nobody suggests one + * + * @hide + */ + public static final String DEFAULT_DNS_SERVER = "default_dns_server"; // Populated lazily, guarded by class object: - private static NameValueCache sNameValueCache = null; - - private static void lazyInitCache() { - if (sNameValueCache == null) { - sNameValueCache = new NameValueCache( - SYS_PROP_SETTING_VERSION, - CONTENT_URI, - CALL_METHOD_GET_GLOBAL, - CALL_METHOD_PUT_GLOBAL); - } - } + private static NameValueCache sNameValueCache = new NameValueCache( + SYS_PROP_SETTING_VERSION, + CONTENT_URI, + CALL_METHOD_GET_GLOBAL, + CALL_METHOD_PUT_GLOBAL); /** * Look up a name in the database. @@ -5783,14 +5174,13 @@ public final class Settings { * @param name to look up in the table * @return the corresponding value, or null if not present */ - public synchronized static String getString(ContentResolver resolver, String name) { + public static String getString(ContentResolver resolver, String name) { return getStringForUser(resolver, name, UserHandle.myUserId()); } /** @hide */ - public synchronized static String getStringForUser(ContentResolver resolver, String name, + public static String getStringForUser(ContentResolver resolver, String name, int userHandle) { - lazyInitCache(); return sNameValueCache.getStringForUser(resolver, name, userHandle); } @@ -5809,7 +5199,6 @@ public final class Settings { /** @hide */ public static boolean putStringForUser(ContentResolver resolver, String name, String value, int userHandle) { - lazyInitCache(); if (LOCAL_LOGV) { Log.v(TAG, "Global.putString(name=" + name + ", value=" + value + " for " + userHandle); diff --git a/core/java/android/service/dreams/Dream.java b/core/java/android/service/dreams/Dream.java index dedfb0c..590acfa 100644 --- a/core/java/android/service/dreams/Dream.java +++ b/core/java/android/service/dreams/Dream.java @@ -59,10 +59,10 @@ import com.android.internal.policy.PolicyManager; * <category android:name="android.intent.category.DREAM" /> * </intent-filter> * - * <!-- Point to configuration activity for this dream (optional) --> + * <!-- Point to additional information for this dream (optional) --> * <meta-data - * android:name="android.service.dreams.config_activity" - * android:value="com.example.mypackage/com.example.mypackage.MyDreamSettingsActivity" /> + * android:name="android.service.dream" + * android:resource="@xml/my_dream" /> * </service> * } * </pre> @@ -72,6 +72,12 @@ public class Dream extends Service implements Window.Callback { private final String TAG = Dream.class.getSimpleName() + "[" + getClass().getSimpleName() + "]"; /** + * The name of the dream manager service. + * @hide + */ + public static final String DREAM_SERVICE = "dreams"; + + /** * Used with {@link Intent#ACTION_MAIN} to declare the necessary intent-filter for a dream. * * @see Dream @@ -81,12 +87,12 @@ public class Dream extends Service implements Window.Callback { "android.intent.category.DREAM"; /** - * Service meta-data key for declaring an optional configuration activity. - * - * @see Dream - * */ - public static final String METADATA_NAME_CONFIG_ACTIVITY = - "android.service.dreams.config_activity"; + * Name under which a Dream publishes information about itself. + * This meta-data must reference an XML resource containing + * a <code><{@link android.R.styleable#Dream dream}></code> + * tag. + */ + public static final String DREAM_META_DATA = "android.service.dream"; /** * Broadcast Action: Sent after the system starts dreaming. @@ -361,13 +367,6 @@ public class Dream extends Service implements Window.Callback { return getWindow().findViewById(id); } - /** FIXME remove once platform dreams are updated */ - @Deprecated - protected void lightsOut() { - setLowProfile(true); - setFullscreen(true); - } - /** * Marks this dream as interactive to receive input events. * @@ -506,7 +505,7 @@ public class Dream extends Service implements Window.Callback { // end public api private void loadSandman() { - mSandman = IDreamManager.Stub.asInterface(ServiceManager.getService("dreams")); + mSandman = IDreamManager.Stub.asInterface(ServiceManager.getService(DREAM_SERVICE)); } private final void attach(IBinder windowToken) { @@ -591,7 +590,7 @@ public class Dream extends Service implements Window.Callback { mFinished = true; if (mSandman != null) { - mSandman.awakenSelf(mWindowToken); + mSandman.finishSelf(mWindowToken); } else { Slog.w(TAG, "No dream manager found"); } diff --git a/core/java/android/service/dreams/IDreamManager.aidl b/core/java/android/service/dreams/IDreamManager.aidl index bd1c524..1c1b390 100644 --- a/core/java/android/service/dreams/IDreamManager.aidl +++ b/core/java/android/service/dreams/IDreamManager.aidl @@ -30,5 +30,5 @@ interface IDreamManager { ComponentName getDefaultDreamComponent(); void testDream(in ComponentName componentName); boolean isDreaming(); - void awakenSelf(in IBinder token); + void finishSelf(in IBinder token); }
\ No newline at end of file diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java index c703aaf..b64a06e 100644 --- a/core/java/android/view/GLES20Canvas.java +++ b/core/java/android/view/GLES20Canvas.java @@ -166,6 +166,7 @@ class GLES20Canvas extends HardwareCanvas { static native void nSetLayerColorFilter(int layerId, int nativeColorFilter); static native void nUpdateTextureLayer(int layerId, int width, int height, boolean opaque, SurfaceTexture surface); + static native void nClearLayerTexture(int layerId); static native void nSetTextureLayerTransform(int layerId, int matrix); static native void nDestroyLayer(int layerId); static native void nDestroyLayerDeferred(int layerId); diff --git a/core/java/android/view/GLES20Layer.java b/core/java/android/view/GLES20Layer.java index a462ed6..812fb97 100644 --- a/core/java/android/view/GLES20Layer.java +++ b/core/java/android/view/GLES20Layer.java @@ -66,6 +66,11 @@ abstract class GLES20Layer extends HardwareLayer { mLayer = 0; } + @Override + void clearStorage() { + if (mLayer != 0) GLES20Canvas.nClearLayerTexture(mLayer); + } + static class Finalizer { private int mLayerId; diff --git a/core/java/android/view/GLES20TextureLayer.java b/core/java/android/view/GLES20TextureLayer.java index 797c734..e863e49 100644 --- a/core/java/android/view/GLES20TextureLayer.java +++ b/core/java/android/view/GLES20TextureLayer.java @@ -39,7 +39,7 @@ class GLES20TextureLayer extends GLES20Layer { mFinalizer = new Finalizer(mLayer); } else { mFinalizer = null; - } + } } @Override diff --git a/core/java/android/view/HardwareLayer.java b/core/java/android/view/HardwareLayer.java index d6868ca..d3bc35a 100644 --- a/core/java/android/view/HardwareLayer.java +++ b/core/java/android/view/HardwareLayer.java @@ -204,4 +204,9 @@ abstract class HardwareLayer { * @param dirtyRect The dirty region of the layer that needs to be redrawn */ abstract void redrawLater(DisplayList displayList, Rect dirtyRect); + + /** + * Indicates that this layer has lost its underlying storage. + */ + abstract void clearStorage(); } diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java index bafab21..28763b3 100644 --- a/core/java/android/view/HardwareRenderer.java +++ b/core/java/android/view/HardwareRenderer.java @@ -21,6 +21,7 @@ import android.content.ComponentCallbacks2; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.SurfaceTexture; +import android.opengl.EGL14; import android.opengl.GLUtils; import android.opengl.ManagedEGLContext; import android.os.Handler; @@ -608,12 +609,6 @@ public abstract class HardwareRenderer { @SuppressWarnings({"deprecation"}) static abstract class GlRenderer extends HardwareRenderer { - // These values are not exposed in our EGL APIs - static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098; - static final int EGL_OPENGL_ES2_BIT = 4; - static final int EGL_SURFACE_TYPE = 0x3033; - static final int EGL_SWAP_BEHAVIOR_PRESERVED_BIT = 0x0400; - static final int SURFACE_STATE_ERROR = 0; static final int SURFACE_STATE_SUCCESS = 1; static final int SURFACE_STATE_UPDATED = 2; @@ -953,19 +948,8 @@ public abstract class HardwareRenderer { return null; } - /* - * Before we can issue GL commands, we need to make sure - * the context is current and bound to a surface. - */ - if (!sEgl.eglMakeCurrent(sEglDisplay, mEglSurface, mEglSurface, mEglContext)) { - throw new Surface.OutOfResourcesException("eglMakeCurrent failed " - + GLUtils.getEGLErrorString(sEgl.eglGetError())); - } - initCaches(); - enableDirtyRegions(); - return mEglContext.getGL(); } @@ -990,10 +974,17 @@ public abstract class HardwareRenderer { abstract void initCaches(); EGLContext createContext(EGL10 egl, EGLDisplay eglDisplay, EGLConfig eglConfig) { - int[] attribs = { EGL_CONTEXT_CLIENT_VERSION, mGlVersion, EGL_NONE }; - - return egl.eglCreateContext(eglDisplay, eglConfig, EGL_NO_CONTEXT, - mGlVersion != 0 ? attribs : null); + int[] attribs = { EGL14.EGL_CONTEXT_CLIENT_VERSION, mGlVersion, EGL_NONE }; + + EGLContext context = egl.eglCreateContext(eglDisplay, eglConfig, EGL_NO_CONTEXT, + mGlVersion != 0 ? attribs : null); + if (context == null || context == EGL_NO_CONTEXT) { + //noinspection ConstantConditions + throw new IllegalStateException( + "Could not create an EGL context. eglCreateContext failed with error: " + + GLUtils.getEGLErrorString(sEgl.eglGetError())); + } + return context; } @Override @@ -1059,6 +1050,14 @@ public abstract class HardwareRenderer { throw new RuntimeException("createWindowSurface failed " + GLUtils.getEGLErrorString(error)); } + + if (!sEgl.eglMakeCurrent(sEglDisplay, mEglSurface, mEglSurface, mEglContext)) { + throw new IllegalStateException("eglMakeCurrent failed " + + GLUtils.getEGLErrorString(sEgl.eglGetError())); + } + + enableDirtyRegions(); + return true; } @@ -1423,7 +1422,7 @@ public abstract class HardwareRenderer { @Override int[] getConfig(boolean dirtyRegions) { return new int[] { - EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + EGL_RENDERABLE_TYPE, EGL14.EGL_OPENGL_ES2_BIT, EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, @@ -1432,7 +1431,7 @@ public abstract class HardwareRenderer { // TODO: Find a better way to choose the stencil size EGL_STENCIL_SIZE, mShowOverdraw ? GLES20Canvas.getStencilSize() : 0, EGL_SURFACE_TYPE, EGL_WINDOW_BIT | - (dirtyRegions ? EGL_SWAP_BEHAVIOR_PRESERVED_BIT : 0), + (dirtyRegions ? EGL14.EGL_SWAP_BEHAVIOR_PRESERVED_BIT : 0), EGL_NONE }; } diff --git a/core/java/android/view/ScaleGestureDetector.java b/core/java/android/view/ScaleGestureDetector.java index fa03139..b0a2711 100644 --- a/core/java/android/view/ScaleGestureDetector.java +++ b/core/java/android/view/ScaleGestureDetector.java @@ -17,8 +17,11 @@ package android.view; import android.content.Context; +import android.os.SystemClock; import android.util.FloatMath; +import java.util.Arrays; + /** * Detects scaling transformation gestures using the supplied {@link MotionEvent}s. * The {@link OnScaleGestureListener} callback will notify users when a particular @@ -139,6 +142,12 @@ public class ScaleGestureDetector { private int mSpanSlop; private int mMinSpan; + private float[] mTouchHistoryLastAccepted; + private int[] mTouchHistoryDirection; + private long[] mTouchHistoryLastAcceptedTime; + + private static final long TOUCH_STABILIZE_TIME = 128; // ms + /** * Consistency verifier for debugging purposes. */ @@ -155,6 +164,120 @@ public class ScaleGestureDetector { } /** + * The touchMajor/touchMinor elements of a MotionEvent can flutter/jitter on + * some hardware/driver combos. Smooth it out to get kinder, gentler behavior. + * @param ev MotionEvent to add to the ongoing history + */ + private void addTouchHistory(MotionEvent ev) { + final long currentTime = SystemClock.uptimeMillis(); + final int count = ev.getPointerCount(); + for (int i = 0; i < count; i++) { + final int id = ev.getPointerId(i); + ensureTouchHistorySize(id); + + final boolean hasLastAccepted = !Float.isNaN(mTouchHistoryLastAccepted[id]); + boolean accept = true; + final int historySize = ev.getHistorySize(); + for (int h = 0; h < historySize + 1; h++) { + final float major; + final float minor; + if (h < historySize) { + major = ev.getHistoricalTouchMajor(i, h); + minor = ev.getHistoricalTouchMinor(i, h); + } else { + major = ev.getTouchMajor(i); + minor = ev.getTouchMinor(i); + } + final float avg = (major + minor) / 2; + + if (hasLastAccepted) { + final int directionSig = (int) Math.signum(avg - mTouchHistoryLastAccepted[id]); + if (directionSig != mTouchHistoryDirection[id] || + (directionSig == 0 && mTouchHistoryDirection[id] == 0)) { + mTouchHistoryDirection[id] = directionSig; + final long time = h < historySize ? ev.getHistoricalEventTime(h) + : ev.getEventTime(); + mTouchHistoryLastAcceptedTime[id] = time; + accept = false; + } + if (currentTime - mTouchHistoryLastAcceptedTime[id] < TOUCH_STABILIZE_TIME) { + accept = false; + } + } + } + + if (accept) { + float newAccepted = (ev.getTouchMajor(i) + ev.getTouchMinor(i)) / 2; + if (hasLastAccepted) { + newAccepted = (mTouchHistoryLastAccepted[id] + newAccepted) / 2; + } + mTouchHistoryLastAccepted[id] = newAccepted; + mTouchHistoryDirection[id] = 0; + mTouchHistoryLastAcceptedTime[id] = ev.getEventTime(); + } + } + } + + /** + * Clear out the touch history for a given pointer id. + * @param id pointer id to clear + * @see #addTouchHistory(MotionEvent) + */ + private void removeTouchHistoryForId(int id) { + mTouchHistoryLastAccepted[id] = Float.NaN; + mTouchHistoryDirection[id] = 0; + mTouchHistoryLastAcceptedTime[id] = 0; + } + + /** + * Get the adjusted combined touchMajor/touchMinor value for a given pointer id + * @param id the pointer id of the data to obtain + * @return the adjusted major/minor value for the point at id + * @see #addTouchHistory(MotionEvent) + */ + private float getAdjustedTouchHistory(int id) { + return mTouchHistoryLastAccepted[id]; + } + + /** + * Clear all touch history tracking. Useful in ACTION_CANCEL or ACTION_UP. + * @see #addTouchHistory(MotionEvent) + */ + private void clearTouchHistory() { + Arrays.fill(mTouchHistoryLastAccepted, Float.NaN); + Arrays.fill(mTouchHistoryDirection, 0); + Arrays.fill(mTouchHistoryLastAcceptedTime, 0); + } + + private void ensureTouchHistorySize(int id) { + final int requiredSize = id + 1; + if (mTouchHistoryLastAccepted == null || mTouchHistoryLastAccepted.length < requiredSize) { + final float[] newLastAccepted = new float[requiredSize]; + final int[] newDirection = new int[requiredSize]; + final long[] newLastAcceptedTime = new long[requiredSize]; + + int oldLength = 0; + if (mTouchHistoryLastAccepted != null) { + System.arraycopy(mTouchHistoryLastAccepted, 0, newLastAccepted, 0, + mTouchHistoryLastAccepted.length); + System.arraycopy(mTouchHistoryDirection, 0, newDirection, 0, + mTouchHistoryDirection.length); + System.arraycopy(mTouchHistoryLastAcceptedTime, 0, newLastAcceptedTime, 0, + mTouchHistoryLastAcceptedTime.length); + oldLength = mTouchHistoryLastAccepted.length; + } + + Arrays.fill(newLastAccepted, oldLength, newLastAccepted.length, Float.NaN); + Arrays.fill(newDirection, oldLength, newDirection.length, 0); + Arrays.fill(newLastAcceptedTime, oldLength, newLastAcceptedTime.length, 0); + + mTouchHistoryLastAccepted = newLastAccepted; + mTouchHistoryDirection = newDirection; + mTouchHistoryLastAcceptedTime = newLastAcceptedTime; + } + } + + /** * Accepts MotionEvents and dispatches events to a {@link OnScaleGestureListener} * when appropriate. * @@ -186,11 +309,12 @@ public class ScaleGestureDetector { } if (streamComplete) { + clearTouchHistory(); return true; } } - final boolean configChanged = + final boolean configChanged = action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_POINTER_UP || action == MotionEvent.ACTION_POINTER_DOWN; final boolean pointerUp = action == MotionEvent.ACTION_POINTER_UP; @@ -208,13 +332,19 @@ public class ScaleGestureDetector { final float focusX = sumX / div; final float focusY = sumY / div; + if (pointerUp) { + removeTouchHistoryForId(event.getPointerId(event.getActionIndex())); + } else { + addTouchHistory(event); + } + // Determine average deviation from focal point float devSumX = 0, devSumY = 0; for (int i = 0; i < count; i++) { if (skipIndex == i) continue; // Average touch major and touch minor and convert the resulting diameter into a radius. - final float touchSize = (event.getTouchMajor(i) + event.getTouchMinor(i)) / 4; + final float touchSize = getAdjustedTouchHistory(event.getPointerId(i)) / 2; devSumX += Math.abs(event.getX(i) - focusX) + touchSize; devSumY += Math.abs(event.getY(i) - focusY) + touchSize; } diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index 973c7f6..0d16dd3 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -46,13 +46,18 @@ import java.util.concurrent.locks.ReentrantLock; * * <p>The surface is Z ordered so that it is behind the window holding its * SurfaceView; the SurfaceView punches a hole in its window to allow its - * surface to be displayed. The view hierarchy will take care of correctly + * surface to be displayed. The view hierarchy will take care of correctly * compositing with the Surface any siblings of the SurfaceView that would - * normally appear on top of it. This can be used to place overlays such as + * normally appear on top of it. This can be used to place overlays such as * buttons on top of the Surface, though note however that it can have an * impact on performance since a full alpha-blended composite will be performed * each time the Surface changes. * + * <p> The transparent region that makes the surface visible is based on the + * layout positions in the view hierarchy. If the post-layout transform + * properties are used to draw a sibling view on top of the SurfaceView, the + * view may not be properly composited with the surface. + * * <p>Access to the underlying surface is provided via the SurfaceHolder interface, * which can be retrieved by calling {@link #getHolder}. * @@ -62,14 +67,14 @@ import java.util.concurrent.locks.ReentrantLock; * Surface is created and destroyed as the window is shown and hidden. * * <p>One of the purposes of this class is to provide a surface in which a - * secondary thread can render into the screen. If you are going to use it + * secondary thread can render into the screen. If you are going to use it * this way, you need to be aware of some threading semantics: * * <ul> * <li> All SurfaceView and * {@link SurfaceHolder.Callback SurfaceHolder.Callback} methods will be called * from the thread running the SurfaceView's window (typically the main thread - * of the application). They thus need to correctly synchronize with any + * of the application). They thus need to correctly synchronize with any * state that is also touched by the drawing thread. * <li> You must ensure that the drawing thread only touches the underlying * Surface while it is valid -- between @@ -456,11 +461,12 @@ public class SurfaceView extends View { } if (mWindow == null) { + Display display = getDisplay(); mWindow = new MyWindow(this); mLayout.type = mWindowType; mLayout.gravity = Gravity.START|Gravity.TOP; mSession.addToDisplayWithoutInputChannel(mWindow, mWindow.mSeq, mLayout, - mVisible ? VISIBLE : GONE, Display.DEFAULT_DISPLAY, mContentInsets); + mVisible ? VISIBLE : GONE, display.getDisplayId(), mContentInsets); } boolean realSizeChanged; diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java index 7e335f0..876b7d84 100644 --- a/core/java/android/view/TextureView.java +++ b/core/java/android/view/TextureView.java @@ -224,6 +224,7 @@ public class TextureView extends View { private void destroySurface() { if (mLayer != null) { mSurface.detachFromGLContext(); + mLayer.clearStorage(); boolean shouldRelease = true; if (mListener != null) { diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 30b8b85..111f959 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -2141,6 +2141,20 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ static final int PFLAG2_PADDING_RESOLVED = 0x20000000; + /** + * Flag indicating that the start/end drawables has been resolved into left/right ones. + */ + static final int PFLAG2_DRAWABLE_RESOLVED = 0x40000000; + + /** + * Group of bits indicating that RTL properties resolution is done. + */ + static final int ALL_RTL_PROPERTIES_RESOLVED = PFLAG2_LAYOUT_DIRECTION_RESOLVED | + PFLAG2_TEXT_DIRECTION_RESOLVED | + PFLAG2_TEXT_ALIGNMENT_RESOLVED | + PFLAG2_PADDING_RESOLVED | + PFLAG2_DRAWABLE_RESOLVED; + // There are a couple of flags left in mPrivateFlags2 /* End of masks for mPrivateFlags2 */ @@ -2773,14 +2787,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * {@hide} */ @ViewDebug.ExportedProperty(category = "padding") - protected int mPaddingLeft = UNDEFINED_PADDING; + protected int mPaddingLeft = 0; /** * The right padding in pixels, that is the distance in pixels between the * right edge of this view and the right edge of its content. * {@hide} */ @ViewDebug.ExportedProperty(category = "padding") - protected int mPaddingRight = UNDEFINED_PADDING; + protected int mPaddingRight = 0; /** * The top padding in pixels, that is the distance in pixels between the * top edge of this view and the top edge of its content. @@ -3199,9 +3213,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback, mResources = context != null ? context.getResources() : null; mViewFlags = SOUND_EFFECTS_ENABLED | HAPTIC_FEEDBACK_ENABLED; // Set layout and text direction defaults - mPrivateFlags2 = (LAYOUT_DIRECTION_DEFAULT << PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT) | + mPrivateFlags2 = + (LAYOUT_DIRECTION_DEFAULT << PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT) | (TEXT_DIRECTION_DEFAULT << PFLAG2_TEXT_DIRECTION_MASK_SHIFT) | + (PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT) | (TEXT_ALIGNMENT_DEFAULT << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT) | + (PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT) | (IMPORTANT_FOR_ACCESSIBILITY_DEFAULT << PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_SHIFT); mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); setOverScrollMode(OVER_SCROLL_IF_CONTENT_SCROLLS); @@ -3285,6 +3302,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, int overScrollMode = mOverScrollMode; boolean initializeScrollbars = false; + boolean leftPaddingDefined = false; + boolean rightPaddingDefined = false; + boolean startPaddingDefined = false; + boolean endPaddingDefined = false; + final int targetSdkVersion = context.getApplicationInfo().targetSdkVersion; final int N = a.getIndexCount(); @@ -3298,10 +3320,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback, padding = a.getDimensionPixelSize(attr, -1); mUserPaddingLeftInitial = padding; mUserPaddingRightInitial = padding; + leftPaddingDefined = true; + rightPaddingDefined = true; break; case com.android.internal.R.styleable.View_paddingLeft: leftPadding = a.getDimensionPixelSize(attr, -1); mUserPaddingLeftInitial = leftPadding; + leftPaddingDefined = true; break; case com.android.internal.R.styleable.View_paddingTop: topPadding = a.getDimensionPixelSize(attr, -1); @@ -3309,15 +3334,18 @@ public class View implements Drawable.Callback, KeyEvent.Callback, case com.android.internal.R.styleable.View_paddingRight: rightPadding = a.getDimensionPixelSize(attr, -1); mUserPaddingRightInitial = rightPadding; + rightPaddingDefined = true; break; case com.android.internal.R.styleable.View_paddingBottom: bottomPadding = a.getDimensionPixelSize(attr, -1); break; case com.android.internal.R.styleable.View_paddingStart: startPadding = a.getDimensionPixelSize(attr, UNDEFINED_PADDING); + startPaddingDefined = true; break; case com.android.internal.R.styleable.View_paddingEnd: endPadding = a.getDimensionPixelSize(attr, UNDEFINED_PADDING); + endPaddingDefined = true; break; case com.android.internal.R.styleable.View_scrollX: x = a.getDimensionPixelOffset(attr, 0); @@ -3419,7 +3447,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, break; case com.android.internal.R.styleable.View_layoutDirection: // Clear any layout direction flags (included resolved bits) already set - mPrivateFlags2 &= ~(PFLAG2_LAYOUT_DIRECTION_MASK | PFLAG2_LAYOUT_DIRECTION_RESOLVED_MASK); + mPrivateFlags2 &= + ~(PFLAG2_LAYOUT_DIRECTION_MASK | PFLAG2_LAYOUT_DIRECTION_RESOLVED_MASK); // Set the layout direction flags depending on the value of the attribute final int layoutDirection = a.getInt(attr, -1); final int value = (layoutDirection != -1) ? @@ -3614,16 +3643,30 @@ public class View implements Drawable.Callback, KeyEvent.Callback, mUserPaddingRightInitial = padding; } + // RTL compatibility mode: pre Jelly Bean MR1 case OR no RTL support case. + // left / right padding are used if defined (meaning here nothing to do). If they are not + // defined and start / end padding are defined (e.g. in Frameworks resources), then we use + // start / end and resolve them as left / right (layout direction is not taken into account). + if (isRtlCompatibilityMode()) { + if (!leftPaddingDefined && startPaddingDefined) { + leftPadding = startPadding; + } + if (!rightPaddingDefined && endPaddingDefined) { + rightPadding = endPadding; + } + } + // If the user specified the padding (either with android:padding or // android:paddingLeft/Top/Right/Bottom), use this padding, otherwise // use the default padding or the padding from the background drawable - // (stored at this point in mPadding*) + // (stored at this point in mPadding*). Padding resolution will happen later if + // RTL is supported. mUserPaddingLeftInitial = leftPadding >= 0 ? leftPadding : mPaddingLeft; mUserPaddingRightInitial = rightPadding >= 0 ? rightPadding : mPaddingRight; internalSetPadding( - mUserPaddingLeftInitial != UNDEFINED_PADDING ? mUserPaddingLeftInitial : 0, + mUserPaddingLeftInitial, topPadding >= 0 ? topPadding : mPaddingTop, - mUserPaddingRightInitial != UNDEFINED_PADDING ? mUserPaddingRightInitial : 0, + mUserPaddingRightInitial, bottomPadding >= 0 ? bottomPadding : mPaddingBottom); if (viewFlagMasks != 0) { @@ -4348,13 +4391,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @return Whether any parent scrolled. */ public boolean requestRectangleOnScreen(Rect rectangle, boolean immediate) { - if (mAttachInfo == null) { + if (mParent == null) { return false; } View child = this; - RectF position = mAttachInfo.mTmpTransformRect; + RectF position = (mAttachInfo != null) ? mAttachInfo.mTmpTransformRect : new RectF(); position.set(rectangle); ViewParent parent = mParent; @@ -5772,6 +5815,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * {@link #LAYOUT_DIRECTION_INHERIT} or * {@link #LAYOUT_DIRECTION_LOCALE}. * @attr ref android.R.styleable#View_layoutDirection + * + * @hide */ @ViewDebug.ExportedProperty(category = "layout", mapping = { @ViewDebug.IntToString(from = LAYOUT_DIRECTION_LTR, to = "LTR"), @@ -5779,7 +5824,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, @ViewDebug.IntToString(from = LAYOUT_DIRECTION_INHERIT, to = "INHERIT"), @ViewDebug.IntToString(from = LAYOUT_DIRECTION_LOCALE, to = "LOCALE") }) - private int getRawLayoutDirection() { + public int getRawLayoutDirection() { return (mPrivateFlags2 & PFLAG2_LAYOUT_DIRECTION_MASK) >> PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT; } @@ -5787,10 +5832,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * Set the layout direction for this view. This will propagate a reset of layout direction * resolution to the view's children and resolve layout direction for this view. * - * @param layoutDirection One of {@link #LAYOUT_DIRECTION_LTR}, - * {@link #LAYOUT_DIRECTION_RTL}, - * {@link #LAYOUT_DIRECTION_INHERIT} or - * {@link #LAYOUT_DIRECTION_LOCALE}. + * @param layoutDirection the layout direction to set. Should be one of: + * + * {@link #LAYOUT_DIRECTION_LTR}, + * {@link #LAYOUT_DIRECTION_RTL}, + * {@link #LAYOUT_DIRECTION_INHERIT}, + * {@link #LAYOUT_DIRECTION_LOCALE}. + * + * Resolution will be done if the value is set to LAYOUT_DIRECTION_INHERIT. The resolution + * proceeds up the parent chain of the view to get the value. If there is no parent, then it + * will return the default {@link #LAYOUT_DIRECTION_LTR}. * * @attr ref android.R.styleable#View_layoutDirection */ @@ -5803,11 +5854,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, // Set the new layout direction (filtered) mPrivateFlags2 |= ((layoutDirection << PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT) & PFLAG2_LAYOUT_DIRECTION_MASK); - resolveRtlProperties(); - // Notify changes - onRtlPropertiesChanged(); - // ... and ask for a layout pass - requestLayout(); + // We need to resolve all RTL properties as they all depend on layout direction + resolveRtlPropertiesIfNeeded(); } } @@ -5816,6 +5864,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * * @return {@link #LAYOUT_DIRECTION_RTL} if the layout direction is RTL or returns * {@link #LAYOUT_DIRECTION_LTR} if the layout direction is not RTL. + * + * For compatibility, this will return {@link #LAYOUT_DIRECTION_LTR} if API version + * is lower than {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}. */ @ViewDebug.ExportedProperty(category = "layout", mapping = { @ViewDebug.IntToString(from = LAYOUT_DIRECTION_LTR, to = "RESOLVED_DIRECTION_LTR"), @@ -5827,12 +5878,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, mPrivateFlags2 |= PFLAG2_LAYOUT_DIRECTION_RESOLVED; return LAYOUT_DIRECTION_LTR; } - // The layout direction will be resolved only if needed - if ((mPrivateFlags2 & PFLAG2_LAYOUT_DIRECTION_RESOLVED) != PFLAG2_LAYOUT_DIRECTION_RESOLVED) { - resolveLayoutDirection(); - } - return ((mPrivateFlags2 & PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL) == PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL) ? - LAYOUT_DIRECTION_RTL : LAYOUT_DIRECTION_LTR; + return ((mPrivateFlags2 & PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL) == + PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL) ? LAYOUT_DIRECTION_RTL : LAYOUT_DIRECTION_LTR; } /** @@ -11474,10 +11521,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, jumpDrawablesToCurrentState(); - resolveRtlProperties(); - // Notify changes - onRtlPropertiesChanged(); - clearAccessibilityFocus(); if (isFocused()) { InputMethodManager imm = InputMethodManager.peekInstance(); @@ -11490,25 +11533,41 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** - * Resolve all RTL related properties + * Resolve all RTL related properties. */ - void resolveRtlProperties() { - // Order is important here: LayoutDirection MUST be resolved first... - resolveLayoutDirection(); + void resolveRtlPropertiesIfNeeded() { + if (!needRtlPropertiesResolution()) return; + + // Order is important here: LayoutDirection MUST be resolved first + if (!isLayoutDirectionResolved()) { + resolveLayoutDirection(); + resolveLayoutParams(); + } // ... then we can resolve the others properties depending on the resolved LayoutDirection. - resolveTextDirection(); - resolveTextAlignment(); - resolvePadding(); - resolveLayoutParams(); - resolveDrawables(); + if (!isTextDirectionResolved()) { + resolveTextDirection(); + } + if (!isTextAlignmentResolved()) { + resolveTextAlignment(); + } + if (!isPaddingResolved()) { + resolvePadding(); + } + if (!isDrawablesResolved()) { + resolveDrawables(); + } + requestLayout(); + invalidate(true); + onRtlPropertiesChanged(); } - // Reset resolution of all RTL related properties + // Reset resolution of all RTL related properties. void resetRtlProperties() { resetResolvedLayoutDirection(); resetResolvedTextDirection(); resetResolvedTextAlignment(); resetResolvedPadding(); + resetResolvedDrawables(); } /** @@ -11538,6 +11597,22 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** + * Return true if we are in RTL compatibility mode (either before Jelly Bean MR1 or + * RTL not supported) + */ + private boolean isRtlCompatibilityMode() { + final int targetSdkVersion = getContext().getApplicationInfo().targetSdkVersion; + return targetSdkVersion < JELLY_BEAN_MR1 || !hasRtlSupport(); + } + + /** + * @return true if RTL properties need resolution. + */ + private boolean needRtlPropertiesResolution() { + return (mPrivateFlags2 & ALL_RTL_PROPERTIES_RESOLVED) != ALL_RTL_PROPERTIES_RESOLVED; + } + + /** * Called when any RTL property (layout direction or text direction or text alignment) has * been changed. * @@ -11614,7 +11689,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** - * Reset the resolved layout direction. + * Reset the resolved layout direction. Layout direction will be resolved during a call to + * {@link #onMeasure(int, int)}. * * @hide */ @@ -11624,6 +11700,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** + * @return true if the layout direction is inherited. + * * @hide */ public boolean isLayoutDirectionInherited() { @@ -11631,12 +11709,19 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** + * @return true if layout direction has been resolved. + */ + private boolean isLayoutDirectionResolved() { + return (mPrivateFlags2 & PFLAG2_LAYOUT_DIRECTION_RESOLVED) == PFLAG2_LAYOUT_DIRECTION_RESOLVED; + } + + /** * Return if padding has been resolved * * @hide */ boolean isPaddingResolved() { - return (mPrivateFlags2 & PFLAG2_PADDING_RESOLVED) != 0; + return (mPrivateFlags2 & PFLAG2_PADDING_RESOLVED) == PFLAG2_PADDING_RESOLVED; } /** @@ -11645,26 +11730,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @hide */ public void resolvePadding() { - final int targetSdkVersion = getContext().getApplicationInfo().targetSdkVersion; - if (targetSdkVersion < JELLY_BEAN_MR1 || !hasRtlSupport()) { - // Pre Jelly Bean MR1 case (compatibility mode) OR no RTL support case: - // left / right padding are used if defined. If they are not defined and start / end - // padding are defined (e.g. in Frameworks resources), then we use start / end and - // resolve them as left / right (layout direction is not taken into account). - if (mUserPaddingLeftInitial == UNDEFINED_PADDING && - mUserPaddingStart != UNDEFINED_PADDING) { - mUserPaddingLeft = mUserPaddingStart; - } - if (mUserPaddingRightInitial == UNDEFINED_PADDING && - mUserPaddingEnd != UNDEFINED_PADDING) { - mUserPaddingRight = mUserPaddingEnd; - } - - mUserPaddingBottom = (mUserPaddingBottom >= 0) ? mUserPaddingBottom : mPaddingBottom; - - internalSetPadding(mUserPaddingLeft, mPaddingTop, mUserPaddingRight, - mUserPaddingBottom); - } else { + if (!isRtlCompatibilityMode()) { // Post Jelly Bean MR1 case: we need to take the resolved layout direction into account. // If start / end padding are defined, they will be resolved (hence overriding) to // left / right or right / left depending on the resolved layout direction. @@ -14116,6 +14182,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if (mBackground != null) { mBackground.setLayoutDirection(getLayoutDirection()); } + mPrivateFlags2 |= PFLAG2_DRAWABLE_RESOLVED; onResolveDrawables(getLayoutDirection()); } @@ -14134,6 +14201,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback, public void onResolveDrawables(int layoutDirection) { } + private void resetResolvedDrawables() { + mPrivateFlags2 &= ~PFLAG2_DRAWABLE_RESOLVED; + } + + private boolean isDrawablesResolved() { + return (mPrivateFlags2 & PFLAG2_DRAWABLE_RESOLVED) == PFLAG2_DRAWABLE_RESOLVED; + } + /** * If your view subclass is displaying its own Drawable objects, it should * override this function and return true for any Drawable it is @@ -14403,6 +14478,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, padding = new Rect(); sThreadLocal.set(padding); } + resetResolvedDrawables(); background.setLayoutDirection(getLayoutDirection()); if (background.getPadding(padding)) { resetResolvedPadding(); @@ -15379,9 +15455,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, // first clears the measured dimension flag mPrivateFlags &= ~PFLAG_MEASURED_DIMENSION_SET; - if (!isPaddingResolved()) { - resolvePadding(); - } + resolveRtlPropertiesIfNeeded(); // measure ourselves, this should set the measured dimension flag back onMeasure(widthMeasureSpec, heightMeasureSpec); @@ -16526,6 +16600,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * {@link #TEXT_DIRECTION_LTR}, * {@link #TEXT_DIRECTION_RTL}, * {@link #TEXT_DIRECTION_LOCALE} + * + * Resolution will be done if the value is set to TEXT_DIRECTION_INHERIT. The resolution + * proceeds up the parent chain of the view to get the value. If there is no parent, then it will + * return the default {@link #TEXT_DIRECTION_FIRST_STRONG}. */ public void setTextDirection(int textDirection) { if (getRawTextDirection() != textDirection) { @@ -16534,6 +16612,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, resetResolvedTextDirection(); // Set the new text direction mPrivateFlags2 |= ((textDirection << PFLAG2_TEXT_DIRECTION_MASK_SHIFT) & PFLAG2_TEXT_DIRECTION_MASK); + // Do resolution + resolveTextDirection(); // Notify change onRtlPropertiesChanged(); // Refresh @@ -16545,11 +16625,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, /** * Return the resolved text direction. * - * This needs resolution if the value is TEXT_DIRECTION_INHERIT. The resolution matches what has - * been set by {@link #setTextDirection(int)} if it is not TEXT_DIRECTION_INHERIT, otherwise the - * resolution proceeds up the parent chain of the view. If there is no parent, then it will - * return the default {@link #TEXT_DIRECTION_FIRST_STRONG}. - * * @return the resolved text direction. Returns one of: * * {@link #TEXT_DIRECTION_FIRST_STRONG} @@ -16559,10 +16634,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * {@link #TEXT_DIRECTION_LOCALE} */ public int getTextDirection() { - // The text direction will be resolved only if needed - if ((mPrivateFlags2 & PFLAG2_TEXT_DIRECTION_RESOLVED) != PFLAG2_TEXT_DIRECTION_RESOLVED) { - resolveTextDirection(); - } return (mPrivateFlags2 & PFLAG2_TEXT_DIRECTION_RESOLVED_MASK) >> PFLAG2_TEXT_DIRECTION_RESOLVED_MASK_SHIFT; } @@ -16601,6 +16672,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } else { // We cannot do the resolution if there is no parent, so use the default one mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT; + // Resolution will need to happen again later + return; } break; case TEXT_DIRECTION_FIRST_STRONG: @@ -16639,16 +16712,21 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** - * Reset resolved text direction. Text direction can be resolved with a call to - * getTextDirection(). + * Reset resolved text direction. Text direction will be resolved during a call to + * {@link #onMeasure(int, int)}. * * @hide */ public void resetResolvedTextDirection() { + // Reset any previous text direction resolution mPrivateFlags2 &= ~(PFLAG2_TEXT_DIRECTION_RESOLVED | PFLAG2_TEXT_DIRECTION_RESOLVED_MASK); + // Set to default value + mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT; } /** + * @return true if text direction is inherited. + * * @hide */ public boolean isTextDirectionInherited() { @@ -16656,6 +16734,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** + * @return true if text direction is resolved. + */ + private boolean isTextDirectionResolved() { + return (mPrivateFlags2 & PFLAG2_TEXT_DIRECTION_RESOLVED) == PFLAG2_TEXT_DIRECTION_RESOLVED; + } + + /** * Return the value specifying the text alignment or policy that was set with * {@link #setTextAlignment(int)}. * @@ -16697,6 +16782,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * {@link #TEXT_ALIGNMENT_VIEW_START}, * {@link #TEXT_ALIGNMENT_VIEW_END} * + * Resolution will be done if the value is set to TEXT_ALIGNMENT_INHERIT. The resolution + * proceeds up the parent chain of the view to get the value. If there is no parent, then it + * will return the default {@link #TEXT_ALIGNMENT_GRAVITY}. + * * @attr ref android.R.styleable#View_textAlignment */ public void setTextAlignment(int textAlignment) { @@ -16705,7 +16794,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback, mPrivateFlags2 &= ~PFLAG2_TEXT_ALIGNMENT_MASK; resetResolvedTextAlignment(); // Set the new text alignment - mPrivateFlags2 |= ((textAlignment << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT) & PFLAG2_TEXT_ALIGNMENT_MASK); + mPrivateFlags2 |= + ((textAlignment << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT) & PFLAG2_TEXT_ALIGNMENT_MASK); + // Do resolution + resolveTextAlignment(); // Notify change onRtlPropertiesChanged(); // Refresh @@ -16717,10 +16809,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, /** * Return the resolved text alignment. * - * The resolved text alignment. This needs resolution if the value is - * TEXT_ALIGNMENT_INHERIT. The resolution matches {@link #setTextAlignment(int)} if it is - * not TEXT_ALIGNMENT_INHERIT, otherwise resolution proceeds up the parent chain of the view. - * * @return the resolved text alignment. Returns one of: * * {@link #TEXT_ALIGNMENT_GRAVITY}, @@ -16740,11 +16828,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, @ViewDebug.IntToString(from = TEXT_ALIGNMENT_VIEW_END, to = "VIEW_END") }) public int getTextAlignment() { - // If text alignment is not resolved, then resolve it - if ((mPrivateFlags2 & PFLAG2_TEXT_ALIGNMENT_RESOLVED) != PFLAG2_TEXT_ALIGNMENT_RESOLVED) { - resolveTextAlignment(); - } - return (mPrivateFlags2 & PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK) >> PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT; + return (mPrivateFlags2 & PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK) >> + PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT; } /** @@ -16786,6 +16871,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, else { // We cannot do the resolution if there is no parent so use the default mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT; + // Resolution will need to happen again later + return; } break; case TEXT_ALIGNMENT_GRAVITY: @@ -16825,16 +16912,21 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** - * Reset resolved text alignment. + * Reset resolved text alignment. Text alignment will be resolved during a call to + * {@link #onMeasure(int, int)}. * * @hide */ public void resetResolvedTextAlignment() { // Reset any previous text alignment resolution mPrivateFlags2 &= ~(PFLAG2_TEXT_ALIGNMENT_RESOLVED | PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK); + // Set to default + mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT; } /** + * @return true if text alignment is inherited. + * * @hide */ public boolean isTextAlignmentInherited() { @@ -16842,6 +16934,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** + * @return true if text alignment is resolved. + */ + private boolean isTextAlignmentResolved() { + return (mPrivateFlags2 & PFLAG2_TEXT_ALIGNMENT_RESOLVED) == PFLAG2_TEXT_ALIGNMENT_RESOLVED; + } + + /** * Generate a value suitable for use in {@link #setId(int)}. * This value will not collide with ID values generated at build time by aapt for R.id. * diff --git a/core/java/android/view/ViewDebug.java b/core/java/android/view/ViewDebug.java index 1286eb9..c013d85 100644 --- a/core/java/android/view/ViewDebug.java +++ b/core/java/android/view/ViewDebug.java @@ -1178,10 +1178,14 @@ public class ViewDebug { private static void writeValue(BufferedWriter out, Object value) throws IOException { if (value != null) { - String output = value.toString().replace("\n", "\\n"); - out.write(String.valueOf(output.length())); - out.write(","); - out.write(output); + String output = "[EXCEPTION]"; + try { + output = value.toString().replace("\n", "\\n"); + } finally { + out.write(String.valueOf(output.length())); + out.write(","); + out.write(output); + } } else { out.write("4,null"); } diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index 34411ea..41890d6 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -3391,11 +3391,6 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager if (child.hasTransientState()) { childHasTransientStateChanged(child, true); } - - if (child.isLayoutDirectionInherited()) { - child.resetResolvedLayoutDirection(); - child.resolveRtlProperties(); - } } private void addInArray(View child, int index) { @@ -3621,7 +3616,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager childHasTransientStateChanged(view, false); } - view.resetResolvedLayoutDirection(); + view.resetRtlProperties(); onViewRemoved(view); @@ -5261,19 +5256,92 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager * @hide */ @Override + public void resolveLayoutDirection() { + super.resolveLayoutDirection(); + + int count = getChildCount(); + for (int i = 0; i < count; i++) { + final View child = getChildAt(i); + if (child.isLayoutDirectionInherited()) { + child.resolveLayoutDirection(); + } + } + } + + /** + * @hide + */ + @Override + public void resolveTextDirection() { + super.resolveTextDirection(); + + int count = getChildCount(); + for (int i = 0; i < count; i++) { + final View child = getChildAt(i); + if (child.isTextDirectionInherited()) { + child.resolveTextDirection(); + } + } + } + + /** + * @hide + */ + @Override + public void resolveTextAlignment() { + super.resolveTextAlignment(); + + int count = getChildCount(); + for (int i = 0; i < count; i++) { + final View child = getChildAt(i); + if (child.isTextAlignmentInherited()) { + child.resolveTextAlignment(); + } + } + } + + /** + * @hide + */ + @Override public void resetResolvedLayoutDirection() { super.resetResolvedLayoutDirection(); - // Take care of resetting the children resolution too int count = getChildCount(); for (int i = 0; i < count; i++) { final View child = getChildAt(i); if (child.isLayoutDirectionInherited()) { child.resetResolvedLayoutDirection(); } + } + } + + /** + * @hide + */ + @Override + public void resetResolvedTextDirection() { + super.resetResolvedTextDirection(); + + int count = getChildCount(); + for (int i = 0; i < count; i++) { + final View child = getChildAt(i); if (child.isTextDirectionInherited()) { child.resetResolvedTextDirection(); } + } + } + + /** + * @hide + */ + @Override + public void resetResolvedTextAlignment() { + super.resetResolvedTextAlignment(); + + int count = getChildCount(); + for (int i = 0; i < count; i++) { + final View child = getChildAt(i); if (child.isTextAlignmentInherited()) { child.resetResolvedTextAlignment(); } diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 6db40ba..438f792 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -1616,6 +1616,7 @@ public final class ViewRootImpl implements ViewParent, mAttachInfo.mHardwareRenderer.setup(mWidth, mHeight); if (!hwInitialized) { mAttachInfo.mHardwareRenderer.invalidate(mHolder.getSurface()); + mFullRedrawNeeded = true; } } } diff --git a/core/java/android/view/VolumePanel.java b/core/java/android/view/VolumePanel.java index 8315bd7..d7c7f46 100644 --- a/core/java/android/view/VolumePanel.java +++ b/core/java/android/view/VolumePanel.java @@ -699,9 +699,12 @@ public class VolumePanel extends Handler implements OnSeekBarChangeListener, Vie if (sc.seekbarView.getMax() != max) { sc.seekbarView.setMax(max); } + sc.seekbarView.setProgress(index); - if (streamType != mAudioManager.getMasterStreamType() - && streamType != AudioService.STREAM_REMOTE_MUSIC && isMuted(streamType)) { + if (((flags & AudioManager.FLAG_FIXED_VOLUME) != 0) || + (streamType != mAudioManager.getMasterStreamType() && + streamType != AudioService.STREAM_REMOTE_MUSIC && + isMuted(streamType))) { sc.seekbarView.setEnabled(false); } else { sc.seekbarView.setEnabled(true); diff --git a/core/java/android/view/accessibility/IAccessibilityManager.aidl b/core/java/android/view/accessibility/IAccessibilityManager.aidl index 60238627..c3ef54c 100644 --- a/core/java/android/view/accessibility/IAccessibilityManager.aidl +++ b/core/java/android/view/accessibility/IAccessibilityManager.aidl @@ -20,6 +20,7 @@ package android.view.accessibility; import android.accessibilityservice.AccessibilityServiceInfo; import android.accessibilityservice.IAccessibilityServiceConnection; import android.accessibilityservice.IAccessibilityServiceClient; +import android.content.ComponentName; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.IAccessibilityInteractionConnection; @@ -53,4 +54,7 @@ interface IAccessibilityManager { in AccessibilityServiceInfo info); void unregisterUiTestAutomationService(IAccessibilityServiceClient client); + + void temporaryEnableAccessibilityStateUntilKeyguardRemoved(in ComponentName service, + boolean touchExplorationEnabled); } diff --git a/core/java/android/webkit/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java index fea427d..4dbca23 100644 --- a/core/java/android/webkit/BrowserFrame.java +++ b/core/java/android/webkit/BrowserFrame.java @@ -1025,7 +1025,7 @@ class BrowserFrame extends Handler { } private float density() { - return mContext.getResources().getDisplayMetrics().density; + return WebViewCore.getFixedDisplayDensity(mContext); } /** diff --git a/core/java/android/webkit/JniUtil.java b/core/java/android/webkit/JniUtil.java index e3e6092..01a81c4 100644 --- a/core/java/android/webkit/JniUtil.java +++ b/core/java/android/webkit/JniUtil.java @@ -173,8 +173,8 @@ class JniUtil { checkInitialized(); // If the device has not checked in it won't have pulled down the system setting for the // Autofill Url. In that case we will not make autofill server requests. - return Settings.Secure.getString(sContext.getContentResolver(), - Settings.Secure.WEB_AUTOFILL_QUERY_URL); + return Settings.Global.getString(sContext.getContentResolver(), + Settings.Global.WEB_AUTOFILL_QUERY_URL); } private static boolean canSatisfyMemoryAllocation(long bytesRequested) { diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java index be2d863..aa68904 100644 --- a/core/java/android/webkit/WebSettings.java +++ b/core/java/android/webkit/WebSettings.java @@ -367,6 +367,7 @@ public abstract class WebSettings { * internal pattern. Default is true. * * @deprecated This method is now obsolete. + * @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1} */ @Deprecated public void setUseWebViewBackgroundForOverscrollBackground(boolean view) { diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java index 1c47615..d68511c 100644 --- a/core/java/android/webkit/WebViewClassic.java +++ b/core/java/android/webkit/WebViewClassic.java @@ -1664,7 +1664,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc mTouchSlopSquare = slop * slop; slop = configuration.getScaledDoubleTapSlop(); mDoubleTapSlopSquare = slop * slop; - final float density = mContext.getResources().getDisplayMetrics().density; + final float density = WebViewCore.getFixedDisplayDensity(mContext); // use one line height, 16 based on our current default font, for how // far we allow a touch be away from the edge of a link mNavSlop = (int) (16 * density); @@ -1809,7 +1809,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc } /* package */ void adjustDefaultZoomDensity(int zoomDensity) { - final float density = mContext.getResources().getDisplayMetrics().density + final float density = WebViewCore.getFixedDisplayDensity(mContext) * 100 / zoomDensity; updateDefaultZoomDensity(density); } diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java index 33fe834..3fb3ec6 100644 --- a/core/java/android/webkit/WebViewCore.java +++ b/core/java/android/webkit/WebViewCore.java @@ -2479,6 +2479,13 @@ public final class WebViewCore { setupViewport(true); } + static float getFixedDisplayDensity(Context context) { + // We make bad assumptions about multiplying and dividing density by 100, + // force them to be true with this hack + float density = context.getResources().getDisplayMetrics().density; + return ((int) (density * 100)) / 100.0f; + } + private void setupViewport(boolean updateViewState) { if (mWebViewClassic == null || mSettings == null) { // We've been destroyed or are being destroyed, return early @@ -2523,14 +2530,13 @@ public final class WebViewCore { // adjust the default scale to match the densityDpi float adjust = 1.0f; if (mViewportDensityDpi == -1) { - adjust = mContext.getResources().getDisplayMetrics().density; + adjust = getFixedDisplayDensity(mContext); } else if (mViewportDensityDpi > 0) { adjust = (float) mContext.getResources().getDisplayMetrics().densityDpi / mViewportDensityDpi; + adjust = ((int) (adjust * 100)) / 100.0f; } - // We make bad assumptions about multiplying and dividing by 100, force - // them to be true with this hack - adjust = ((int) (adjust * 100)) / 100.0f; + // Remove any update density messages in flight. // If the density is indeed different from WebView's default scale, // a new message will be queued. diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index 920d44f..7f0af09 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -65,6 +65,7 @@ import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputConnection; import android.view.inputmethod.InputConnectionWrapper; import android.view.inputmethod.InputMethodManager; +import android.widget.RemoteViews.OnClickHandler; import com.android.internal.R; @@ -675,6 +676,14 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te static final Interpolator sLinearInterpolator = new LinearInterpolator(); /** + * The saved state that we will be restoring from when we next sync. + * Kept here so that if we happen to be asked to save our state before + * the sync happens, we can return this existing data rather than losing + * it. + */ + private SavedState mPendingSync; + + /** * Interface definition for a callback to be invoked when the list or grid * has been scrolled. */ @@ -1612,6 +1621,21 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te SavedState ss = new SavedState(superState); + if (mPendingSync != null) { + // Just keep what we last restored. + ss.selectedId = mPendingSync.selectedId; + ss.firstId = mPendingSync.firstId; + ss.viewTop = mPendingSync.viewTop; + ss.position = mPendingSync.position; + ss.height = mPendingSync.height; + ss.filter = mPendingSync.filter; + ss.inActionMode = mPendingSync.inActionMode; + ss.checkedItemCount = mPendingSync.checkedItemCount; + ss.checkState = mPendingSync.checkState; + ss.checkIdState = mPendingSync.checkIdState; + return ss; + } + boolean haveChildren = getChildCount() > 0 && mItemCount > 0; long selectedId = getSelectedItemId(); ss.selectedId = selectedId; @@ -1692,6 +1716,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te if (ss.selectedId >= 0) { mNeedSync = true; + mPendingSync = ss; mSyncRowId = ss.selectedId; mSyncPosition = ss.position; mSpecificTop = ss.viewTop; @@ -1702,6 +1727,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te setNextSelectedPositionInt(INVALID_POSITION); mSelectorPosition = INVALID_POSITION; mNeedSync = true; + mPendingSync = ss; mSyncRowId = ss.firstId; mSyncPosition = ss.position; mSpecificTop = ss.viewTop; @@ -1803,6 +1829,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te mDataChanged = false; mPositionScrollAfterLayout = null; mNeedSync = false; + mPendingSync = null; mOldSelectedPosition = INVALID_POSITION; mOldSelectedRowId = INVALID_ROW_ID; setSelectedPositionInt(INVALID_POSITION); @@ -5209,6 +5236,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te if (mNeedSync) { // Update this first, since setNextSelectedPositionInt inspects it mNeedSync = false; + mPendingSync = null; if (mTranscriptMode == TRANSCRIPT_MODE_ALWAYS_SCROLL) { mLayoutMode = LAYOUT_FORCE_BOTTOM; @@ -5324,6 +5352,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te mNextSelectedPosition = INVALID_POSITION; mNextSelectedRowId = INVALID_ROW_ID; mNeedSync = false; + mPendingSync = null; mSelectorPosition = INVALID_POSITION; checkSelectionChanged(); } @@ -5847,6 +5876,21 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } /** + * Sets up the onClickHandler to be used by the RemoteViewsAdapter when inflating RemoteViews + * + * @param handler The OnClickHandler to use when inflating RemoteViews. + * + * @hide + */ + public void setRemoteViewsOnClickHandler(OnClickHandler handler) { + // Ensure that we don't already have a RemoteViewsAdapter that is bound to an existing + // service handling the specified intent. + if (mRemoteAdapter != null) { + mRemoteAdapter.setRemoteViewsOnClickHandler(handler); + } + } + + /** * This defers a notifyDataSetChanged on the pending RemoteViewsAdapter if it has not * connected yet. */ diff --git a/core/java/android/widget/AdapterViewAnimator.java b/core/java/android/widget/AdapterViewAnimator.java index 2266cea..90e949a 100644 --- a/core/java/android/widget/AdapterViewAnimator.java +++ b/core/java/android/widget/AdapterViewAnimator.java @@ -31,6 +31,7 @@ import android.view.ViewConfiguration; import android.view.ViewGroup; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityNodeInfo; +import android.widget.RemoteViews.OnClickHandler; import java.util.ArrayList; import java.util.HashMap; @@ -992,6 +993,21 @@ public abstract class AdapterViewAnimator extends AdapterView<Adapter> } } + /** + * Sets up the onClickHandler to be used by the RemoteViewsAdapter when inflating RemoteViews + * + * @param handler The OnClickHandler to use when inflating RemoteViews. + * + * @hide + */ + public void setRemoteViewsOnClickHandler(OnClickHandler handler) { + // Ensure that we don't already have a RemoteViewsAdapter that is bound to an existing + // service handling the specified intent. + if (mRemoteViewsAdapter != null) { + mRemoteViewsAdapter.setRemoteViewsOnClickHandler(handler); + } + } + @Override public void setSelection(int position) { setDisplayedChild(position); diff --git a/core/java/android/widget/AnalogClock.java b/core/java/android/widget/AnalogClock.java index 63a0870..c7da818 100644 --- a/core/java/android/widget/AnalogClock.java +++ b/core/java/android/widget/AnalogClock.java @@ -36,6 +36,10 @@ import java.util.TimeZone; /** * This widget display an analogic clock with two hands for hours and * minutes. + * + * @attr ref android.R.styleable#AnalogClock_dial + * @attr ref android.R.styleable#AnalogClock_hand_hour + * @attr ref android.R.styleable#AnalogClock_hand_minute */ @RemoteView public class AnalogClock extends View { diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java index 6afaba3..ea50e2e 100644 --- a/core/java/android/widget/ProgressBar.java +++ b/core/java/android/widget/ProgressBar.java @@ -354,7 +354,7 @@ public class ProgressBar extends View { Shader.TileMode.REPEAT, Shader.TileMode.CLAMP); shapeDrawable.getPaint().setShader(bitmapShader); - return (clip) ? new ClipDrawable(shapeDrawable, Gravity.START, + return (clip) ? new ClipDrawable(shapeDrawable, Gravity.LEFT, ClipDrawable.HORIZONTAL) : shapeDrawable; } @@ -1040,6 +1040,11 @@ public class ProgressBar extends View { } } } + if (isLayoutRtl()) { + int tempLeft = left; + left = w - right; + right = w - tempLeft; + } mIndeterminateDrawable.setBounds(left, top, right, bottom); } @@ -1057,7 +1062,12 @@ public class ProgressBar extends View { // Translate canvas so a indeterminate circular progress bar with padding // rotates properly in its animation canvas.save(); - canvas.translate(mPaddingLeft, mPaddingTop); + if(isLayoutRtl()) { + canvas.translate(getWidth() - mPaddingRight, mPaddingTop); + canvas.scale(-1.0f, 1.0f); + } else { + canvas.translate(mPaddingLeft, mPaddingTop); + } long time = getDrawingTime(); if (mHasAnimation) { mAnimation.getTransformation(time, mTransformation); diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java index 90f55bf..8d83774 100644 --- a/core/java/android/widget/RemoteViews.java +++ b/core/java/android/widget/RemoteViews.java @@ -237,12 +237,11 @@ public class RemoteViews implements Parcelable, Filter { * @hide */ public void mergeRemoteViews(RemoteViews newRv) { + if (newRv == null) return; // We first copy the new RemoteViews, as the process of merging modifies the way the actions // reference the bitmap cache. We don't want to modify the object as it may need to // be merged and applied multiple times. - Parcel p = Parcel.obtain(); - newRv.writeToParcel(p, 0); - RemoteViews copy = new RemoteViews(p); + RemoteViews copy = newRv.clone(); HashMap<String, Action> map = new HashMap<String, Action>(); if (mActions == null) { @@ -261,7 +260,7 @@ public class RemoteViews implements Parcelable, Filter { for (int i = 0; i < count; i++) { Action a = newActions.get(i); String key = newActions.get(i).getUniqueKey(); - int mergeBehavior = map.get(key).mergeBehavior(); + int mergeBehavior = newActions.get(i).mergeBehavior(); if (map.containsKey(key) && mergeBehavior == Action.MERGE_REPLACE) { mActions.remove(map.get(key)); map.remove(key); @@ -530,9 +529,11 @@ public class RemoteViews implements Parcelable, Filter { if (target instanceof AbsListView) { AbsListView v = (AbsListView) target; v.setRemoteViewsAdapter(intent); + v.setRemoteViewsOnClickHandler(handler); } else if (target instanceof AdapterViewAnimator) { AdapterViewAnimator v = (AdapterViewAnimator) target; v.setRemoteViewsAdapter(intent); + v.setRemoteViewsOnClickHandler(handler); } } @@ -1579,23 +1580,12 @@ public class RemoteViews implements Parcelable, Filter { recalculateMemoryUsage(); } - @Override - public RemoteViews clone() { - RemoteViews that; - if (!hasLandscapeAndPortraitLayouts()) { - that = new RemoteViews(mPackage, mLayoutId); - if (mActions != null) { - that.mActions = (ArrayList<Action>)mActions.clone(); - } - } else { - RemoteViews land = mLandscape.clone(); - RemoteViews port = mPortrait.clone(); - that = new RemoteViews(land, port); - } - // update the memory usage stats of the cloned RemoteViews - that.recalculateMemoryUsage(); - return that; + public RemoteViews clone() { + Parcel p = Parcel.obtain(); + writeToParcel(p, 0); + p.setDataPosition(0); + return new RemoteViews(p); } public String getPackage() { @@ -2166,6 +2156,8 @@ public class RemoteViews implements Parcelable, Filter { * @param value The value to pass to the method. */ public void setUri(int viewId, String methodName, Uri value) { + // Resolve any filesystem path before sending remotely + value = value.getCanonicalUri(); addAction(new ReflectionAction(viewId, methodName, ReflectionAction.URI, value)); } diff --git a/core/java/android/widget/RemoteViewsAdapter.java b/core/java/android/widget/RemoteViewsAdapter.java index f0109ce..e481702 100644 --- a/core/java/android/widget/RemoteViewsAdapter.java +++ b/core/java/android/widget/RemoteViewsAdapter.java @@ -36,6 +36,7 @@ import android.view.LayoutInflater; import android.view.View; import android.view.View.MeasureSpec; import android.view.ViewGroup; +import android.widget.RemoteViews.OnClickHandler; import com.android.internal.widget.IRemoteViewsAdapterConnection; import com.android.internal.widget.IRemoteViewsFactory; @@ -68,6 +69,7 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback private LayoutInflater mLayoutInflater; private RemoteViewsAdapterServiceConnection mServiceConnection; private WeakReference<RemoteAdapterConnectionCallback> mCallback; + private OnClickHandler mRemoteViewsOnClickHandler; private FixedSizeRemoteViewsCache mCache; private int mVisibleWindowLowerBound; private int mVisibleWindowUpperBound; @@ -277,11 +279,11 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback * @param view the RemoteViews that was loaded. If null, the RemoteViews was not loaded * successfully. */ - public void onRemoteViewsLoaded(RemoteViews view) { + public void onRemoteViewsLoaded(RemoteViews view, OnClickHandler handler) { try { // Remove all the children of this layout first removeAllViews(); - addView(view.apply(getContext(), this)); + addView(view.apply(getContext(), this, handler)); } catch (Exception e) { Log.e(TAG, "Failed to apply RemoteViews."); } @@ -330,7 +332,7 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback // Notify all the references for that position of the newly loaded RemoteViews final LinkedList<RemoteViewsFrameLayout> refs = mReferences.get(pos); for (final RemoteViewsFrameLayout ref : refs) { - ref.onRemoteViewsLoaded(view); + ref.onRemoteViewsLoaded(view, mRemoteViewsOnClickHandler); } refs.clear(); @@ -421,7 +423,8 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback } private RemoteViewsFrameLayout createLoadingView(int position, View convertView, - ViewGroup parent, Object lock, LayoutInflater layoutInflater) { + ViewGroup parent, Object lock, LayoutInflater layoutInflater, OnClickHandler + handler) { // Create and return a new FrameLayout, and setup the references for this position final Context context = parent.getContext(); RemoteViewsFrameLayout layout = new RemoteViewsFrameLayout(context); @@ -433,7 +436,8 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback if (mUserLoadingView != null) { // Try to inflate user-specified loading view try { - View loadingView = mUserLoadingView.apply(parent.getContext(), parent); + View loadingView = mUserLoadingView.apply(parent.getContext(), parent, + handler); loadingView.setTagInternal(com.android.internal.R.id.rowTypeId, new Integer(0)); layout.addView(loadingView); @@ -448,7 +452,7 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback // Use the size of the first row as a guide for the size of the loading view if (mFirstViewHeight < 0) { try { - View firstView = mFirstView.apply(parent.getContext(), parent); + View firstView = mFirstView.apply(parent.getContext(), parent, handler); firstView.measure( MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); @@ -815,6 +819,10 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback return mDataReady; } + public void setRemoteViewsOnClickHandler(OnClickHandler handler) { + mRemoteViewsOnClickHandler = handler; + } + public void saveRemoteViewsCache() { final Pair<Intent.FilterComparison, Integer> key = new Pair<Intent.FilterComparison, Integer> (new Intent.FilterComparison(mIntent), mAppWidgetId); @@ -1102,7 +1110,7 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback // Reuse the convert view where possible if (layout != null) { if (convertViewTypeId == typeId) { - rv.reapply(context, convertViewChild); + rv.reapply(context, convertViewChild, mRemoteViewsOnClickHandler); return layout; } layout.removeAllViews(); @@ -1111,7 +1119,7 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback } // Otherwise, create a new view to be returned - View newView = rv.apply(context, parent); + View newView = rv.apply(context, parent, mRemoteViewsOnClickHandler); newView.setTagInternal(com.android.internal.R.id.rowTypeId, new Integer(typeId)); layout.addView(newView); @@ -1127,7 +1135,7 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback final RemoteViewsMetaData metaData = mCache.getMetaData(); synchronized (metaData) { loadingView = metaData.createLoadingView(position, convertView, parent, - mCache, mLayoutInflater); + mCache, mLayoutInflater, mRemoteViewsOnClickHandler); } return loadingView; } finally { @@ -1140,7 +1148,7 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback final RemoteViewsMetaData metaData = mCache.getMetaData(); synchronized (metaData) { loadingView = metaData.createLoadingView(position, convertView, parent, - mCache, mLayoutInflater); + mCache, mLayoutInflater, mRemoteViewsOnClickHandler); } mRequestedViews.add(position, loadingView); diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java index bffbe11..4ad0819 100644 --- a/core/java/com/android/internal/app/ResolverActivity.java +++ b/core/java/com/android/internal/app/ResolverActivity.java @@ -436,9 +436,10 @@ public class ResolverActivity extends AlertActivity implements AdapterView.OnIte if (mBaseResolveList != null) { mCurrentResolveList = mBaseResolveList; } else { - mCurrentResolveList = mPm.queryIntentActivities( + mCurrentResolveList = mPm.queryIntentActivitiesAsUser( mIntent, PackageManager.MATCH_DEFAULT_ONLY - | (mAlwaysUseOption ? PackageManager.GET_RESOLVED_FILTER : 0)); + | (mAlwaysUseOption ? PackageManager.GET_RESOLVED_FILTER : 0), + UserHandle.getUserId(mLaunchedFromUid)); // Filter out any activities that the launched uid does not // have permission for. We don't do this when we have an explicit // list of resolved activities, because that only happens when diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl index 294d4c4..780f5b3 100644 --- a/core/java/com/android/internal/statusbar/IStatusBar.aidl +++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl @@ -28,8 +28,9 @@ oneway interface IStatusBar void updateNotification(IBinder key, in StatusBarNotification notification); void removeNotification(IBinder key); void disable(int state); - void animateExpand(); - void animateCollapse(); + void animateExpandNotificationsPanel(); + void animateExpandSettingsPanel(); + void animateCollapsePanels(); void setSystemUiVisibility(int vis, int mask); void topAppWindowChanged(boolean menuVisible); void setImeWindowStatus(in IBinder token, int vis, int backDisposition); diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl index c64f170..600c27a 100644 --- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl +++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl @@ -24,14 +24,15 @@ import com.android.internal.statusbar.StatusBarNotification; /** @hide */ interface IStatusBarService { - void expand(); - void collapse(); + void expandNotificationsPanel(); + void collapsePanels(); void disable(int what, IBinder token, String pkg); void setIcon(String slot, String iconPackage, int iconId, int iconLevel, String contentDescription); void setIconVisibility(String slot, boolean visible); void removeIcon(String slot); void topAppWindowChanged(boolean menuVisible); void setImeWindowStatus(in IBinder token, int vis, int backDisposition); + void expandSettingsPanel(); // ---- Methods below are for use by the status bar policy services ---- // You need the STATUS_BAR_SERVICE permission diff --git a/core/java/com/android/internal/statusbar/StatusBarIcon.java b/core/java/com/android/internal/statusbar/StatusBarIcon.java index 3333c82..e0792cb 100644 --- a/core/java/com/android/internal/statusbar/StatusBarIcon.java +++ b/core/java/com/android/internal/statusbar/StatusBarIcon.java @@ -18,18 +18,21 @@ package com.android.internal.statusbar; import android.os.Parcel; import android.os.Parcelable; +import android.os.UserHandle; public class StatusBarIcon implements Parcelable { public String iconPackage; + public UserHandle user; public int iconId; public int iconLevel; public boolean visible = true; public int number; public CharSequence contentDescription; - public StatusBarIcon(String iconPackage, int iconId, int iconLevel, int number, + public StatusBarIcon(String iconPackage, UserHandle user, int iconId, int iconLevel, int number, CharSequence contentDescription) { this.iconPackage = iconPackage; + this.user = user; this.iconId = iconId; this.iconLevel = iconLevel; this.number = number; @@ -38,15 +41,16 @@ public class StatusBarIcon implements Parcelable { @Override public String toString() { - return "StatusBarIcon(pkg=" + this.iconPackage + " id=0x" + Integer.toHexString(this.iconId) + return "StatusBarIcon(pkg=" + this.iconPackage + "user=" + user.getIdentifier() + + " id=0x" + Integer.toHexString(this.iconId) + " level=" + this.iconLevel + " visible=" + visible + " num=" + this.number + " )"; } @Override public StatusBarIcon clone() { - StatusBarIcon that = new StatusBarIcon(this.iconPackage, this.iconId, this.iconLevel, - this.number, this.contentDescription); + StatusBarIcon that = new StatusBarIcon(this.iconPackage, this.user, this.iconId, + this.iconLevel, this.number, this.contentDescription); that.visible = this.visible; return that; } @@ -60,6 +64,7 @@ public class StatusBarIcon implements Parcelable { public void readFromParcel(Parcel in) { this.iconPackage = in.readString(); + this.user = (UserHandle) in.readParcelable(null); this.iconId = in.readInt(); this.iconLevel = in.readInt(); this.visible = in.readInt() != 0; @@ -69,6 +74,7 @@ public class StatusBarIcon implements Parcelable { public void writeToParcel(Parcel out, int flags) { out.writeString(this.iconPackage); + out.writeParcelable(this.user, 0); out.writeInt(this.iconId); out.writeInt(this.iconLevel); out.writeInt(this.visible ? 1 : 0); diff --git a/core/java/com/android/internal/view/RotationPolicy.java b/core/java/com/android/internal/view/RotationPolicy.java index 98beadb..95130c8 100644 --- a/core/java/com/android/internal/view/RotationPolicy.java +++ b/core/java/com/android/internal/view/RotationPolicy.java @@ -23,6 +23,7 @@ import android.os.AsyncTask; import android.os.Handler; import android.os.RemoteException; import android.os.ServiceManager; +import android.os.UserHandle; import android.provider.Settings; import android.util.Log; import android.view.IWindowManager; @@ -55,16 +56,17 @@ public final class RotationPolicy { */ public static boolean isRotationLockToggleVisible(Context context) { return isRotationLockToggleSupported(context) && - Settings.System.getInt(context.getContentResolver(), - Settings.System.HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY, 0) == 0; + Settings.System.getIntForUser(context.getContentResolver(), + Settings.System.HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY, 0, + UserHandle.USER_CURRENT) == 0; } /** * Returns true if rotation lock is enabled. */ public static boolean isRotationLocked(Context context) { - return Settings.System.getInt(context.getContentResolver(), - Settings.System.ACCELEROMETER_ROTATION, 0) == 0; + return Settings.System.getIntForUser(context.getContentResolver(), + Settings.System.ACCELEROMETER_ROTATION, 0, UserHandle.USER_CURRENT) == 0; } /** @@ -73,8 +75,9 @@ public final class RotationPolicy { * Should be used by the rotation lock toggle. */ public static void setRotationLock(Context context, final boolean enabled) { - Settings.System.putInt(context.getContentResolver(), - Settings.System.HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY, 0); + Settings.System.putIntForUser(context.getContentResolver(), + Settings.System.HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY, 0, + UserHandle.USER_CURRENT); AsyncTask.execute(new Runnable() { @Override @@ -100,8 +103,9 @@ public final class RotationPolicy { * Should be used by Display settings and Accessibility settings. */ public static void setRotationLockForAccessibility(Context context, final boolean enabled) { - Settings.System.putInt(context.getContentResolver(), - Settings.System.HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY, enabled ? 1 : 0); + Settings.System.putIntForUser(context.getContentResolver(), + Settings.System.HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY, enabled ? 1 : 0, + UserHandle.USER_CURRENT); AsyncTask.execute(new Runnable() { @Override @@ -121,16 +125,25 @@ public final class RotationPolicy { } /** - * Registers a listener for rotation policy changes. + * Registers a listener for rotation policy changes affecting the caller's user */ public static void registerRotationPolicyListener(Context context, RotationPolicyListener listener) { + registerRotationPolicyListener(context, listener, UserHandle.getCallingUserId()); + } + + /** + * Registers a listener for rotation policy changes affecting a specific user, + * or USER_ALL for all users. + */ + public static void registerRotationPolicyListener(Context context, + RotationPolicyListener listener, int userHandle) { context.getContentResolver().registerContentObserver(Settings.System.getUriFor( Settings.System.ACCELEROMETER_ROTATION), - false, listener.mObserver); + false, listener.mObserver, userHandle); context.getContentResolver().registerContentObserver(Settings.System.getUriFor( Settings.System.HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY), - false, listener.mObserver); + false, listener.mObserver, userHandle); } /** diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java index 09457cc..84e1d95 100644 --- a/core/java/com/android/internal/widget/LockPatternUtils.java +++ b/core/java/com/android/internal/widget/LockPatternUtils.java @@ -256,9 +256,13 @@ public class LockPatternUtils { * @return Whether the pattern matches the stored one. */ public boolean checkPattern(List<LockPatternView.Cell> pattern) { - int userId = getCurrentOrCallingUserId(); + final int userId = getCurrentOrCallingUserId(); try { - return getLockSettings().checkPattern(patternToHash(pattern), userId); + final boolean matched = getLockSettings().checkPattern(patternToHash(pattern), userId); + if (matched && (userId == UserHandle.USER_OWNER)) { + KeyStore.getInstance().password(patternToString(pattern)); + } + return matched; } catch (RemoteException re) { return true; } @@ -271,9 +275,14 @@ public class LockPatternUtils { * @return Whether the password matches the stored one. */ public boolean checkPassword(String password) { - int userId = getCurrentOrCallingUserId(); + final int userId = getCurrentOrCallingUserId(); try { - return getLockSettings().checkPassword(passwordToHash(password), userId); + final boolean matched = getLockSettings().checkPassword(passwordToHash(password), + userId); + if (matched && (userId == UserHandle.USER_OWNER)) { + KeyStore.getInstance().password(password); + } + return matched; } catch (RemoteException re) { return true; } diff --git a/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java b/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java index 26518eb..f8332c4 100644 --- a/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java +++ b/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java @@ -31,6 +31,7 @@ import android.view.KeyCharacterMap; import android.view.KeyEvent; import android.view.View; import android.view.ViewGroup; +import android.view.ViewGroup.LayoutParams; import android.view.ViewRootImpl; import com.android.internal.R; @@ -55,23 +56,56 @@ public class PasswordEntryKeyboardHelper implements OnKeyboardActionListener { private long[] mVibratePattern; private boolean mEnableHaptics = false; + private static final int NUMERIC = 0; + private static final int QWERTY = 1; + private static final int QWERTY_SHIFTED = 2; + private static final int SYMBOLS = 3; + private static final int SYMBOLS_SHIFTED = 4; + + int mLayouts[] = new int[] { + R.xml.password_kbd_numeric, + R.xml.password_kbd_qwerty, + R.xml.password_kbd_qwerty_shifted, + R.xml.password_kbd_symbols, + R.xml.password_kbd_symbols_shift + }; + + private boolean mUsingScreenWidth; + public PasswordEntryKeyboardHelper(Context context, KeyboardView keyboardView, View targetView) { - this(context, keyboardView, targetView, true); + this(context, keyboardView, targetView, true, null); } public PasswordEntryKeyboardHelper(Context context, KeyboardView keyboardView, View targetView, boolean useFullScreenWidth) { + this(context, keyboardView, targetView, useFullScreenWidth, null); + } + + public PasswordEntryKeyboardHelper(Context context, KeyboardView keyboardView, View targetView, + boolean useFullScreenWidth, int layouts[]) { mContext = context; mTargetView = targetView; mKeyboardView = keyboardView; - if (useFullScreenWidth - || mKeyboardView.getLayoutParams().width == ViewGroup.LayoutParams.MATCH_PARENT) { - createKeyboards(); + mKeyboardView.setOnKeyboardActionListener(this); + mUsingScreenWidth = useFullScreenWidth; + if (layouts != null) { + if (layouts.length != mLayouts.length) { + throw new RuntimeException("Wrong number of layouts"); + } + for (int i = 0; i < mLayouts.length; i++) { + mLayouts[i] = layouts[i]; + } + } + createKeyboards(); + } + + public void createKeyboards() { + LayoutParams lp = mKeyboardView.getLayoutParams(); + if (mUsingScreenWidth || lp.width == ViewGroup.LayoutParams.MATCH_PARENT) { + createKeyboardsWithDefaultWidth(); } else { - createKeyboardsWithSpecificSize(mKeyboardView.getLayoutParams().width, - mKeyboardView.getLayoutParams().height); + createKeyboardsWithSpecificSize(lp.width, lp.height); } - mKeyboardView.setOnKeyboardActionListener(this); } public void setEnableHaptics(boolean enabled) { @@ -82,46 +116,40 @@ public class PasswordEntryKeyboardHelper implements OnKeyboardActionListener { return mKeyboardMode == KEYBOARD_MODE_ALPHA; } - private void createKeyboardsWithSpecificSize(int viewWidth, int viewHeight) { - mNumericKeyboard = new PasswordEntryKeyboard(mContext, R.xml.password_kbd_numeric, - viewWidth, viewHeight); - mQwertyKeyboard = new PasswordEntryKeyboard(mContext, - R.xml.password_kbd_qwerty, R.id.mode_normal, viewWidth, viewHeight); + private void createKeyboardsWithSpecificSize(int width, int height) { + mNumericKeyboard = new PasswordEntryKeyboard(mContext, mLayouts[NUMERIC], width, height); + mQwertyKeyboard = new PasswordEntryKeyboard(mContext, mLayouts[QWERTY], R.id.mode_normal, + width, height); mQwertyKeyboard.enableShiftLock(); - mQwertyKeyboardShifted = new PasswordEntryKeyboard(mContext, - R.xml.password_kbd_qwerty_shifted, - R.id.mode_normal, viewWidth, viewHeight); + mQwertyKeyboardShifted = new PasswordEntryKeyboard(mContext, mLayouts[QWERTY_SHIFTED], + R.id.mode_normal, width, height); mQwertyKeyboardShifted.enableShiftLock(); mQwertyKeyboardShifted.setShifted(true); // always shifted. - mSymbolsKeyboard = new PasswordEntryKeyboard(mContext, R.xml.password_kbd_symbols, - viewWidth, viewHeight); + mSymbolsKeyboard = new PasswordEntryKeyboard(mContext, mLayouts[SYMBOLS], width, height); mSymbolsKeyboard.enableShiftLock(); - mSymbolsKeyboardShifted = new PasswordEntryKeyboard(mContext, - R.xml.password_kbd_symbols_shift, viewWidth, viewHeight); + mSymbolsKeyboardShifted = new PasswordEntryKeyboard(mContext, mLayouts[SYMBOLS_SHIFTED], + width, height); mSymbolsKeyboardShifted.enableShiftLock(); mSymbolsKeyboardShifted.setShifted(true); // always shifted } - private void createKeyboards() { - mNumericKeyboard = new PasswordEntryKeyboard(mContext, R.xml.password_kbd_numeric); - mQwertyKeyboard = new PasswordEntryKeyboard(mContext, - R.xml.password_kbd_qwerty, R.id.mode_normal); + private void createKeyboardsWithDefaultWidth() { + mNumericKeyboard = new PasswordEntryKeyboard(mContext, mLayouts[NUMERIC]); + mQwertyKeyboard = new PasswordEntryKeyboard(mContext, mLayouts[QWERTY], R.id.mode_normal); mQwertyKeyboard.enableShiftLock(); - mQwertyKeyboardShifted = new PasswordEntryKeyboard(mContext, - R.xml.password_kbd_qwerty_shifted, + mQwertyKeyboardShifted = new PasswordEntryKeyboard(mContext, mLayouts[QWERTY_SHIFTED], R.id.mode_normal); mQwertyKeyboardShifted.enableShiftLock(); mQwertyKeyboardShifted.setShifted(true); // always shifted. - mSymbolsKeyboard = new PasswordEntryKeyboard(mContext, R.xml.password_kbd_symbols); + mSymbolsKeyboard = new PasswordEntryKeyboard(mContext, mLayouts[SYMBOLS]); mSymbolsKeyboard.enableShiftLock(); - mSymbolsKeyboardShifted = new PasswordEntryKeyboard(mContext, - R.xml.password_kbd_symbols_shift); + mSymbolsKeyboardShifted = new PasswordEntryKeyboard(mContext, mLayouts[SYMBOLS_SHIFTED]); mSymbolsKeyboardShifted.enableShiftLock(); mSymbolsKeyboardShifted.setShifted(true); // always shifted } |
