From d7cd29da91ccc0aba1f1097e19366f9ca36c7ce1 Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Wed, 1 Jul 2009 11:22:45 -0700 Subject: [PATCH] Add facility to run setup wizard after an update. The system now keeps a tag of the last version (just an arbitrary string) that the setup wizard was run for. If this is different than the current one in the setup wizard, then setup is launched at boot. This introduces a new intent action for the part of the setup wizard that gets run for an ungrade, which the system uses to find its current version tag for comparing against what was last stored. It is up to the launched setup activity update the stored setting to reflect its current value, once it is happy. --- core/java/android/content/Intent.java | 21 +++ core/java/android/provider/Settings.java | 7 + .../android/server/WindowManagerService.java | 8 ++ .../server/am/ActivityManagerService.java | 130 +++++++++++++----- 4 files changed, 135 insertions(+), 31 deletions(-) diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index 6b723bc8fbbb2..263f9279e69ad 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -1085,6 +1085,27 @@ public class Intent implements Parcelable { @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) public static final String ACTION_POWER_USAGE_SUMMARY = "android.intent.action.POWER_USAGE_SUMMARY"; + /** + * Activity Action: Setup wizard to launch after a platform update. This + * activity should have a string meta-data field associated with it, + * {@link #METADATA_SETUP_VERSION}, which defines the current version of + * the platform for setup. The activity will be launched only if + * {@link android.provider.Settings.Secure#LAST_SETUP_SHOWN} is not the + * same value. + *

Input: Nothing. + *

Output: Nothing. + * @hide + */ + @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) + public static final String ACTION_UPGRADE_SETUP = "android.intent.action.UPGRADE_SETUP"; + + /** + * A string associated with a {@link #ACTION_UPGRADE_SETUP} activity + * describing the last run version of the platform that was setup. + * @hide + */ + public static final String METADATA_SETUP_VERSION = "android.SETUP_VERSION"; + // --------------------------------------------------------------------- // --------------------------------------------------------------------- // Standard intent broadcast actions (see action variable). diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 424f740a5f563..4a40058d59004 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -2237,6 +2237,13 @@ public final class Settings { * @hide */ public static final String BACKUP_TRANSPORT = "backup_transport"; + + /** + * Version for which the setup wizard was last shown. Bumped for + * each release when there is new setup information to show. + * @hide + */ + public static final String LAST_SETUP_SHOWN = "last_setup_shown"; /** * Helper method for determining if a location provider is enabled. diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java index cfa625c594486..2dd70efcec1bb 100644 --- a/services/java/com/android/server/WindowManagerService.java +++ b/services/java/com/android/server/WindowManagerService.java @@ -2325,6 +2325,14 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo if (!mDisplayFrozen) { if (mNextAppTransition == WindowManagerPolicy.TRANSIT_NONE) { mNextAppTransition = transit; + } else if (transit == WindowManagerPolicy.TRANSIT_TASK_OPEN + && mNextAppTransition == WindowManagerPolicy.TRANSIT_TASK_CLOSE) { + // Opening a new task always supersedes a close for the anim. + mNextAppTransition = transit; + } else if (transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN + && mNextAppTransition == WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE) { + // Opening a new activity always supersedes a close for the anim. + mNextAppTransition = transit; } mAppTransitionReady = false; mAppTransitionTimeout = false; diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index f716571e55770..2fe4dd4c31092 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -745,6 +745,8 @@ public final class ActivityManagerService extends ActivityManagerNative implemen int mFactoryTest; + boolean mCheckedForSetup; + /** * The time at which we will allow normal application switches again, * after a call to {@link #stopAppSwitches()}. @@ -1774,6 +1776,12 @@ public final class ActivityManagerService extends ActivityManagerNative implemen r.stopped = true; } + // Launch the new version setup screen if needed. We do this -after- + // launching the initial activity (that is, home), so that it can have + // a chance to initialize itself while in the background, making the + // switch back to it faster and look better. + startSetupActivityLocked(); + return true; } @@ -2355,6 +2363,96 @@ public final class ActivityManagerService extends ActivityManagerNative implemen } } + private boolean startHomeActivityLocked() { + if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL + && mTopAction == null) { + // We are running in factory test mode, but unable to find + // the factory test app, so just sit around displaying the + // error message and don't try to start anything. + return false; + } + Intent intent = new Intent( + mTopAction, + mTopData != null ? Uri.parse(mTopData) : null); + intent.setComponent(mTopComponent); + if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { + intent.addCategory(Intent.CATEGORY_HOME); + } + ActivityInfo aInfo = + intent.resolveActivityInfo(mContext.getPackageManager(), + STOCK_PM_FLAGS); + if (aInfo != null) { + intent.setComponent(new ComponentName( + aInfo.applicationInfo.packageName, aInfo.name)); + // Don't do this if the home app is currently being + // instrumented. + ProcessRecord app = getProcessRecordLocked(aInfo.processName, + aInfo.applicationInfo.uid); + if (app == null || app.instrumentationClass == null) { + intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); + startActivityLocked(null, intent, null, null, 0, aInfo, + null, null, 0, 0, 0, false, false); + } + } + + + return true; + } + + /** + * Starts the "new version setup screen" if appropriate. + */ + private void startSetupActivityLocked() { + // Only do this once per boot. + if (mCheckedForSetup) { + return; + } + + // We will show this screen if the current one is a different + // version than the last one shown, and we are not running in + // low-level factory test mode. + final ContentResolver resolver = mContext.getContentResolver(); + if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL && + Settings.Secure.getInt(resolver, + Settings.Secure.DEVICE_PROVISIONED, 0) != 0) { + mCheckedForSetup = true; + + // See if we should be showing the platform update setup UI. + Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); + List ris = mSelf.mContext.getPackageManager() + .queryIntentActivities(intent, PackageManager.GET_META_DATA); + + // We don't allow third party apps to replace this. + ResolveInfo ri = null; + for (int i=0; ris != null && i