summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorDianne Hackborn <hackbod@google.com>2010-06-04 13:30:32 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2010-06-04 13:30:32 -0700
commitfaed5fbf1583ccb6633cde31f1ec3a3acf508260 (patch)
tree385e1b8de68667650e2022ac29817342b3c4c5cb /core
parent7c035d8a65626b8fed6e7da46477137ab9d5573e (diff)
parent860755faa6bdd3c2aeae49c05b87b5bc080ae60c (diff)
downloadframeworks_base-faed5fbf1583ccb6633cde31f1ec3a3acf508260.zip
frameworks_base-faed5fbf1583ccb6633cde31f1ec3a3acf508260.tar.gz
frameworks_base-faed5fbf1583ccb6633cde31f1ec3a3acf508260.tar.bz2
Merge "Add support for heavy-weight applications." into kraken
Diffstat (limited to 'core')
-rw-r--r--core/java/android/app/ActivityManager.java6
-rw-r--r--core/java/android/app/ActivityManagerNative.java17
-rw-r--r--core/java/android/app/IActivityManager.java3
-rw-r--r--core/java/android/content/IntentSender.java20
-rw-r--r--core/java/android/content/pm/ApplicationInfo.java11
-rw-r--r--core/java/android/content/pm/PackageParser.java38
-rw-r--r--core/java/com/android/internal/app/HeavyWeightSwitcherActivity.java156
-rw-r--r--core/res/AndroidManifest.xml6
-rw-r--r--core/res/res/layout/heavy_weight_switcher.xml145
-rw-r--r--core/res/res/values/attrs_manifest.xml9
-rw-r--r--core/res/res/values/public.xml3
-rw-r--r--core/res/res/values/strings.xml23
12 files changed, 435 insertions, 2 deletions
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index c9096cf..793b9d2 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -726,6 +726,12 @@ public class ActivityManager {
public static final int IMPORTANCE_FOREGROUND = 100;
/**
+ * Constant for {@link #importance}: this process is running a
+ * heavy-weight application and thus should not be killed.
+ */
+ public static final int IMPORTANCE_HEAVY_WEIGHT = 150;
+
+ /**
* Constant for {@link #importance}: this process is running something
* that is considered to be actively visible to the user.
*/
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index f694285..b78d22f 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -1251,6 +1251,13 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
reply.writeNoException();
return true;
}
+
+ case FINISH_HEAVY_WEIGHT_APP_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ finishHeavyWeightApp();
+ reply.writeNoException();
+ return true;
+ }
}
return super.onTransact(code, data, reply, flags);
@@ -2758,5 +2765,15 @@ class ActivityManagerProxy implements IActivityManager
return res;
}
+ public void finishHeavyWeightApp() throws RemoteException {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ mRemote.transact(FINISH_HEAVY_WEIGHT_APP_TRANSACTION, data, reply, 0);
+ reply.readException();
+ data.recycle();
+ reply.recycle();
+ }
+
private IBinder mRemote;
}
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 31f0a63..cd24fa6 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -303,6 +303,8 @@ public interface IActivityManager extends IInterface {
public boolean isUserAMonkey() throws RemoteException;
+ public void finishHeavyWeightApp() throws RemoteException;
+
/*
* Private non-Binder interfaces
*/
@@ -513,4 +515,5 @@ public interface IActivityManager extends IInterface {
int WILL_ACTIVITY_BE_VISIBLE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+105;
int START_ACTIVITY_WITH_CONFIG_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+106;
int GET_RUNNING_EXTERNAL_APPLICATIONS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+107;
+ int FINISH_HEAVY_WEIGHT_APP_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+108;
}
diff --git a/core/java/android/content/IntentSender.java b/core/java/android/content/IntentSender.java
index e182021..007a715 100644
--- a/core/java/android/content/IntentSender.java
+++ b/core/java/android/content/IntentSender.java
@@ -16,6 +16,7 @@
package android.content;
+import android.app.ActivityManagerNative;
import android.content.Context;
import android.content.Intent;
import android.content.IIntentSender;
@@ -170,6 +171,25 @@ public class IntentSender implements Parcelable {
}
/**
+ * Return the package name of the application that created this
+ * IntentSender, that is the identity under which you will actually be
+ * sending the Intent. The returned string is supplied by the system, so
+ * that an application can not spoof its package.
+ *
+ * @return The package name of the PendingIntent, or null if there is
+ * none associated with it.
+ */
+ public String getTargetPackage() {
+ try {
+ return ActivityManagerNative.getDefault()
+ .getPackageForIntentSender(mTarget);
+ } catch (RemoteException e) {
+ // Should never happen.
+ return null;
+ }
+ }
+
+ /**
* Comparison operator on two IntentSender objects, such that true
* is returned then they both represent the same operation from the
* same package.
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 7047113..7901b155 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -273,6 +273,17 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
public static final int FLAG_SUPPORTS_XLARGE_SCREENS = 1<<19;
/**
+ * Value for {@link #flags}: set to <code>true</code> if the application
+ * has reported that it is heavy-weight, and thus can not participate in
+ * the normal application lifecycle.
+ *
+ * <p>Comes from the
+ * {@link android.R.styleable#AndroidManifestApplication_heavyWeight android:heavyWeight}
+ * attribute of the &lt;application&gt; tag.
+ */
+ public static final int FLAG_HEAVY_WEIGHT = 1<<20;
+
+ /**
* Value for {@link #flags}: this is true if the application has set
* its android:neverEncrypt to true, false otherwise. It is used to specify
* that this package specifically "opts-out" of a secured file system solution,
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 4ddc124..a5f5acc 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -1600,6 +1600,18 @@ public class PackageParser {
ai.enabled = sa.getBoolean(
com.android.internal.R.styleable.AndroidManifestApplication_enabled, true);
+
+ if (sa.getBoolean(
+ com.android.internal.R.styleable.AndroidManifestApplication_heavyWeight,
+ false)) {
+ ai.flags |= ApplicationInfo.FLAG_HEAVY_WEIGHT;
+
+ // A heavy-weight application can not be in a custom process.
+ // We can do direct compare because we intern all strings.
+ if (ai.processName != null && ai.processName != ai.packageName) {
+ outError[0] = "Heavy-weight applications can not use custom processes";
+ }
+ }
}
sa.recycle();
@@ -1889,6 +1901,14 @@ public class PackageParser {
sa.recycle();
+ if (receiver && (owner.applicationInfo.flags&ApplicationInfo.FLAG_HEAVY_WEIGHT) != 0) {
+ // A heavy-weight application can not have receives in its main process
+ // We can do direct compare because we intern all strings.
+ if (a.info.processName == owner.packageName) {
+ outError[0] = "Heavy-weight applications can not have receivers in main process";
+ }
+ }
+
if (outError[0] != null) {
return null;
}
@@ -2171,6 +2191,15 @@ public class PackageParser {
sa.recycle();
+ if ((owner.applicationInfo.flags&ApplicationInfo.FLAG_HEAVY_WEIGHT) != 0) {
+ // A heavy-weight application can not have providers in its main process
+ // We can do direct compare because we intern all strings.
+ if (p.info.processName == owner.packageName) {
+ outError[0] = "Heavy-weight applications can not have providers in main process";
+ return null;
+ }
+ }
+
if (cpname == null) {
outError[0] = "<provider> does not incude authorities attribute";
return null;
@@ -2403,6 +2432,15 @@ public class PackageParser {
sa.recycle();
+ if ((owner.applicationInfo.flags&ApplicationInfo.FLAG_HEAVY_WEIGHT) != 0) {
+ // A heavy-weight application can not have services in its main process
+ // We can do direct compare because we intern all strings.
+ if (s.info.processName == owner.packageName) {
+ outError[0] = "Heavy-weight applications can not have services in main process";
+ return null;
+ }
+ }
+
int outerDepth = parser.getDepth();
int type;
while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
diff --git a/core/java/com/android/internal/app/HeavyWeightSwitcherActivity.java b/core/java/com/android/internal/app/HeavyWeightSwitcherActivity.java
new file mode 100644
index 0000000..ada7f36
--- /dev/null
+++ b/core/java/com/android/internal/app/HeavyWeightSwitcherActivity.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2010 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 com.android.internal.app;
+
+import com.android.internal.R;
+
+import android.app.Activity;
+import android.app.ActivityManagerNative;
+import android.content.Intent;
+import android.content.IntentSender;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.util.Log;
+import android.view.View;
+import android.view.Window;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+/**
+ * This activity is displayed when the system attempts to start an Intent for
+ * which there is more than one matching activity, allowing the user to decide
+ * which to go to. It is not normally used directly by application developers.
+ */
+public class HeavyWeightSwitcherActivity extends Activity {
+ /** The PendingIntent of the new activity being launched. */
+ public static final String KEY_INTENT = "intent";
+ /** Set if the caller is requesting a result. */
+ public static final String KEY_HAS_RESULT = "has_result";
+ /** Package of current heavy-weight app. */
+ public static final String KEY_CUR_APP = "cur_app";
+ /** Task that current heavy-weight activity is running in. */
+ public static final String KEY_CUR_TASK = "cur_task";
+ /** Package of newly requested heavy-weight app. */
+ public static final String KEY_NEW_APP = "new_app";
+
+ IntentSender mStartIntent;
+ boolean mHasResult;
+ String mCurApp;
+ int mCurTask;
+ String mNewApp;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ requestWindowFeature(Window.FEATURE_LEFT_ICON);
+
+ mStartIntent = (IntentSender)getIntent().getParcelableExtra(KEY_INTENT);
+ mHasResult = getIntent().getBooleanExtra(KEY_HAS_RESULT, false);
+ mCurApp = getIntent().getStringExtra(KEY_CUR_APP);
+ mCurTask = getIntent().getIntExtra(KEY_CUR_TASK, 0);
+ mNewApp = getIntent().getStringExtra(KEY_NEW_APP);
+
+ setContentView(com.android.internal.R.layout.heavy_weight_switcher);
+
+ setIconAndText(R.id.old_app_icon, R.id.old_app_action, R.id.old_app_description,
+ mCurApp, R.string.old_app_action, R.string.old_app_description);
+ setIconAndText(R.id.new_app_icon, R.id.new_app_action, R.id.new_app_description,
+ mNewApp, R.string.new_app_action, R.string.new_app_description);
+
+ View button = findViewById((R.id.switch_old));
+ button.setOnClickListener(mSwitchOldListener);
+ button = findViewById((R.id.switch_new));
+ button.setOnClickListener(mSwitchNewListener);
+ button = findViewById((R.id.cancel));
+ button.setOnClickListener(mCancelListener);
+
+ getWindow().setFeatureDrawableResource(Window.FEATURE_LEFT_ICON,
+ android.R.drawable.ic_dialog_alert);
+ }
+
+ void setText(int id, CharSequence text) {
+ ((TextView)findViewById(id)).setText(text);
+ }
+
+ void setDrawable(int id, Drawable dr) {
+ if (dr != null) {
+ ((ImageView)findViewById(id)).setImageDrawable(dr);
+ }
+ }
+
+ void setIconAndText(int iconId, int actionId, int descriptionId,
+ String packageName, int actionStr, int descriptionStr) {
+ CharSequence appName = "";
+ Drawable appIcon = null;
+ if (mCurApp != null) {
+ try {
+ ApplicationInfo info = getPackageManager().getApplicationInfo(
+ packageName, 0);
+ appName = info.loadLabel(getPackageManager());
+ appIcon = info.loadIcon(getPackageManager());
+ } catch (PackageManager.NameNotFoundException e) {
+ }
+ }
+
+ setDrawable(iconId, appIcon);
+ setText(actionId, getString(actionStr, appName));
+ setText(descriptionId, getText(descriptionStr));
+ }
+
+ private OnClickListener mSwitchOldListener = new OnClickListener() {
+ public void onClick(View v) {
+ try {
+ ActivityManagerNative.getDefault().moveTaskToFront(mCurTask);
+ } catch (RemoteException e) {
+ }
+ finish();
+ }
+ };
+
+ private OnClickListener mSwitchNewListener = new OnClickListener() {
+ public void onClick(View v) {
+ try {
+ ActivityManagerNative.getDefault().finishHeavyWeightApp();
+ } catch (RemoteException e) {
+ }
+ try {
+ if (mHasResult) {
+ startIntentSenderForResult(mStartIntent, -1, null,
+ Intent.FLAG_ACTIVITY_FORWARD_RESULT,
+ Intent.FLAG_ACTIVITY_FORWARD_RESULT, 0);
+ } else {
+ startIntentSenderForResult(mStartIntent, -1, null, 0, 0, 0);
+ }
+ } catch (IntentSender.SendIntentException ex) {
+ Log.w("HeavyWeightSwitcherActivity", "Failure starting", ex);
+ }
+ finish();
+ }
+ };
+
+ private OnClickListener mCancelListener = new OnClickListener() {
+ public void onClick(View v) {
+ finish();
+ }
+ };
+}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 2a2208f..1fcf186 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1250,6 +1250,12 @@
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
+ <activity android:name="com.android.internal.app.HeavyWeightSwitcherActivity"
+ android:theme="@style/Theme.Dialog"
+ android:label="@string/heavy_weight_switcher_title"
+ android:finishOnCloseSystemDialogs="true"
+ android:excludeFromRecents="true">
+ </activity>
<activity android:name="com.android.internal.app.DisableCarModeActivity"
android:theme="@style/Theme.NoDisplay"
android:excludeFromRecents="true">
diff --git a/core/res/res/layout/heavy_weight_switcher.xml b/core/res/res/layout/heavy_weight_switcher.xml
new file mode 100644
index 0000000..9acf009
--- /dev/null
+++ b/core/res/res/layout/heavy_weight_switcher.xml
@@ -0,0 +1,145 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical" android:padding="4dp"
+ android:gravity="center_horizontal"
+ android:layout_width="wrap_content" android:layout_height="wrap_content">
+
+ <TextView
+ android:layout_width="match_parent" android:layout_height="wrap_content"
+ android:layout_weight="0"
+ android:paddingBottom="8dp"
+ android:text="@string/heavy_weight_switcher_text"/>
+
+ <ImageView android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:scaleType="fitXY"
+ android:src="?android:listDivider" />
+
+ <LinearLayout android:id="@+id/switch_old"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ android:orientation="horizontal"
+ android:background="@android:drawable/list_selector_background"
+ android:paddingRight="3dip"
+ android:paddingLeft="3dip"
+ android:paddingTop="5dip"
+ android:paddingBottom="14dip"
+ android:gravity="center_vertical"
+ android:focusable="true" >
+
+ <ImageView android:id="@+id/old_app_icon"
+ android:layout_width="@android:dimen/app_icon_size"
+ android:layout_height="@android:dimen/app_icon_size"
+ android:layout_marginRight="11dip"
+ android:layout_gravity="center_vertical"
+ android:scaleType="fitCenter"/>
+
+ <LinearLayout
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:duplicateParentState="true" >
+ <TextView android:id="@+id/old_app_action"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textStyle="bold"
+ android:singleLine="true"
+ android:layout_marginBottom="2dip"
+ android:duplicateParentState="true" />
+ <TextView android:id="@+id/old_app_description"
+ android:layout_marginTop="-4dip"
+ android:layout_gravity="center_vertical"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:duplicateParentState="true" />
+ </LinearLayout>
+ </LinearLayout>
+
+ <ImageView android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:scaleType="fitXY"
+ android:src="?android:listDivider" />
+
+ <LinearLayout android:id="@+id/switch_new"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ android:orientation="horizontal"
+ android:background="@android:drawable/list_selector_background"
+ android:paddingRight="3dip"
+ android:paddingLeft="3dip"
+ android:paddingTop="5dip"
+ android:paddingBottom="8dip"
+ android:gravity="center_vertical"
+ android:focusable="true" >
+
+ <ImageView android:id="@+id/new_app_icon"
+ android:layout_width="@android:dimen/app_icon_size"
+ android:layout_height="@android:dimen/app_icon_size"
+ android:layout_marginRight="11dip"
+ android:layout_gravity="center_vertical"
+ android:scaleType="fitCenter"/>
+
+ <LinearLayout
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:duplicateParentState="true" >
+ <TextView android:id="@+id/new_app_action"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textStyle="bold"
+ android:singleLine="true"
+ android:layout_marginBottom="2dip"
+ android:duplicateParentState="true" />
+ <TextView android:id="@+id/new_app_description"
+ android:layout_marginTop="-4dip"
+ android:layout_gravity="center_vertical"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:duplicateParentState="true" />
+ </LinearLayout>
+ </LinearLayout>
+
+ <ImageView android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:scaleType="fitXY"
+ android:src="?android:listDivider" />
+
+ <TextView android:id="@+id/cancel"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:background="@android:drawable/list_selector_background"
+ android:paddingRight="6dip"
+ android:paddingLeft="6dip"
+ android:paddingTop="5dip"
+ android:paddingBottom="8dip"
+ android:textStyle="bold"
+ android:singleLine="true"
+ android:gravity="center"
+ android:focusable="true"
+ android:text="@string/cancel" />
+
+</LinearLayout>
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index b4c4811..5ca7b28 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -740,6 +740,15 @@
<attr name="restoreNeedsApplication" />
<attr name="restoreAnyVersion" />
<attr name="neverEncrypt" />
+ <!-- Declare that this is a heavy-weight application. This kind of
+ application is not able to save and restore its state on demand,
+ so can not participate in the normal activity lifecycle. It will
+ not be killed while in the background; the user must explicitly
+ quit it. Only one such app can be running at a time; if the user
+ tries to launch a second heavy-weight app, they will be prompted
+ to quit the first before doing so. While a heavy-weight
+ application is running, the user will be informed of this. -->
+ <attr name="heavyWeight" format="boolean" />
</declare-styleable>
<!-- The <code>permission</code> tag declares a security permission that can be
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 5d18e9e..1932771 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1245,8 +1245,9 @@
<public type="attr" name="logo" id="0x010102be" />
<public type="attr" name="xlargeScreens" id="0x010102bf" />
-
+ <public type="attr" name="heavyWeight" id="0x010102c0" />
<public-padding type="attr" name="kraken_resource_pad" end="0x01010300" />
+
<public-padding type="id" name="kraken_resource_pad" end="0x01020040" />
<public-padding type="anim" name="kraken_resource_pad" end="0x010a0020" />
<public-padding type="drawable" name="kraken_resource_pad" end="0x01080100" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 613a9a2..e7f892a 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1935,8 +1935,29 @@
<!-- Button allowing the user to choose to wait for an application that is not responding to become responsive again. -->
<string name="wait">Wait</string>
+ <!-- Notification text to tell the user that a heavy-weight application is running. -->
+ <string name="heavy_weight_notification"><xliff:g id="app">%1$s</xliff:g> running</string>
+
+ <!-- Notification details to tell the user that a heavy-weight application is running. -->
+ <string name="heavy_weight_notification_detail">Select to switch to application</string>
+
+ <!-- Title of dialog prompting whether user wants to switch between heavy-weight apps. -->
+ <string name="heavy_weight_switcher_title">Switch applications?</string>
+
+ <!-- Descriptive text for switching to a new heavy-weight application. -->
+ <string name="heavy_weight_switcher_text">Another application is already running
+ that must be stopped before you can start a new one.</string>
+
+ <string name="old_app_action">Return to <xliff:g id="old_app">%1$s</xliff:g></string>
+ <string name="old_app_description">Don\'t start the new application.</string>
+
+ <string name="new_app_action">Start <xliff:g id="old_app">%1$s</xliff:g></string>
+ <string name="new_app_description">Stop the old application without saving.</string>
+
<!-- Displayed in the title of the chooser for things to do with text that
- is to be sent to another application. For example, I can send text through SMS or IM. A dialog with those choices would be shown, and this would be the title. -->
+ is to be sent to another application. For example, I can send
+ text through SMS or IM. A dialog with those choices would be shown,
+ and this would be the title. -->
<string name="sendText">Select an action for text</string>
<!-- Title of the dialog where the user is adjusting the phone ringer volume -->