diff options
Diffstat (limited to 'core/java')
21 files changed, 275 insertions, 118 deletions
diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java index 5cde65c..03e0c0f 100644 --- a/core/java/android/accounts/AccountManagerService.java +++ b/core/java/android/accounts/AccountManagerService.java @@ -247,7 +247,6 @@ public class AccountManagerService } public void systemReady() { - initUser(UserHandle.USER_OWNER); } private UserManager getUserManager() { diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java index 7492629..67d3930 100644 --- a/core/java/android/app/ActivityManagerNative.java +++ b/core/java/android/app/ActivityManagerNative.java @@ -2809,6 +2809,15 @@ class ActivityManagerProxy implements IActivityManager return success; } + public void clearPendingBackup() throws RemoteException { + Parcel data = Parcel.obtain(); + Parcel reply = Parcel.obtain(); + data.writeInterfaceToken(IActivityManager.descriptor); + mRemote.transact(CLEAR_PENDING_BACKUP_TRANSACTION, data, reply, 0); + reply.recycle(); + data.recycle(); + } + public void backupAgentCreated(String packageName, IBinder agent) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 5f65f08..456d757 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -29,6 +29,7 @@ import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.IPackageManager; import android.content.pm.InstrumentationInfo; +import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.ProviderInfo; @@ -2396,12 +2397,31 @@ public final class ActivityThread { private void handleCreateBackupAgent(CreateBackupAgentData data) { if (DEBUG_BACKUP) Slog.v(TAG, "handleCreateBackupAgent: " + data); + // Sanity check the requested target package's uid against ours + try { + PackageInfo requestedPackage = getPackageManager().getPackageInfo( + data.appInfo.packageName, 0, UserHandle.myUserId()); + if (requestedPackage.applicationInfo.uid != Process.myUid()) { + Slog.w(TAG, "Asked to instantiate non-matching package " + + data.appInfo.packageName); + return; + } + } catch (RemoteException e) { + Slog.e(TAG, "Can't reach package manager", e); + return; + } + // no longer idle; we have backup work to do unscheduleGcIdler(); // instantiate the BackupAgent class named in the manifest LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo); String packageName = packageInfo.mPackageName; + if (packageName == null) { + Slog.d(TAG, "Asked to create backup agent for nonexistent package"); + return; + } + if (mBackupAgents.get(packageName) != null) { Slog.d(TAG, "BackupAgent " + " for " + packageName + " already exists"); diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java index 97250e9..8fc1c86 100644 --- a/core/java/android/app/IActivityManager.java +++ b/core/java/android/app/IActivityManager.java @@ -152,6 +152,7 @@ public interface IActivityManager extends IInterface { public boolean bindBackupAgent(ApplicationInfo appInfo, int backupRestoreMode) throws RemoteException; + public void clearPendingBackup() throws RemoteException; public void backupAgentCreated(String packageName, IBinder agent) throws RemoteException; public void unbindBackupAgent(ApplicationInfo appInfo) throws RemoteException; public void killApplicationProcess(String processName, int uid) throws RemoteException; @@ -619,4 +620,5 @@ public interface IActivityManager extends IInterface { int GET_RUNNING_USER_IDS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+156; int REQUEST_BUG_REPORT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+157; int INPUT_DISPATCHING_TIMED_OUT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+158; + int CLEAR_PENDING_BACKUP_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+159; } diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java index 58df167..bb0c686 100644 --- a/core/java/android/content/SyncManager.java +++ b/core/java/android/content/SyncManager.java @@ -55,6 +55,7 @@ import android.text.format.Time; import android.util.EventLog; import android.util.Log; import android.util.Pair; +import android.util.Slog; import com.android.internal.R; import com.android.internal.util.IndentingPrintWriter; @@ -311,13 +312,10 @@ public class SyncManager { if (userId == UserHandle.USER_NULL) return; if (Intent.ACTION_USER_REMOVED.equals(action)) { - Log.i(TAG, "User removed: u" + userId); onUserRemoved(userId); } else if (Intent.ACTION_USER_STARTING.equals(action)) { - Log.i(TAG, "User starting: u" + userId); onUserStarting(userId); } else if (Intent.ACTION_USER_STOPPING.equals(action)) { - Log.i(TAG, "User stopping: u" + userId); onUserStopping(userId); } } @@ -338,6 +336,10 @@ public class SyncManager { } } + /** + * Should only be created after {@link ContentService#systemReady()} so that + * {@link PackageManager} is ready to query. + */ public SyncManager(Context context, boolean factoryTest) { // Initialize the SyncStorageEngine first, before registering observers // and creating threads and so on; it may fail if the disk is full. @@ -441,9 +443,6 @@ public class SyncManager { UserHandle.ALL, new IntentFilter(AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION), null, null); - - // do this synchronously to ensure we have the accounts before this call returns - onUserStarting(UserHandle.USER_OWNER); } // Pick a random second in a day to seed all periodic syncs diff --git a/core/java/android/content/SyncQueue.java b/core/java/android/content/SyncQueue.java index 14bfc5b..c9a325e 100644 --- a/core/java/android/content/SyncQueue.java +++ b/core/java/android/content/SyncQueue.java @@ -51,8 +51,6 @@ public class SyncQueue { public SyncQueue(SyncStorageEngine syncStorageEngine, final SyncAdaptersCache syncAdapters) { mSyncStorageEngine = syncStorageEngine; mSyncAdapters = syncAdapters; - - addPendingOperations(UserHandle.USER_OWNER); } public void addPendingOperations(int userId) { diff --git a/core/java/android/content/res/TypedArray.java b/core/java/android/content/res/TypedArray.java index 7f3b6b9..2968fbb 100644 --- a/core/java/android/content/res/TypedArray.java +++ b/core/java/android/content/res/TypedArray.java @@ -469,20 +469,13 @@ public class TypedArray { * {@link android.view.ViewGroup}'s layout_width and layout_height * attributes. This is only here for performance reasons; applications * should use {@link #getDimensionPixelSize}. - * + * * @param index Index of the attribute to retrieve. * @param name Textual name of attribute for error reporting. * * @return Attribute dimension value multiplied by the appropriate * metric and truncated to integer pixels. - * - * @throws RuntimeException - * if this TypedArray does not contain an entry for <code>index</code> - * - * @deprecated Use {@link #getLayoutDimension(int, int)} instead. - * */ - @Deprecated public int getLayoutDimension(int index, String name) { index *= AssetManager.STYLE_NUM_ENTRIES; final int[] data = mData; diff --git a/core/java/android/os/AsyncTask.java b/core/java/android/os/AsyncTask.java index 69e1de9..ce5f163 100644 --- a/core/java/android/os/AsyncTask.java +++ b/core/java/android/os/AsyncTask.java @@ -110,7 +110,7 @@ import java.util.concurrent.atomic.AtomicInteger; * <h2>The 4 steps</h2> * <p>When an asynchronous task is executed, the task goes through 4 steps:</p> * <ol> - * <li>{@link #onPreExecute()}, invoked on the UI thread immediately after the task + * <li>{@link #onPreExecute()}, invoked on the UI thread before the task * is executed. This step is normally used to setup the task, for instance by * showing a progress bar in the user interface.</li> * <li>{@link #doInBackground}, invoked on the background thread diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java index 4820c5e..6c9290b 100644 --- a/core/java/android/service/dreams/DreamService.java +++ b/core/java/android/service/dreams/DreamService.java @@ -51,12 +51,17 @@ import com.android.internal.policy.PolicyManager; * an exhibition/lean-back experience.</p> * * <p>The Dream lifecycle is as follows:</p> - * <ul> - * <li>onAttachedToWindow</li> - * <li>onDreamingStarted</li> - * <li>onDreamingStopped</li> - * <li>onDetachedFromWindow</li> - * </ul> + * <ol> + * <li>{@link #onAttachedToWindow} + * <p>Use this for initial setup, such as calling {@link #setContentView setContentView()}.</li> + * <li>{@link #onDreamingStarted} + * <p>Your dream has started, so you should begin animations or other behaviors here.</li> + * <li>{@link #onDreamingStopped} + * <p>Use this to stop the things you started in {@link #onDreamingStarted}.</li> + * <li>{@link #onDetachedFromWindow} + * <p>Use this to dismantle resources your dream set up. For example, detach from handlers + * and listeners.</li> + * </ol> * * <p>In addition, onCreate and onDestroy (from the Service interface) will also be called, but * initialization and teardown should be done by overriding the hooks above.</p> @@ -80,14 +85,40 @@ import com.android.internal.policy.PolicyManager; * android:resource="@xml/my_dream" /> * </service> * </pre> - * <p>If specified, additional information for the dream is defined using the - * <code><{@link android.R.styleable#Dream dream}></code> element. For example:</p> - * <pre> - * (in res/xml/my_dream.xml) * + * <p>If specified with the {@code <meta-data>} element, + * additional information for the dream is defined using the + * {@link android.R.styleable#Dream <dream>} element in a separate XML file. + * Currently, the only addtional + * information you can provide is for a settings activity that allows the user to configure + * the dream behavior. For example:</p> + * <p class="code-caption">res/xml/my_dream.xml</p> + * <pre> * <dream xmlns:android="http://schemas.android.com/apk/res/android" * android:settingsActivity="com.example.app/.MyDreamSettingsActivity" /> * </pre> + * <p>This makes a Settings button available alongside your dream's listing in the + * system settings, which when pressed opens the specified activity.</p> + * + * + * <p>To specify your dream layout, call {@link #setContentView}, typically during the + * {@link #onAttachedToWindow} callback. For example:</p> + * <pre> + * public class MyDream extends DreamService { + * + * @Override + * public void onAttachedToWindow() { + * super.onAttachedToWindow(); + * + * // Exit dream upon user touch + * setInteractive(false); + * // Hide system UI + * setFullscreen(true); + * // Set the dream layout + * setContentView(R.layout.dream); + * } + * } + * </pre> */ public class DreamService extends Service implements Window.Callback { private final String TAG = DreamService.class.getSimpleName() + "[" + getClass().getSimpleName() + "]"; @@ -323,11 +354,12 @@ public class DreamService extends Service implements Window.Callback { /** * Sets a view to be the content view for this Dream. - * Behaves similarly to {@link android.app.Activity#setContentView(android.view.View)}, + * Behaves similarly to {@link android.app.Activity#setContentView(android.view.View)} in an activity, * including using {@link ViewGroup.LayoutParams#MATCH_PARENT} as the layout height and width of the view. * - * <p>Note: Requires a window, do not call before {@link #onAttachedToWindow()}</p> - * @param view The desired content to display. + * <p>Note: This requires a window, so you should usually call it during + * {@link #onAttachedToWindow()} and never earlier (you <strong>cannot</strong> call it + * during {@link #onCreate}).</p> * * @see #setContentView(int) * @see #setContentView(android.view.View, android.view.ViewGroup.LayoutParams) @@ -339,9 +371,12 @@ public class DreamService extends Service implements Window.Callback { /** * Sets a view to be the content view for this Dream. * Behaves similarly to - * {@link android.app.Activity#setContentView(android.view.View, android.view.ViewGroup.LayoutParams)}. + * {@link android.app.Activity#setContentView(android.view.View, android.view.ViewGroup.LayoutParams)} + * in an activity. * - * <p>Note: Requires a window, do not call before {@link #onAttachedToWindow()}</p> + * <p>Note: This requires a window, so you should usually call it during + * {@link #onAttachedToWindow()} and never earlier (you <strong>cannot</strong> call it + * during {@link #onCreate}).</p> * * @param view The desired content to display. * @param params Layout parameters for the view. diff --git a/core/java/android/service/dreams/Sandman.java b/core/java/android/service/dreams/Sandman.java index 70142ce..5f5b079 100644 --- a/core/java/android/service/dreams/Sandman.java +++ b/core/java/android/service/dreams/Sandman.java @@ -36,9 +36,6 @@ import android.util.Slog; public final class Sandman { private static final String TAG = "Sandman"; - private static final int DEFAULT_SCREENSAVER_ENABLED = 1; - private static final int DEFAULT_SCREENSAVER_ACTIVATED_ON_DOCK = 1; - // The component name of a special dock app that merely launches a dream. // We don't want to launch this app when docked because it causes an unnecessary // activity transition. We just want to start the dream. @@ -109,14 +106,18 @@ public final class Sandman { } private static boolean isScreenSaverEnabled(Context context) { + int def = context.getResources().getBoolean( + com.android.internal.R.bool.config_dreamsEnabledByDefault) ? 1 : 0; return Settings.Secure.getIntForUser(context.getContentResolver(), - Settings.Secure.SCREENSAVER_ENABLED, DEFAULT_SCREENSAVER_ENABLED, + Settings.Secure.SCREENSAVER_ENABLED, def, UserHandle.USER_CURRENT) != 0; } private static boolean isScreenSaverActivatedOnDock(Context context) { + int def = context.getResources().getBoolean( + com.android.internal.R.bool.config_dreamsActivatedOnDockByDefault) ? 1 : 0; return Settings.Secure.getIntForUser(context.getContentResolver(), - Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK, - DEFAULT_SCREENSAVER_ACTIVATED_ON_DOCK, UserHandle.USER_CURRENT) != 0; + Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK, def, + UserHandle.USER_CURRENT) != 0; } } diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java index ec1695e..59f941d 100644 --- a/core/java/android/view/HardwareRenderer.java +++ b/core/java/android/view/HardwareRenderer.java @@ -1200,7 +1200,12 @@ public abstract class HardwareRenderer { Trace.traceEnd(Trace.TRACE_TAG_VIEW); } - status = onPreDraw(dirty); + Trace.traceBegin(Trace.TRACE_TAG_VIEW, "prepareFrame"); + try { + status = onPreDraw(dirty); + } finally { + Trace.traceEnd(Trace.TRACE_TAG_VIEW); + } saveCount = canvas.save(); callbacks.onHardwarePreDraw(canvas); diff --git a/core/java/android/view/LayoutInflater.java b/core/java/android/view/LayoutInflater.java index f692e05..26a5b26 100644 --- a/core/java/android/view/LayoutInflater.java +++ b/core/java/android/view/LayoutInflater.java @@ -20,7 +20,6 @@ import android.graphics.Canvas; import android.os.Handler; import android.os.Message; import android.widget.FrameLayout; -import com.android.internal.R; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -44,20 +43,20 @@ import java.util.HashMap; * * <pre>LayoutInflater inflater = (LayoutInflater)context.getSystemService * (Context.LAYOUT_INFLATER_SERVICE);</pre> - * + * * <p> * To create a new LayoutInflater with an additional {@link Factory} for your * own views, you can use {@link #cloneInContext} to clone an existing * ViewFactory, and then call {@link #setFactory} on it to include your * Factory. - * + * * <p> * For performance reasons, view inflation relies heavily on pre-processing of * XML files that is done at build time. Therefore, it is not currently possible * to use LayoutInflater with an XmlPullParser over a plain XML file at runtime; * it only works with an XmlPullParser returned from a compiled resource * (R.<em>something</em> file.) - * + * * @see Context#getSystemService */ public abstract class LayoutInflater { @@ -83,7 +82,7 @@ public abstract class LayoutInflater { private static final HashMap<String, Constructor<? extends View>> sConstructorMap = new HashMap<String, Constructor<? extends View>>(); - + private HashMap<String, Boolean> mFilterMap; private static final String TAG_MERGE = "merge"; @@ -94,36 +93,36 @@ public abstract class LayoutInflater { /** * Hook to allow clients of the LayoutInflater to restrict the set of Views that are allowed * to be inflated. - * + * */ public interface Filter { /** * Hook to allow clients of the LayoutInflater to restrict the set of Views * that are allowed to be inflated. - * + * * @param clazz The class object for the View that is about to be inflated - * + * * @return True if this class is allowed to be inflated, or false otherwise */ @SuppressWarnings("unchecked") boolean onLoadClass(Class clazz); } - + public interface Factory { /** * Hook you can supply that is called when inflating from a LayoutInflater. * You can use this to customize the tag names available in your XML * layout files. - * + * * <p> * Note that it is good practice to prefix these custom names with your * package (i.e., com.coolcompany.apps) to avoid conflicts with system * names. - * + * * @param name Tag name to be inflated. * @param context The context the view is being created in. * @param attrs Inflation attributes as specified in XML file. - * + * * @return View Newly created view. Return null for the default * behavior. */ @@ -151,14 +150,14 @@ public abstract class LayoutInflater { private static class FactoryMerger implements Factory2 { private final Factory mF1, mF2; private final Factory2 mF12, mF22; - + FactoryMerger(Factory f1, Factory2 f12, Factory f2, Factory2 f22) { mF1 = f1; mF2 = f2; mF12 = f12; mF22 = f22; } - + public View onCreateView(String name, Context context, AttributeSet attrs) { View v = mF1.onCreateView(name, context, attrs); if (v != null) return v; @@ -173,13 +172,13 @@ public abstract class LayoutInflater { : mF2.onCreateView(name, context, attrs); } } - + /** * Create a new LayoutInflater instance associated with a particular Context. * Applications will almost always want to use * {@link Context#getSystemService Context.getSystemService()} to retrieve * the standard {@link Context#LAYOUT_INFLATER_SERVICE Context.INFLATER_SERVICE}. - * + * * @param context The Context in which this LayoutInflater will create its * Views; most importantly, this supplies the theme from which the default * values for their attributes are retrieved. @@ -192,7 +191,7 @@ public abstract class LayoutInflater { * Create a new LayoutInflater instance that is a copy of an existing * LayoutInflater, optionally with its Context changed. For use in * implementing {@link #cloneInContext}. - * + * * @param original The original LayoutInflater to copy. * @param newContext The new Context to use. */ @@ -203,7 +202,7 @@ public abstract class LayoutInflater { mPrivateFactory = original.mPrivateFactory; mFilter = original.mFilter; } - + /** * Obtains the LayoutInflater from the given context. */ @@ -221,15 +220,15 @@ public abstract class LayoutInflater { * pointing to a different Context than the original. This is used by * {@link ContextThemeWrapper} to create a new LayoutInflater to go along * with the new Context theme. - * + * * @param newContext The new Context to associate with the new LayoutInflater. * May be the same as the original Context if desired. - * + * * @return Returns a brand spanking new LayoutInflater object associated with * the given Context. */ public abstract LayoutInflater cloneInContext(Context newContext); - + /** * Return the context we are running in, for access to resources, class * loader, etc. @@ -265,7 +264,7 @@ public abstract class LayoutInflater { * called on each element name as the xml is parsed. If the factory returns * a View, that is added to the hierarchy. If it returns null, the next * factory default {@link #onCreateView} method is called. - * + * * <p>If you have an existing * LayoutInflater and want to add your own factory to it, use * {@link #cloneInContext} to clone the existing instance and then you @@ -321,13 +320,13 @@ public abstract class LayoutInflater { public Filter getFilter() { return mFilter; } - + /** * Sets the {@link Filter} to by this LayoutInflater. If a view is attempted to be inflated * which is not allowed by the {@link Filter}, the {@link #inflate(int, ViewGroup)} call will * throw an {@link InflateException}. This filter will replace any previous filter set on this * LayoutInflater. - * + * * @param filter The Filter which restricts the set of Views that are allowed to be inflated. * This filter will replace any previous filter set on this LayoutInflater. */ @@ -341,7 +340,7 @@ public abstract class LayoutInflater { /** * Inflate a new view hierarchy from the specified xml resource. Throws * {@link InflateException} if there is an error. - * + * * @param resource ID for an XML layout resource to load (e.g., * <code>R.layout.main_page</code>) * @param root Optional view to be the parent of the generated hierarchy. @@ -361,7 +360,7 @@ public abstract class LayoutInflater { * reasons, view inflation relies heavily on pre-processing of XML files * that is done at build time. Therefore, it is not currently possible to * use LayoutInflater with an XmlPullParser over a plain XML file at runtime. - * + * * @param parser XML dom node containing the description of the view * hierarchy. * @param root Optional view to be the parent of the generated hierarchy. @@ -376,7 +375,7 @@ public abstract class LayoutInflater { /** * Inflate a new view hierarchy from the specified xml resource. Throws * {@link InflateException} if there is an error. - * + * * @param resource ID for an XML layout resource to load (e.g., * <code>R.layout.main_page</code>) * @param root Optional view to be the parent of the generated hierarchy (if @@ -408,7 +407,7 @@ public abstract class LayoutInflater { * reasons, view inflation relies heavily on pre-processing of XML files * that is done at build time. Therefore, it is not currently possible to * use LayoutInflater with an XmlPullParser over a plain XML file at runtime. - * + * * @param parser XML dom node containing the description of the view * hierarchy. * @param root Optional view to be the parent of the generated hierarchy (if @@ -443,7 +442,7 @@ public abstract class LayoutInflater { } final String name = parser.getName(); - + if (DEBUG) { System.out.println("**************************"); System.out.println("Creating root view: " @@ -529,17 +528,17 @@ public abstract class LayoutInflater { * Low-level function for instantiating a view by name. This attempts to * instantiate a view class of the given <var>name</var> found in this * LayoutInflater's ClassLoader. - * + * * <p> * There are two things that can happen in an error case: either the * exception describing the error will be thrown, or a null will be * returned. You must deal with both possibilities -- the former will happen * the first time createView() is called for a class of a particular name, * the latter every time there-after for that class name. - * + * * @param name The full name of the class to be instantiated. * @param attrs The XML attributes supplied for this instance. - * + * * @return View The newly instantiated view, or null. */ public final View createView(String name, String prefix, AttributeSet attrs) @@ -552,7 +551,7 @@ public abstract class LayoutInflater { // Class not found in the cache, see if it's real, and try to add it clazz = mContext.getClassLoader().loadClass( prefix != null ? (prefix + name) : name).asSubclass(View.class); - + if (mFilter != null && clazz != null) { boolean allowed = mFilter.onLoadClass(clazz); if (!allowed) { @@ -570,7 +569,7 @@ public abstract class LayoutInflater { // New class -- remember whether it is allowed clazz = mContext.getClassLoader().loadClass( prefix != null ? (prefix + name) : name).asSubclass(View.class); - + boolean allowed = clazz != null && mFilter.onLoadClass(clazz); mFilterMap.put(name, allowed); if (!allowed) { @@ -633,10 +632,10 @@ public abstract class LayoutInflater { * given the xml element name. Override it to handle custom view objects. If * you override this in your subclass be sure to call through to * super.onCreateView(name) for names you do not recognize. - * + * * @param name The fully qualified class name of the View to be create. * @param attrs An AttributeSet of attributes to apply to the View. - * + * * @return View The View created. */ protected View onCreateView(String name, AttributeSet attrs) @@ -680,7 +679,7 @@ public abstract class LayoutInflater { if (view == null && mPrivateFactory != null) { view = mPrivateFactory.onCreateView(parent, name, mContext, attrs); } - + if (view == null) { if (-1 == name.indexOf('.')) { view = onCreateView(parent, name, attrs); @@ -727,7 +726,7 @@ public abstract class LayoutInflater { } final String name = parser.getName(); - + if (TAG_REQUEST_FOCUS.equals(name)) { parseRequestFocus(parser, parent); } else if (TAG_INCLUDE.equals(name)) { @@ -742,7 +741,7 @@ public abstract class LayoutInflater { final ViewGroup viewGroup = (ViewGroup) parent; final ViewGroup.LayoutParams params = viewGroup.generateLayoutParams(attrs); rInflate(parser, view, attrs, true); - viewGroup.addView(view, params); + viewGroup.addView(view, params); } else { final View view = createViewFromTag(parent, name, attrs); final ViewGroup viewGroup = (ViewGroup) parent; @@ -811,14 +810,21 @@ public abstract class LayoutInflater { // We try to load the layout params set in the <include /> tag. If // they don't exist, we will rely on the layout params set in the // included XML file. - TypedArray ta = getContext().obtainStyledAttributes(attrs, - R.styleable.ViewGroup_Layout); - boolean definesBothWidthAndHeight = - ta.hasValue(R.styleable.ViewGroup_Layout_layout_width) && - ta.hasValue(R.styleable.ViewGroup_Layout_layout_height); - AttributeSet attributes = definesBothWidthAndHeight ? attrs : childAttrs; - view.setLayoutParams(group.generateLayoutParams(attributes)); - ta.recycle(); + // During a layoutparams generation, a runtime exception is thrown + // if either layout_width or layout_height is missing. We catch + // this exception and set localParams accordingly: true means we + // successfully loaded layout params from the <include /> tag, + // false means we need to rely on the included layout params. + ViewGroup.LayoutParams params = null; + try { + params = group.generateLayoutParams(attrs); + } catch (RuntimeException e) { + params = group.generateLayoutParams(childAttrs); + } finally { + if (params != null) { + view.setLayoutParams(params); + } + } // Inflate all children. rInflate(childParser, view, childAttrs, true); diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index b4ba871..b36db7f 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -10002,8 +10002,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback, /** * Resolve the layout parameters depending on the resolved layout direction + * + * @hide */ - private void resolveLayoutParams() { + public void resolveLayoutParams() { if (mLayoutParams != null) { mLayoutParams.resolveLayoutDirection(getLayoutDirection()); } diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index b95e1bd..dabdf5a 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -5362,6 +5362,19 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager * @hide */ @Override + public void resolveLayoutParams() { + super.resolveLayoutParams(); + int count = getChildCount(); + for (int i = 0; i < count; i++) { + final View child = getChildAt(i); + child.resolveLayoutParams(); + } + } + + /** + * @hide + */ + @Override public void resetRtlProperties() { super.resetRtlProperties(); int count = getChildCount(); @@ -5611,19 +5624,15 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager } /** - * Extracts the <code>width</code> and <code>height</code> layout parameters - * from the supplied TypedArray, <code>a</code>, and assigns them - * to the appropriate fields. If, <code>a</code>, does not contain an - * entry for either attribute, the value, {@link ViewGroup.LayoutParams#WRAP_CONTENT}, - * is used as a default. + * Extracts the layout parameters from the supplied attributes. * * @param a the style attributes to extract the parameters from * @param widthAttr the identifier of the width attribute * @param heightAttr the identifier of the height attribute */ protected void setBaseAttributes(TypedArray a, int widthAttr, int heightAttr) { - width = a.getLayoutDimension(widthAttr, WRAP_CONTENT); - height = a.getLayoutDimension(heightAttr, WRAP_CONTENT); + width = a.getLayoutDimension(widthAttr, "layout_width"); + height = a.getLayoutDimension(heightAttr, "layout_height"); } /** @@ -5981,6 +5990,11 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager */ @Override public void resolveLayoutDirection(int layoutDirection) { + // No need to resolve if it is the same layout direction as before + if (this.layoutDirection == layoutDirection) { + return; + } + setLayoutDirection(layoutDirection); if (!isMarginRelative()) return; diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 02c97ae..8a82a54 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -890,11 +890,13 @@ public final class ViewRootImpl implements ViewParent, // Intersect with the bounds of the window to skip // updates that lie outside of the visible region final float appScale = mAttachInfo.mApplicationScale; - localDirty.intersect(0, 0, - (int) (mWidth * appScale + 0.5f), (int) (mHeight * appScale + 0.5f)); - - if (!mWillDrawSoon) { - scheduleTraversals(); + if (localDirty.intersect(0, 0, + (int) (mWidth * appScale + 0.5f), (int) (mHeight * appScale + 0.5f))) { + if (!mWillDrawSoon) { + scheduleTraversals(); + } + } else { + localDirty.setEmpty(); } return null; diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java index 7855763c..5cdc1ed 100644 --- a/core/java/android/view/WindowManagerGlobal.java +++ b/core/java/android/view/WindowManagerGlobal.java @@ -99,6 +99,7 @@ public final class WindowManagerGlobal { public static final int ADD_STARTING_NOT_NEEDED = -6; public static final int ADD_MULTIPLE_SINGLETON = -7; public static final int ADD_PERMISSION_DENIED = -8; + public static final int ADD_INVALID_DISPLAY = -9; private static WindowManagerGlobal sDefaultWindowManager; private static IWindowManager sWindowManagerService; diff --git a/core/java/android/widget/FrameLayout.java b/core/java/android/widget/FrameLayout.java index 45f30df..e158776 100644 --- a/core/java/android/widget/FrameLayout.java +++ b/core/java/android/widget/FrameLayout.java @@ -608,12 +608,6 @@ public class FrameLayout extends ViewGroup { */ public int gravity = -1; - @Override - protected void setBaseAttributes(TypedArray a, int widthAttr, int heightAttr) { - width = a.getLayoutDimension(widthAttr, MATCH_PARENT); - height = a.getLayoutDimension(heightAttr, MATCH_PARENT); - } - /** * {@inheritDoc} */ diff --git a/core/java/android/widget/RadioGroup.java b/core/java/android/widget/RadioGroup.java index 42d63b2..78d05b0 100644 --- a/core/java/android/widget/RadioGroup.java +++ b/core/java/android/widget/RadioGroup.java @@ -297,6 +297,33 @@ public class RadioGroup extends LinearLayout { public LayoutParams(MarginLayoutParams source) { super(source); } + + /** + * <p>Fixes the child's width to + * {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT} and the child's + * height to {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT} + * when not specified in the XML file.</p> + * + * @param a the styled attributes set + * @param widthAttr the width attribute to fetch + * @param heightAttr the height attribute to fetch + */ + @Override + protected void setBaseAttributes(TypedArray a, + int widthAttr, int heightAttr) { + + if (a.hasValue(widthAttr)) { + width = a.getLayoutDimension(widthAttr, "layout_width"); + } else { + width = WRAP_CONTENT; + } + + if (a.hasValue(heightAttr)) { + height = a.getLayoutDimension(heightAttr, "layout_height"); + } else { + height = WRAP_CONTENT; + } + } } /** diff --git a/core/java/android/widget/TableLayout.java b/core/java/android/widget/TableLayout.java index 113299a..399b4fa 100644 --- a/core/java/android/widget/TableLayout.java +++ b/core/java/android/widget/TableLayout.java @@ -741,9 +741,14 @@ public class TableLayout extends LinearLayout { * @param heightAttr the height attribute to fetch */ @Override - protected void setBaseAttributes(TypedArray a, int widthAttr, int heightAttr) { + protected void setBaseAttributes(TypedArray a, + int widthAttr, int heightAttr) { this.width = MATCH_PARENT; - this.height = a.getLayoutDimension(heightAttr, WRAP_CONTENT); + if (a.hasValue(heightAttr)) { + this.height = a.getLayoutDimension(heightAttr, "layout_height"); + } else { + this.height = WRAP_CONTENT; + } } } diff --git a/core/java/android/widget/TableRow.java b/core/java/android/widget/TableRow.java index 3f8f9dae..68ffd73 100644 --- a/core/java/android/widget/TableRow.java +++ b/core/java/android/widget/TableRow.java @@ -505,8 +505,19 @@ public class TableRow extends LinearLayout { @Override protected void setBaseAttributes(TypedArray a, int widthAttr, int heightAttr) { - width = a.getLayoutDimension(widthAttr, MATCH_PARENT); - height = a.getLayoutDimension(heightAttr, WRAP_CONTENT); + // We don't want to force users to specify a layout_width + if (a.hasValue(widthAttr)) { + width = a.getLayoutDimension(widthAttr, "layout_width"); + } else { + width = MATCH_PARENT; + } + + // We don't want to force users to specify a layout_height + if (a.hasValue(heightAttr)) { + height = a.getLayoutDimension(heightAttr, "layout_height"); + } else { + height = WRAP_CONTENT; + } } } diff --git a/core/java/com/android/internal/net/VpnProfile.java b/core/java/com/android/internal/net/VpnProfile.java index 7287327..c9b7cb3 100644 --- a/core/java/com/android/internal/net/VpnProfile.java +++ b/core/java/com/android/internal/net/VpnProfile.java @@ -70,6 +70,47 @@ public class VpnProfile implements Cloneable, Parcelable { this.key = key; } + public VpnProfile(Parcel in) { + key = in.readString(); + name = in.readString(); + type = in.readInt(); + server = in.readString(); + username = in.readString(); + password = in.readString(); + dnsServers = in.readString(); + searchDomains = in.readString(); + routes = in.readString(); + mppe = in.readInt() != 0; + l2tpSecret = in.readString(); + ipsecIdentifier = in.readString(); + ipsecSecret = in.readString(); + ipsecUserCert = in.readString(); + ipsecCaCert = in.readString(); + ipsecServerCert = in.readString(); + saveLogin = in.readInt() != 0; + } + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeString(key); + out.writeString(name); + out.writeInt(type); + out.writeString(server); + out.writeString(username); + out.writeString(password); + out.writeString(dnsServers); + out.writeString(searchDomains); + out.writeString(routes); + out.writeInt(mppe ? 1 : 0); + out.writeString(l2tpSecret); + out.writeString(ipsecIdentifier); + out.writeString(ipsecSecret); + out.writeString(ipsecUserCert); + out.writeString(ipsecCaCert); + out.writeString(ipsecServerCert); + out.writeInt(saveLogin ? 1 : 0); + } + public static VpnProfile decode(String key, byte[] value) { try { if (key == null) { @@ -155,17 +196,10 @@ public class VpnProfile implements Cloneable, Parcelable { } } - @Override - public void writeToParcel(Parcel out, int flags) { - out.writeString(key); - out.writeByteArray(encode()); - } - public static final Creator<VpnProfile> CREATOR = new Creator<VpnProfile>() { @Override public VpnProfile createFromParcel(Parcel in) { - final String key = in.readString(); - return decode(key, in.createByteArray()); + return new VpnProfile(in); } @Override |
