Merge "MediaRecorder: Fix crash when given a released Camera object" into lmp-dev
diff --git a/api/current.txt b/api/current.txt
index 623c281..9ef93cb 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -3309,6 +3309,7 @@
method public android.view.LayoutInflater getLayoutInflater();
method public android.app.LoaderManager getLoaderManager();
method public java.lang.String getLocalClassName();
+ method public final android.media.session.MediaController getMediaController();
method public android.view.MenuInflater getMenuInflater();
method public final android.app.Activity getParent();
method public android.content.Intent getParentActivityIntent();
@@ -3432,6 +3433,7 @@
method public void setFinishOnTouchOutside(boolean);
method public void setImmersive(boolean);
method public void setIntent(android.content.Intent);
+ method public final void setMediaController(android.media.session.MediaController);
method public boolean setMediaPlaying(boolean);
method public final void setProgress(int);
method public final void setProgressBarIndeterminate(boolean);
@@ -3510,6 +3512,7 @@
method public android.app.PendingIntent getRunningServiceControlPanel(android.content.ComponentName) throws java.lang.SecurityException;
method public java.util.List<android.app.ActivityManager.RunningServiceInfo> getRunningServices(int) throws java.lang.SecurityException;
method public deprecated java.util.List<android.app.ActivityManager.RunningTaskInfo> getRunningTasks(int) throws java.lang.SecurityException;
+ method public boolean isInLockTaskMode();
method public boolean isLowRamDevice();
method public static boolean isRunningInTestHarness();
method public static boolean isUserAMonkey();
@@ -8367,6 +8370,9 @@
field public java.lang.String targetPackage;
}
+ public class KeySet {
+ }
+
public class LabeledIntent extends android.content.Intent {
ctor public LabeledIntent(android.content.Intent, java.lang.String, int, int);
ctor public LabeledIntent(android.content.Intent, java.lang.String, java.lang.CharSequence, int);
@@ -8504,6 +8510,7 @@
method public abstract java.util.List<android.content.pm.PackageInfo> getInstalledPackages(int);
method public abstract java.lang.String getInstallerPackageName(java.lang.String);
method public abstract android.content.pm.InstrumentationInfo getInstrumentationInfo(android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException;
+ method public abstract android.content.pm.KeySet getKeySetByAlias(java.lang.String, java.lang.String);
method public abstract android.content.Intent getLaunchIntentForPackage(java.lang.String);
method public abstract android.content.Intent getLeanbackLaunchIntentForPackage(java.lang.String);
method public abstract java.lang.String getNameForUid(int);
@@ -8522,12 +8529,15 @@
method public abstract android.content.res.Resources getResourcesForApplication(android.content.pm.ApplicationInfo) throws android.content.pm.PackageManager.NameNotFoundException;
method public abstract android.content.res.Resources getResourcesForApplication(java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException;
method public abstract android.content.pm.ServiceInfo getServiceInfo(android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException;
+ method public abstract android.content.pm.KeySet getSigningKeySet(java.lang.String);
method public abstract android.content.pm.FeatureInfo[] getSystemAvailableFeatures();
method public abstract java.lang.String[] getSystemSharedLibraryNames();
method public abstract java.lang.CharSequence getText(java.lang.String, int, android.content.pm.ApplicationInfo);
method public abstract android.content.res.XmlResourceParser getXml(java.lang.String, int, android.content.pm.ApplicationInfo);
method public abstract boolean hasSystemFeature(java.lang.String);
method public abstract boolean isSafeMode();
+ method public abstract boolean isSignedBy(java.lang.String, android.content.pm.KeySet);
+ method public abstract boolean isSignedByExactly(java.lang.String, android.content.pm.KeySet);
method public abstract java.util.List<android.content.pm.ResolveInfo> queryBroadcastReceivers(android.content.Intent, int);
method public abstract java.util.List<android.content.pm.ProviderInfo> queryContentProviders(java.lang.String, int, int);
method public abstract java.util.List<android.content.pm.InstrumentationInfo> queryInstrumentation(java.lang.String, int);
@@ -16217,19 +16227,14 @@
}
public final class PlaybackState implements android.os.Parcelable {
- ctor public PlaybackState();
- ctor public PlaybackState(android.media.session.PlaybackState);
method public int describeContents();
method public long getActions();
method public long getBufferPosition();
method public java.lang.CharSequence getErrorMessage();
- method public float getPlaybackRate();
+ method public long getLastPositionUpdateTime();
+ method public float getPlaybackSpeed();
method public long getPosition();
method public int getState();
- method public void setActions(long);
- method public void setBufferPosition(long);
- method public void setErrorMessage(java.lang.CharSequence);
- method public void setState(int, long, float);
method public void writeToParcel(android.os.Parcel, int);
field public static final long ACTION_FAST_FORWARD = 64L; // 0x40L
field public static final long ACTION_PAUSE = 2L; // 0x2L
@@ -16256,6 +16261,17 @@
field public static final int STATE_STOPPED = 1; // 0x1
}
+ public static final class PlaybackState.Builder {
+ ctor public PlaybackState.Builder();
+ ctor public PlaybackState.Builder(android.media.session.PlaybackState);
+ method public android.media.session.PlaybackState build();
+ method public android.media.session.PlaybackState.Builder setActions(long);
+ method public android.media.session.PlaybackState.Builder setBufferPosition(long);
+ method public android.media.session.PlaybackState.Builder setErrorMessage(java.lang.CharSequence);
+ method public android.media.session.PlaybackState.Builder setState(int, long, float, long);
+ method public android.media.session.PlaybackState.Builder setState(int, long, float);
+ }
+
}
package android.media.tv {
@@ -22936,7 +22952,7 @@
method protected void onDisconnected();
method protected abstract void onPrintJobQueued(android.printservice.PrintJob);
method protected abstract void onRequestCancelPrintJob(android.printservice.PrintJob);
- field public static final java.lang.String EXTRA_PRINTER_INFO = "android.intent.extra.print.PRINTER_INFO";
+ field public static final java.lang.String EXTRA_PRINTER_INFO = "android.intent.extra.print.EXTRA_PRINTER_INFO";
field public static final java.lang.String EXTRA_PRINT_JOB_INFO = "android.intent.extra.print.PRINT_JOB_INFO";
field public static final java.lang.String SERVICE_INTERFACE = "android.printservice.PrintService";
field public static final java.lang.String SERVICE_META_DATA = "android.printservice";
@@ -25581,6 +25597,7 @@
field public static final java.lang.String NUMBER = "number";
field public static final java.lang.String SOURCE_DATA = "source_data";
field public static final java.lang.String SOURCE_PACKAGE = "source_package";
+ field public static final java.lang.String TRANSCRIPTION = "transcription";
}
}
@@ -28215,6 +28232,7 @@
ctor public TelecommConstants();
field public static final java.lang.String ACTION_CALL_SERVICE_PROVIDER;
field public static final java.lang.String ACTION_CONNECTION_SERVICE;
+ field public static final java.lang.String ACTION_CONNECTION_SERVICE_CONFIGURE = "android.intent.action.CONNECTION_SERVICE_CONFIGURE";
field public static final java.lang.String ACTION_INCOMING_CALL = "android.intent.action.INCOMING_CALL";
field public static final char DTMF_CHARACTER_PAUSE = 44; // 0x002c ','
field public static final char DTMF_CHARACTER_WAIT = 59; // 0x003b ';'
@@ -34276,6 +34294,7 @@
method protected final int getForcedWindowFlags();
method public abstract android.view.LayoutInflater getLayoutInflater();
method protected final int getLocalFeatures();
+ method public android.media.session.MediaController getMediaController();
method public abstract int getNavigationBarColor();
method public android.transition.Transition getSharedElementEnterTransition();
method public android.transition.Transition getSharedElementExitTransition();
@@ -34332,6 +34351,7 @@
method public void setLayout(int, int);
method public void setLocalFocus(boolean, boolean);
method public void setLogo(int);
+ method public void setMediaController(android.media.session.MediaController);
method public abstract void setNavigationBarColor(int);
method public void setSharedElementEnterTransition(android.transition.Transition);
method public void setSharedElementExitTransition(android.transition.Transition);
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index 3d0eec4..3a2ca30 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -50,6 +50,7 @@
import android.os.ServiceManager;
import android.os.UserHandle;
import android.os.UserManager;
+import android.text.TextUtils;
import android.util.Log;
import com.android.internal.content.PackageHelper;
@@ -923,33 +924,13 @@
return;
}
} else if (opt.equals("--abi")) {
- abi = nextOptionData();
- if (abi == null) {
- System.err.println("Error: must supply argument for --abi");
- return;
- }
+ abi = checkAbiArgument(nextOptionData());
} else {
System.err.println("Error: Unknown option: " + opt);
return;
}
}
- if (abi != null) {
- final String[] supportedAbis = Build.SUPPORTED_ABIS;
- boolean matched = false;
- for (String supportedAbi : supportedAbis) {
- if (supportedAbi.equals(abi)) {
- matched = true;
- break;
- }
- }
-
- if (!matched) {
- System.err.println("Error: abi " + abi + " not supported on this device.");
- return;
- }
- }
-
final Uri verificationURI;
final Uri originatingURI;
final Uri referrerURI;
@@ -1044,6 +1025,8 @@
} else if (opt.equals("-S")) {
params.deltaSize = Long.parseLong(nextOptionData());
params.progressMax = (int) params.deltaSize;
+ } else if (opt.equals("--abi")) {
+ params.abiOverride = checkAbiArgument(nextOptionData());
} else {
throw new IllegalArgumentException("Unknown option " + opt);
}
@@ -1684,6 +1667,21 @@
}
}
+ private static String checkAbiArgument(String abi) {
+ if (TextUtils.isEmpty(abi)) {
+ throw new IllegalArgumentException("Missing ABI argument");
+ }
+
+ final String[] supportedAbis = Build.SUPPORTED_ABIS;
+ for (String supportedAbi : supportedAbis) {
+ if (supportedAbi.equals(abi)) {
+ return abi;
+ }
+ }
+
+ throw new IllegalArgumentException("ABI " + abi + " not supported on this device");
+ }
+
private String nextOption() {
if (mNextArg >= mArgs.length) {
return null;
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index d20a5dc..cac646d 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -23,6 +23,7 @@
import android.util.ArrayMap;
import android.util.SuperNotCalledException;
import android.widget.Toolbar;
+
import com.android.internal.app.IVoiceInteractor;
import com.android.internal.app.WindowDecorActionBar;
import com.android.internal.app.ToolbarActionBar;
@@ -51,6 +52,8 @@
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.media.AudioManager;
+import android.media.session.MediaController;
+import android.media.session.MediaSession;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
@@ -109,14 +112,14 @@
* or embedded inside of another activity (using {@link ActivityGroup}).
*
* There are two methods almost all subclasses of Activity will implement:
- *
+ *
* <ul>
* <li> {@link #onCreate} is where you initialize your activity. Most
* importantly, here you will usually call {@link #setContentView(int)}
* with a layout resource defining your UI, and using {@link #findViewById}
* to retrieve the widgets in that UI that you need to interact with
* programmatically.
- *
+ *
* <li> {@link #onPause} is where you deal with the user leaving your
* activity. Most importantly, any changes made by the user should at this
* point be committed (usually to the
@@ -127,7 +130,7 @@
* activity classes must have a corresponding
* {@link android.R.styleable#AndroidManifestActivity <activity>}
* declaration in their package's <code>AndroidManifest.xml</code>.</p>
- *
+ *
* <p>Topics covered here:
* <ol>
* <li><a href="#Fragments">Fragments</a>
@@ -170,14 +173,14 @@
* and becomes the running activity -- the previous activity always remains
* below it in the stack, and will not come to the foreground again until
* the new activity exits.</p>
- *
+ *
* <p>An activity has essentially four states:</p>
* <ul>
* <li> If an activity in the foreground of the screen (at the top of
* the stack),
* it is <em>active</em> or <em>running</em>. </li>
* <li>If an activity has lost focus but is still visible (that is, a new non-full-sized
- * or transparent activity has focus on top of your activity), it
+ * or transparent activity has focus on top of your activity), it
* is <em>paused</em>. A paused activity is completely alive (it
* maintains all state and member information and remains attached to
* the window manager), but can be killed by the system in extreme
@@ -197,13 +200,13 @@
* The square rectangles represent callback methods you can implement to
* perform operations when the Activity moves between states. The colored
* ovals are major states the Activity can be in.</p>
- *
+ *
* <p><img src="../../../images/activity_lifecycle.png"
* alt="State diagram for an Android Activity Lifecycle." border="0" /></p>
- *
+ *
* <p>There are three key loops you may be interested in monitoring within your
* activity:
- *
+ *
* <ul>
* <li>The <b>entire lifetime</b> of an activity happens between the first call
* to {@link android.app.Activity#onCreate} through to a single final call
@@ -212,7 +215,7 @@
* onDestroy(). For example, if it has a thread running in the background
* to download data from the network, it may create that thread in onCreate()
* and then stop the thread in onDestroy().
- *
+ *
* <li>The <b>visible lifetime</b> of an activity happens between a call to
* {@link android.app.Activity#onStart} until a corresponding call to
* {@link android.app.Activity#onStop}. During this time the user can see the
@@ -224,7 +227,7 @@
* longer sees what you are displaying. The onStart() and onStop() methods
* can be called multiple times, as the activity becomes visible and hidden
* to the user.
- *
+ *
* <li>The <b>foreground lifetime</b> of an activity happens between a call to
* {@link android.app.Activity#onResume} until a corresponding call to
* {@link android.app.Activity#onPause}. During this time the activity is
@@ -234,7 +237,7 @@
* intent is delivered -- so the code in these methods should be fairly
* lightweight.
* </ul>
- *
+ *
* <p>The entire lifecycle of an activity is defined by the following
* Activity methods. All of these are hooks that you can override
* to do appropriate work when the activity changes state. All
@@ -250,7 +253,7 @@
* protected void onCreate(Bundle savedInstanceState);
*
* protected void onStart();
- *
+ *
* protected void onRestart();
*
* protected void onResume();
@@ -366,7 +369,7 @@
* {@link #onSaveInstanceState(Bundle)} is called before placing the activity
* in such a background state, allowing you to save away any dynamic instance
* state in your activity into the given Bundle, to be later received in
- * {@link #onCreate} if the activity needs to be re-created.
+ * {@link #onCreate} if the activity needs to be re-created.
* See the <a href="#ProcessLifecycle">Process Lifecycle</a>
* section for more information on how the lifecycle of a process is tied
* to the activities it is hosting. Note that it is important to save
@@ -390,14 +393,14 @@
*
* <a name="ConfigurationChanges"></a>
* <h3>Configuration Changes</h3>
- *
+ *
* <p>If the configuration of the device (as defined by the
* {@link Configuration Resources.Configuration} class) changes,
* then anything displaying a user interface will need to update to match that
* configuration. Because Activity is the primary mechanism for interacting
* with the user, it includes special support for handling configuration
* changes.</p>
- *
+ *
* <p>Unless you specify otherwise, a configuration change (such as a change
* in screen orientation, language, input devices, etc) will cause your
* current activity to be <em>destroyed</em>, going through the normal activity
@@ -407,7 +410,7 @@
* called in that instance then a new instance of the activity will be
* created, with whatever savedInstanceState the previous instance had generated
* from {@link #onSaveInstanceState}.</p>
- *
+ *
* <p>This is done because any application resource,
* including layout files, can change based on any configuration value. Thus
* the only safe way to handle a configuration change is to re-retrieve all
@@ -415,7 +418,7 @@
* must already know how to save their state and re-create themselves from
* that state, this is a convenient way to have an activity restart itself
* with a new configuration.</p>
- *
+ *
* <p>In some special cases, you may want to bypass restarting of your
* activity based on one or more types of configuration changes. This is
* done with the {@link android.R.attr#configChanges android:configChanges}
@@ -425,7 +428,7 @@
* a configuration change involves any that you do not handle, however, the
* activity will still be restarted and {@link #onConfigurationChanged}
* will not be called.</p>
- *
+ *
* <a name="StartingActivities"></a>
* <h3>Starting Activities and Getting Results</h3>
*
@@ -440,10 +443,10 @@
* ends. For example, you may start an activity that lets the user pick
* a person in a list of contacts; when it ends, it returns the person
* that was selected. To do this, you call the
- * {@link android.app.Activity#startActivityForResult(Intent, int)}
- * version with a second integer parameter identifying the call. The result
+ * {@link android.app.Activity#startActivityForResult(Intent, int)}
+ * version with a second integer parameter identifying the call. The result
* will come back through your {@link android.app.Activity#onActivityResult}
- * method.</p>
+ * method.</p>
*
* <p>When an activity exits, it can call
* {@link android.app.Activity#setResult(int)}
@@ -570,17 +573,17 @@
*
* protected void onPause() {
* super.onPause();
- *
+ *
* SharedPreferences.Editor ed = mPrefs.edit();
* ed.putInt("view_mode", mCurViewMode);
* ed.commit();
* }
* }
* </pre>
- *
+ *
* <a name="Permissions"></a>
* <h3>Permissions</h3>
- *
+ *
* <p>The ability to start a particular Activity can be enforced when it is
* declared in its
* manifest's {@link android.R.styleable#AndroidManifestActivity <activity>}
@@ -601,10 +604,10 @@
*
* <p>See the <a href="{@docRoot}guide/topics/security/security.html">Security and Permissions</a>
* document for more information on permissions and security in general.
- *
+ *
* <a name="ProcessLifecycle"></a>
* <h3>Process Lifecycle</h3>
- *
+ *
* <p>The Android system attempts to keep application process around for as
* long as possible, but eventually will need to remove old processes when
* memory runs low. As described in <a href="#ActivityLifecycle">Activity
@@ -614,7 +617,7 @@
* listed here in order of importance. The system will kill less important
* processes (the last ones) before it resorts to killing more important
* processes (the first ones).
- *
+ *
* <ol>
* <li> <p>The <b>foreground activity</b> (the activity at the top of the screen
* that the user is currently interacting with) is considered the most important.
@@ -642,7 +645,7 @@
* context of an activity BroadcastReceiver or Service to ensure that the system
* knows it needs to keep your process around.
* </ol>
- *
+ *
* <p>Sometimes an Activity may need to do a long-running operation that exists
* independently of the activity lifecycle itself. An example may be a camera
* application that allows you to upload a picture to a web site. The upload
@@ -720,7 +723,7 @@
VoiceInteractor voiceInteractor;
}
/* package */ NonConfigurationInstances mLastNonConfigurationInstances;
-
+
private Window mWindow;
private WindowManager mWindowManager;
@@ -764,7 +767,7 @@
private final ArrayList<ManagedCursor> mManagedCursors =
new ArrayList<ManagedCursor>();
- // protected by synchronized (this)
+ // protected by synchronized (this)
int mResultCode = RESULT_CANCELED;
Intent mResultData = null;
@@ -775,7 +778,7 @@
private int mDefaultKeyMode = DEFAULT_KEYS_DISABLE;
private SpannableStringBuilder mDefaultKeySsb = null;
-
+
protected static final int[] FOCUSED_STATE_SET = {com.android.internal.R.attr.state_focused};
@SuppressWarnings("unused")
@@ -793,16 +796,16 @@
return mIntent;
}
- /**
- * Change the intent returned by {@link #getIntent}. This holds a
- * reference to the given intent; it does not copy it. Often used in
- * conjunction with {@link #onNewIntent}.
- *
- * @param newIntent The new Intent object to return from getIntent
- *
+ /**
+ * Change the intent returned by {@link #getIntent}. This holds a
+ * reference to the given intent; it does not copy it. Often used in
+ * conjunction with {@link #onNewIntent}.
+ *
+ * @param newIntent The new Intent object to return from getIntent
+ *
* @see #getIntent
* @see #onNewIntent
- */
+ */
public void setIntent(Intent newIntent) {
mIntent = newIntent;
}
@@ -816,7 +819,7 @@
public final boolean isChild() {
return mParent != null;
}
-
+
/** Return the parent activity if this view is an embedded child. */
public final Activity getParent() {
return mParent;
@@ -831,7 +834,7 @@
* Retrieve the current {@link android.view.Window} for the activity.
* This can be used to directly access parts of the Window API that
* are not available through Activity/Screen.
- *
+ *
* @return Window The current window, or null if the activity is not
* visual.
*/
@@ -850,7 +853,7 @@
mLoaderManager = getLoaderManager("(root)", mLoadersStarted, true);
return mLoaderManager;
}
-
+
LoaderManagerImpl getLoaderManager(String who, boolean started, boolean create) {
if (mAllLoaderManagers == null) {
mAllLoaderManagers = new ArrayMap<String, LoaderManagerImpl>();
@@ -866,13 +869,13 @@
}
return lm;
}
-
+
/**
* Calls {@link android.view.Window#getCurrentFocus} on the
* Window of this Activity to return the currently focused view.
- *
+ *
* @return View The current View with focus or null.
- *
+ *
* @see #getWindow
* @see android.view.Window#getCurrentFocus
*/
@@ -888,20 +891,20 @@
* with widgets in the UI, calling
* {@link #managedQuery(android.net.Uri , String[], String, String[], String)} to retrieve
* cursors for data being displayed, etc.
- *
+ *
* <p>You can call {@link #finish} from within this function, in
* which case onDestroy() will be immediately called without any of the rest
* of the activity lifecycle ({@link #onStart}, {@link #onResume},
* {@link #onPause}, etc) executing.
- *
+ *
* <p><em>Derived classes must call through to the super class's
* implementation of this method. If they do not, an exception will be
* thrown.</em></p>
- *
+ *
* @param savedInstanceState If the activity is being re-initialized after
* previously being shut down then this Bundle contains the data it most
* recently supplied in {@link #onSaveInstanceState}. <b><i>Note: Otherwise it is null.</i></b>
- *
+ *
* @see #onStart
* @see #onSaveInstanceState
* @see #onRestoreInstanceState
@@ -996,12 +999,12 @@
* decide whether to use your default implementation. The default
* implementation of this method performs a restore of any view state that
* had previously been frozen by {@link #onSaveInstanceState}.
- *
+ *
* <p>This method is called between {@link #onStart} and
* {@link #onPostCreate}.
- *
+ *
* @param savedInstanceState the data most recently supplied in {@link #onSaveInstanceState}.
- *
+ *
* @see #onCreate
* @see #onPostCreate
* @see #onResume
@@ -1098,11 +1101,11 @@
* and {@link #onRestoreInstanceState} have been called). Applications will
* generally not implement this method; it is intended for system
* classes to do final initialization after application code has run.
- *
+ *
* <p><em>Derived classes must call through to the super class's
* implementation of this method. If they do not, an exception will be
* thrown.</em></p>
- *
+ *
* @param savedInstanceState If the activity is being re-initialized after
* previously being shut down then this Bundle contains the data it most
* recently supplied in {@link #onSaveInstanceState}. <b><i>Note: Otherwise it is null.</i></b>
@@ -1133,14 +1136,14 @@
}
/**
- * Called after {@link #onCreate} — or after {@link #onRestart} when
- * the activity had been stopped, but is now again being displayed to the
+ * Called after {@link #onCreate} — or after {@link #onRestart} when
+ * the activity had been stopped, but is now again being displayed to the
* user. It will be followed by {@link #onResume}.
*
* <p><em>Derived classes must call through to the super class's
* implementation of this method. If they do not, an exception will be
* thrown.</em></p>
- *
+ *
* @see #onCreate
* @see #onStop
* @see #onResume
@@ -1148,7 +1151,7 @@
protected void onStart() {
if (DEBUG_LIFECYCLE) Slog.v(TAG, "onStart " + this);
mCalled = true;
-
+
if (!mLoadersStarted) {
mLoadersStarted = true;
if (mLoaderManager != null) {
@@ -1173,11 +1176,11 @@
* this is usually the place
* where the cursor should be requeried (because you had deactivated it in
* {@link #onStop}.
- *
+ *
* <p><em>Derived classes must call through to the super class's
* implementation of this method. If they do not, an exception will be
* thrown.</em></p>
- *
+ *
* @see #onStop
* @see #onStart
* @see #onResume
@@ -1200,7 +1203,7 @@
* <p><em>Derived classes must call through to the super class's
* implementation of this method. If they do not, an exception will be
* thrown.</em></p>
- *
+ *
* @see #onRestoreInstanceState
* @see #onRestart
* @see #onPostResume
@@ -1218,11 +1221,11 @@
* been called). Applications will generally not implement this method;
* it is intended for system classes to do final setup after application
* resume code has run.
- *
+ *
* <p><em>Derived classes must call through to the super class's
* implementation of this method. If they do not, an exception will be
* thrown.</em></p>
- *
+ *
* @see #onResume
*/
protected void onPostResume() {
@@ -1256,19 +1259,19 @@
* activity is re-launched while at the top of the activity stack instead
* of a new instance of the activity being started, onNewIntent() will be
* called on the existing instance with the Intent that was used to
- * re-launch it.
- *
- * <p>An activity will always be paused before receiving a new intent, so
- * you can count on {@link #onResume} being called after this method.
- *
- * <p>Note that {@link #getIntent} still returns the original Intent. You
- * can use {@link #setIntent} to update it to this new Intent.
- *
- * @param intent The new intent that was started for the activity.
- *
+ * re-launch it.
+ *
+ * <p>An activity will always be paused before receiving a new intent, so
+ * you can count on {@link #onResume} being called after this method.
+ *
+ * <p>Note that {@link #getIntent} still returns the original Intent. You
+ * can use {@link #setIntent} to update it to this new Intent.
+ *
+ * @param intent The new intent that was started for the activity.
+ *
* @see #getIntent
- * @see #setIntent
- * @see #onResume
+ * @see #setIntent
+ * @see #onResume
*/
protected void onNewIntent(Intent intent) {
}
@@ -1342,9 +1345,9 @@
*
* <p>If called, this method will occur before {@link #onStop}. There are
* no guarantees about whether it will occur before or after {@link #onPause}.
- *
+ *
* @param outState Bundle in which to place your saved state.
- *
+ *
* @see #onCreate
* @see #onRestoreInstanceState
* @see #onPause
@@ -1429,23 +1432,23 @@
* noticeable amount of CPU in order to make the switch to the next activity
* as fast as possible, or to close resources that are exclusive access
* such as the camera.
- *
+ *
* <p>In situations where the system needs more memory it may kill paused
* processes to reclaim resources. Because of this, you should be sure
* that all of your state is saved by the time you return from
* this function. In general {@link #onSaveInstanceState} is used to save
* per-instance state in the activity and this method is used to store
* global persistent data (in content providers, files, etc.)
- *
+ *
* <p>After receiving this call you will usually receive a following call
* to {@link #onStop} (after the next activity has been resumed and
* displayed), however in some cases there will be a direct call back to
* {@link #onResume} without going through the stopped state.
- *
+ *
* <p><em>Derived classes must call through to the super class's
* implementation of this method. If they do not, an exception will be
* thrown.</em></p>
- *
+ *
* @see #onResume
* @see #onSaveInstanceState
* @see #onStop
@@ -1464,32 +1467,32 @@
* brought to the foreground, {@link #onUserLeaveHint} will not be called on
* the activity being interrupted. In cases when it is invoked, this method
* is called right before the activity's {@link #onPause} callback.
- *
+ *
* <p>This callback and {@link #onUserInteraction} are intended to help
* activities manage status bar notifications intelligently; specifically,
* for helping activities determine the proper time to cancel a notfication.
- *
+ *
* @see #onUserInteraction()
*/
protected void onUserLeaveHint() {
}
-
+
/**
* Generate a new thumbnail for this activity. This method is called before
* pausing the activity, and should draw into <var>outBitmap</var> the
* imagery for the desired thumbnail in the dimensions of that bitmap. It
* can use the given <var>canvas</var>, which is configured to draw into the
* bitmap, for rendering if desired.
- *
+ *
* <p>The default implementation returns fails and does not draw a thumbnail;
* this will result in the platform creating its own thumbnail if needed.
- *
+ *
* @param outBitmap The bitmap to contain the thumbnail.
* @param canvas Can be used to render into the bitmap.
- *
+ *
* @return Return true if you have drawn into the bitmap; otherwise after
* you return it will be filled with a default thumbnail.
- *
+ *
* @see #onCreateDescription
* @see #onSaveInstanceState
* @see #onPause
@@ -1502,15 +1505,15 @@
* Generate a new description for this activity. This method is called
* before pausing the activity and can, if desired, return some textual
* description of its current state to be displayed to the user.
- *
+ *
* <p>The default implementation returns null, which will cause you to
* inherit the description from the previous activity. If all activities
* return null, generally the label of the top activity will be used as the
* description.
- *
+ *
* @return A description of what the user is doing. It should be short and
* sweet (only a few words).
- *
+ *
* @see #onCreateThumbnail
* @see #onSaveInstanceState
* @see #onPause
@@ -1538,15 +1541,15 @@
* Called when you are no longer visible to the user. You will next
* receive either {@link #onRestart}, {@link #onDestroy}, or nothing,
* depending on later user activity.
- *
+ *
* <p>Note that this method may never be called, in low memory situations
* where the system does not have enough memory to keep your activity's
* process running after its {@link #onPause} method is called.
- *
+ *
* <p><em>Derived classes must call through to the super class's
* implementation of this method. If they do not, an exception will be
* thrown.</em></p>
- *
+ *
* @see #onRestart
* @see #onResume
* @see #onSaveInstanceState
@@ -1567,7 +1570,7 @@
* {@link #finish} on it, or because the system is temporarily destroying
* this instance of the activity to save space. You can distinguish
* between these two scenarios with the {@link #isFinishing} method.
- *
+ *
* <p><em>Note: do not count on this method being called as a place for
* saving data! For example, if an activity is editing data in a content
* provider, those edits should be committed in either {@link #onPause} or
@@ -1579,11 +1582,11 @@
* calling this method (or any others) in it, so it should not be used to
* do things that are intended to remain around after the process goes
* away.
- *
+ *
* <p><em>Derived classes must call through to the super class's
* implementation of this method. If they do not, an exception will be
* thrown.</em></p>
- *
+ *
* @see #onPause
* @see #onStop
* @see #finish
@@ -1657,11 +1660,11 @@
* by that attribute, then instead of reporting it the system will stop
* and restart the activity (to have it launched with the new
* configuration).
- *
+ *
* <p>At the time that this function has been called, your Resources
* object will have been updated to return resource values matching the
* new configuration.
- *
+ *
* @param newConfig The new device configuration.
*/
public void onConfigurationChanged(Configuration newConfig) {
@@ -1681,7 +1684,7 @@
mActionBar.onConfigurationChanged(newConfig);
}
}
-
+
/**
* If this activity is being destroyed because it can not handle a
* configuration parameter being changed (and thus its
@@ -1691,7 +1694,7 @@
* destroyed. Note that there is no guarantee that these will be
* accurate (other changes could have happened at any time), so you should
* only use this as an optimization hint.
- *
+ *
* @return Returns a bit field of the configuration parameters that are
* changing, as defined by the {@link android.content.res.Configuration}
* class.
@@ -1699,21 +1702,21 @@
public int getChangingConfigurations() {
return mConfigChangeFlags;
}
-
+
/**
* Retrieve the non-configuration instance data that was previously
* returned by {@link #onRetainNonConfigurationInstance()}. This will
* be available from the initial {@link #onCreate} and
* {@link #onStart} calls to the new instance, allowing you to extract
* any useful dynamic state from the previous instance.
- *
+ *
* <p>Note that the data you retrieve here should <em>only</em> be used
* as an optimization for handling configuration changes. You should always
* be able to handle getting a null pointer back, and an activity must
* still be able to restore itself to its previous state (through the
* normal {@link #onSaveInstanceState(Bundle)} mechanism) even if this
* function returns null.
- *
+ *
* @return Returns the object previously returned by
* {@link #onRetainNonConfigurationInstance()}.
*
@@ -1727,7 +1730,7 @@
return mLastNonConfigurationInstances != null
? mLastNonConfigurationInstances.activity : null;
}
-
+
/**
* Called by the system, as part of destroying an
* activity due to a configuration change, when it is known that a new
@@ -1736,7 +1739,7 @@
* itself, which can later be retrieved by calling
* {@link #getLastNonConfigurationInstance()} in the new activity
* instance.
- *
+ *
* <em>If you are targeting {@link android.os.Build.VERSION_CODES#HONEYCOMB}
* or later, consider instead using a {@link Fragment} with
* {@link Fragment#setRetainInstance(boolean)
@@ -1756,14 +1759,14 @@
* the {@link #getLastNonConfigurationInstance()} method of the following
* activity instance as described there.
* </ul>
- *
+ *
* <p>These guarantees are designed so that an activity can use this API
* to propagate extensive state from the old to new activity instance, from
* loaded bitmaps, to network connections, to evenly actively running
* threads. Note that you should <em>not</em> propagate any data that
* may change based on the configuration, including any data loaded from
* resources such as strings, layouts, or drawables.
- *
+ *
* <p>The guarantee of no message handling during the switch to the next
* activity simplifies use with active objects. For example if your retained
* state is an {@link android.os.AsyncTask} you are guaranteed that its
@@ -1783,21 +1786,21 @@
public Object onRetainNonConfigurationInstance() {
return null;
}
-
+
/**
* Retrieve the non-configuration instance data that was previously
* returned by {@link #onRetainNonConfigurationChildInstances()}. This will
* be available from the initial {@link #onCreate} and
* {@link #onStart} calls to the new instance, allowing you to extract
* any useful dynamic state from the previous instance.
- *
+ *
* <p>Note that the data you retrieve here should <em>only</em> be used
* as an optimization for handling configuration changes. You should always
* be able to handle getting a null pointer back, and an activity must
* still be able to restore itself to its previous state (through the
* normal {@link #onSaveInstanceState(Bundle)} mechanism) even if this
* function returns null.
- *
+ *
* @return Returns the object previously returned by
* {@link #onRetainNonConfigurationChildInstances()}
*/
@@ -1806,7 +1809,7 @@
return mLastNonConfigurationInstances != null
? mLastNonConfigurationInstances.children : null;
}
-
+
/**
* This method is similar to {@link #onRetainNonConfigurationInstance()} except that
* it should return either a mapping from child activity id strings to arbitrary objects,
@@ -1818,7 +1821,7 @@
HashMap<String,Object> onRetainNonConfigurationChildInstances() {
return null;
}
-
+
NonConfigurationInstances retainNonConfigurationInstances() {
Object activity = onRetainNonConfigurationInstance();
HashMap<String, Object> children = onRetainNonConfigurationChildInstances();
@@ -1846,7 +1849,7 @@
&& mVoiceInteractor == null) {
return null;
}
-
+
NonConfigurationInstances nci = new NonConfigurationInstances();
nci.activity = activity;
nci.children = children;
@@ -1886,7 +1889,7 @@
}
}
}
-
+
/**
* Called when a Fragment is being attached to this activity, immediately
* after the call to its {@link Fragment#onAttach Fragment.onAttach()}
@@ -1894,14 +1897,14 @@
*/
public void onAttachFragment(Fragment fragment) {
}
-
+
/**
* Wrapper around
* {@link ContentResolver#query(android.net.Uri , String[], String, String[], String)}
* that gives the resulting {@link Cursor} to call
* {@link #startManagingCursor} so that the activity will manage its
* lifecycle for you.
- *
+ *
* <em>If you are targeting {@link android.os.Build.VERSION_CODES#HONEYCOMB}
* or later, consider instead using {@link LoaderManager} instead, available
* via {@link #getLoaderManager()}.</em>
@@ -1911,14 +1914,14 @@
* you call {@link #stopManagingCursor} on a cursor from a managed query, the system <em>will
* not</em> automatically close the cursor and, in that case, you must call
* {@link Cursor#close()}.</p>
- *
+ *
* @param uri The URI of the content provider to query.
* @param projection List of columns to return.
* @param selection SQL WHERE clause.
* @param sortOrder SQL ORDER BY clause.
- *
+ *
* @return The Cursor that was returned by query().
- *
+ *
* @see ContentResolver#query(android.net.Uri , String[], String, String[], String)
* @see #startManagingCursor
* @hide
@@ -1941,7 +1944,7 @@
* that gives the resulting {@link Cursor} to call
* {@link #startManagingCursor} so that the activity will manage its
* lifecycle for you.
- *
+ *
* <em>If you are targeting {@link android.os.Build.VERSION_CODES#HONEYCOMB}
* or later, consider instead using {@link LoaderManager} instead, available
* via {@link #getLoaderManager()}.</em>
@@ -1951,15 +1954,15 @@
* you call {@link #stopManagingCursor} on a cursor from a managed query, the system <em>will
* not</em> automatically close the cursor and, in that case, you must call
* {@link Cursor#close()}.</p>
- *
+ *
* @param uri The URI of the content provider to query.
* @param projection List of columns to return.
* @param selection SQL WHERE clause.
* @param selectionArgs The arguments to selection, if any ?s are pesent
* @param sortOrder SQL ORDER BY clause.
- *
+ *
* @return The Cursor that was returned by query().
- *
+ *
* @see ContentResolver#query(android.net.Uri , String[], String, String[], String)
* @see #startManagingCursor
*
@@ -1982,7 +1985,7 @@
* {@link Cursor#deactivate} on the given Cursor, and when it is later restarted
* it will call {@link Cursor#requery} for you. When the activity is
* destroyed, all managed Cursors will be closed automatically.
- *
+ *
* <em>If you are targeting {@link android.os.Build.VERSION_CODES#HONEYCOMB}
* or later, consider instead using {@link LoaderManager} instead, available
* via {@link #getLoaderManager()}.</em>
@@ -1992,9 +1995,9 @@
* However, if you call {@link #stopManagingCursor} on a cursor from a managed query, the system
* <em>will not</em> automatically close the cursor and, in that case, you must call
* {@link Cursor#close()}.</p>
- *
+ *
* @param c The Cursor to be managed.
- *
+ *
* @see #managedQuery(android.net.Uri , String[], String, String[], String)
* @see #stopManagingCursor
*
@@ -2013,13 +2016,13 @@
* Given a Cursor that was previously given to
* {@link #startManagingCursor}, stop the activity's management of that
* cursor.
- *
+ *
* <p><strong>Warning:</strong> After calling this method on a cursor from a managed query,
- * the system <em>will not</em> automatically close the cursor and you must call
+ * the system <em>will not</em> automatically close the cursor and you must call
* {@link Cursor#close()}.</p>
- *
+ *
* @param c The Cursor that was being managed.
- *
+ *
* @see #startManagingCursor
*
* @deprecated Use the new {@link android.content.CursorLoader} class with
@@ -2058,7 +2061,7 @@
public View findViewById(int id) {
return getWindow().findViewById(id);
}
-
+
/**
* Retrieve a reference to this activity's ActionBar.
*
@@ -2094,7 +2097,7 @@
mActionBar = new ToolbarActionBar(toolbar, getTitle(), this);
mActionBar.invalidateOptionsMenu();
}
-
+
/**
* Creates a new ActionBar, locates the inflated ActionBarView,
* initializes the ActionBar with the view, and sets mActionBar.
@@ -2116,13 +2119,13 @@
mWindow.setDefaultIcon(mActivityInfo.getIconResource());
mWindow.setDefaultLogo(mActivityInfo.getLogoResource());
}
-
+
/**
* Set the activity content from a layout resource. The resource will be
* inflated, adding all top-level views to the activity.
*
* @param layoutResID Resource ID to be inflated.
- *
+ *
* @see #setContentView(android.view.View)
* @see #setContentView(android.view.View, android.view.ViewGroup.LayoutParams)
*/
@@ -2140,7 +2143,7 @@
* your own layout parameters, invoke
* {@link #setContentView(android.view.View, android.view.ViewGroup.LayoutParams)}
* instead.
- *
+ *
* @param view The desired content to display.
*
* @see #setContentView(int)
@@ -2155,7 +2158,7 @@
* Set the activity content to an explicit view. This view is placed
* directly into the activity's view hierarchy. It can itself be a complex
* view hierarchy.
- *
+ *
* @param view The desired content to display.
* @param params Layout parameters for the view.
*
@@ -2170,7 +2173,7 @@
/**
* Add an additional content view to the activity. Added after any existing
* ones in the activity -- existing views are NOT removed.
- *
+ *
* @param view The desired content to display.
* @param params Layout parameters for the view.
*/
@@ -2235,23 +2238,23 @@
/**
* Use with {@link #setDefaultKeyMode} to turn off default handling of
* keys.
- *
+ *
* @see #setDefaultKeyMode
*/
static public final int DEFAULT_KEYS_DISABLE = 0;
/**
* Use with {@link #setDefaultKeyMode} to launch the dialer during default
* key handling.
- *
+ *
* @see #setDefaultKeyMode
*/
static public final int DEFAULT_KEYS_DIALER = 1;
/**
* Use with {@link #setDefaultKeyMode} to execute a menu shortcut in
* default key handling.
- *
+ *
* <p>That is, the user does not need to hold down the menu key to execute menu shortcuts.
- *
+ *
* @see #setDefaultKeyMode
*/
static public final int DEFAULT_KEYS_SHORTCUT = 2;
@@ -2259,9 +2262,9 @@
* Use with {@link #setDefaultKeyMode} to specify that unhandled keystrokes
* will start an application-defined search. (If the application or activity does not
* actually define a search, the the keys will be ignored.)
- *
+ *
* <p>See {@link android.app.SearchManager android.app.SearchManager} for more details.
- *
+ *
* @see #setDefaultKeyMode
*/
static public final int DEFAULT_KEYS_SEARCH_LOCAL = 3;
@@ -2270,9 +2273,9 @@
* Use with {@link #setDefaultKeyMode} to specify that unhandled keystrokes
* will start a global search (typically web search, but some platforms may define alternate
* methods for global search)
- *
+ *
* <p>See {@link android.app.SearchManager android.app.SearchManager} for more details.
- *
+ *
* @see #setDefaultKeyMode
*/
static public final int DEFAULT_KEYS_SEARCH_GLOBAL = 4;
@@ -2284,16 +2287,16 @@
* floor. Other modes allow you to launch the dialer
* ({@link #DEFAULT_KEYS_DIALER}), execute a shortcut in your options
* menu without requiring the menu key be held down
- * ({@link #DEFAULT_KEYS_SHORTCUT}), or launch a search ({@link #DEFAULT_KEYS_SEARCH_LOCAL}
+ * ({@link #DEFAULT_KEYS_SHORTCUT}), or launch a search ({@link #DEFAULT_KEYS_SEARCH_LOCAL}
* and {@link #DEFAULT_KEYS_SEARCH_GLOBAL}).
- *
+ *
* <p>Note that the mode selected here does not impact the default
* handling of system keys, such as the "back" and "menu" keys, and your
* activity and its views always get a first chance to receive and handle
* all application keys.
- *
+ *
* @param mode The desired default key mode constant.
- *
+ *
* @see #DEFAULT_KEYS_DISABLE
* @see #DEFAULT_KEYS_DIALER
* @see #DEFAULT_KEYS_SHORTCUT
@@ -2303,7 +2306,7 @@
*/
public final void setDefaultKeyMode(@DefaultKeyMode int mode) {
mDefaultKeyMode = mode;
-
+
// Some modes use a SpannableStringBuilder to track & dispatch input events
// This list must remain in sync with the switch in onKeyDown()
switch (mode) {
@@ -2324,10 +2327,10 @@
/**
* Called when a key was pressed down and not handled by any of the views
- * inside of the activity. So, for example, key presses while the cursor
+ * inside of the activity. So, for example, key presses while the cursor
* is inside a TextView will not trigger the event (unless it is a navigation
* to another object) because TextView handles its own key presses.
- *
+ *
* <p>If the focused view didn't want this event, this method is called.
*
* <p>The default implementation takes care of {@link KeyEvent#KEYCODE_BACK}
@@ -2338,12 +2341,12 @@
* will be performed; for earlier applications, it will perform the
* action immediately in on-down, as those versions of the platform
* behaved.
- *
+ *
* <p>Other additional default key handling may be performed
* if configured with {@link #setDefaultKeyMode}.
- *
+ *
* @return Return <code>true</code> to prevent this event from being propagated
- * further, or <code>false</code> to indicate that you have not handled
+ * further, or <code>false</code> to indicate that you have not handled
* this event and it should continue to be propagated.
* @see #onKeyUp
* @see android.view.KeyEvent
@@ -2358,11 +2361,11 @@
}
return true;
}
-
+
if (mDefaultKeyMode == DEFAULT_KEYS_DISABLE) {
return false;
} else if (mDefaultKeyMode == DEFAULT_KEYS_SHORTCUT) {
- if (getWindow().performPanelShortcut(Window.FEATURE_OPTIONS_PANEL,
+ if (getWindow().performPanelShortcut(Window.FEATURE_OPTIONS_PANEL,
keyCode, event, Menu.FLAG_ALWAYS_PERFORM_CLOSE)) {
return true;
}
@@ -2382,12 +2385,12 @@
final String str = mDefaultKeySsb.toString();
clearSpannable = true;
-
+
switch (mDefaultKeyMode) {
case DEFAULT_KEYS_DIALER:
Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + str));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- startActivity(intent);
+ startActivity(intent);
break;
case DEFAULT_KEYS_SEARCH_LOCAL:
startSearch(str, false, null, false);
@@ -2418,16 +2421,16 @@
/**
* Called when a key was released and not handled by any of the views
- * inside of the activity. So, for example, key presses while the cursor
+ * inside of the activity. So, for example, key presses while the cursor
* is inside a TextView will not trigger the event (unless it is a navigation
* to another object) because TextView handles its own key presses.
- *
+ *
* <p>The default implementation handles KEYCODE_BACK to stop the activity
* and go back.
- *
+ *
* @return Return <code>true</code> to prevent this event from being propagated
- * further, or <code>false</code> to indicate that you have not handled
- * this event and it should continue to be propagated.
+ * further, or <code>false</code> to indicate that you have not handled
+ * this event and it should continue to be propagated.
* @see #onKeyDown
* @see KeyEvent
*/
@@ -2451,7 +2454,7 @@
public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) {
return false;
}
-
+
/**
* Called when the activity has detected the user's press of the back
* key. The default implementation simply finishes the current activity,
@@ -2485,9 +2488,9 @@
* Called when a touch screen event was not handled by any of the views
* under it. This is most useful to process touch events that happen
* outside of your window bounds, where there is no view to receive it.
- *
+ *
* @param event The touch screen event being processed.
- *
+ *
* @return Return true if you have consumed the event, false if you haven't.
* The default implementation always returns false.
*/
@@ -2496,10 +2499,10 @@
finish();
return true;
}
-
+
return false;
}
-
+
/**
* Called when the trackball was moved and not handled by any of the
* views inside of the activity. So, for example, if the trackball moves
@@ -2508,9 +2511,9 @@
* here happens <em>before</em> trackball movements are converted to
* DPAD key events, which then get sent back to the view hierarchy, and
* will be processed at the point for things like focus navigation.
- *
+ *
* @param event The trackball event being processed.
- *
+ *
* @return Return true if you have consumed the event, false if you haven't.
* The default implementation always returns false.
*/
@@ -2554,21 +2557,21 @@
* This callback and {@link #onUserLeaveHint} are intended to help
* activities manage status bar notifications intelligently; specifically,
* for helping activities determine the proper time to cancel a notfication.
- *
+ *
* <p>All calls to your activity's {@link #onUserLeaveHint} callback will
* be accompanied by calls to {@link #onUserInteraction}. This
* ensures that your activity will be told of relevant user activity such
* as pulling down the notification pane and touching an item there.
- *
+ *
* <p>Note that this callback will be invoked for the touch down action
* that begins a touch gesture, but may not be invoked for the touch-moved
* and touch-up actions that follow.
- *
+ *
* @see #onUserLeaveHint()
*/
public void onUserInteraction() {
}
-
+
public void onWindowAttributesChanged(WindowManager.LayoutParams params) {
// Update window manager if: we have a view, that view is
// attached to its parent (which will be a RootView), and
@@ -2589,14 +2592,14 @@
* focus. This is the best indicator of whether this activity is visible
* to the user. The default implementation clears the key tracking
* state, so should always be called.
- *
+ *
* <p>Note that this provides information about global focus state, which
* is managed independently of activity lifecycles. As such, while focus
* changes will generally have some relation to lifecycle changes (an
* activity that is stopped will not generally get window focus), you
* should not rely on any particular order between the callbacks here and
* those in the other lifecycle methods such as {@link #onResume}.
- *
+ *
* <p>As a general rule, however, a resumed activity will have window
* focus... unless it has displayed other dialogs or popups that take
* input focus, in which case the activity itself will not have focus
@@ -2606,14 +2609,14 @@
* pausing the foreground activity.
*
* @param hasFocus Whether the window of this activity has focus.
- *
+ *
* @see #hasWindowFocus()
* @see #onResume
* @see View#onWindowFocusChanged(boolean)
*/
public void onWindowFocusChanged(boolean hasFocus) {
}
-
+
/**
* Called when the main window associated with the activity has been
* attached to the window manager.
@@ -2623,7 +2626,7 @@
*/
public void onAttachedToWindow() {
}
-
+
/**
* Called when the main window associated with the activity has been
* detached from the window manager.
@@ -2633,13 +2636,13 @@
*/
public void onDetachedFromWindow() {
}
-
+
/**
* Returns true if this activity's <em>main</em> window currently has window focus.
* Note that this is not the same as the view itself having focus.
- *
+ *
* @return True if this activity's main window currently has window focus.
- *
+ *
* @see #onWindowAttributesChanged(android.view.WindowManager.LayoutParams)
*/
public boolean hasWindowFocus() {
@@ -2661,14 +2664,14 @@
public void onWindowDismissed() {
finish();
}
-
+
/**
- * Called to process key events. You can override this to intercept all
- * key events before they are dispatched to the window. Be sure to call
+ * Called to process key events. You can override this to intercept all
+ * key events before they are dispatched to the window. Be sure to call
* this implementation for key events that should be handled normally.
- *
+ *
* @param event The key event.
- *
+ *
* @return boolean Return true if this event was consumed.
*/
public boolean dispatchKeyEvent(KeyEvent event) {
@@ -2713,9 +2716,9 @@
* intercept all touch screen events before they are dispatched to the
* window. Be sure to call this implementation for touch screen events
* that should be handled normally.
- *
+ *
* @param ev The touch screen event.
- *
+ *
* @return boolean Return true if this event was consumed.
*/
public boolean dispatchTouchEvent(MotionEvent ev) {
@@ -2727,15 +2730,15 @@
}
return onTouchEvent(ev);
}
-
+
/**
* Called to process trackball events. You can override this to
* intercept all trackball events before they are dispatched to the
* window. Be sure to call this implementation for trackball events
* that should be handled normally.
- *
+ *
* @param ev The trackball event.
- *
+ *
* @return boolean Return true if this event was consumed.
*/
public boolean dispatchTrackballEvent(MotionEvent ev) {
@@ -2830,7 +2833,7 @@
/**
* {@inheritDoc}
- *
+ *
* @return The default implementation returns true.
*/
public boolean onMenuOpened(int featureId, Menu menu) {
@@ -2880,7 +2883,7 @@
}
}
return false;
-
+
case Window.FEATURE_CONTEXT_MENU:
if(titleCondensed != null) {
EventLog.writeEvent(50000, 1, titleCondensed.toString());
@@ -2894,7 +2897,7 @@
return false;
}
}
-
+
/**
* Default implementation of
* {@link android.view.Window.Callback#onPanelClosed(int, Menu)} for
@@ -2910,7 +2913,7 @@
mFragments.dispatchOptionsMenuClosed(menu);
onOptionsMenuClosed(menu);
break;
-
+
case Window.FEATURE_CONTEXT_MENU:
onContextMenuClosed(menu);
break;
@@ -2932,32 +2935,32 @@
mWindow.invalidatePanelMenu(Window.FEATURE_OPTIONS_PANEL);
}
}
-
+
/**
* Initialize the contents of the Activity's standard options menu. You
* should place your menu items in to <var>menu</var>.
- *
+ *
* <p>This is only called once, the first time the options menu is
* displayed. To update the menu every time it is displayed, see
* {@link #onPrepareOptionsMenu}.
- *
+ *
* <p>The default implementation populates the menu with standard system
- * menu items. These are placed in the {@link Menu#CATEGORY_SYSTEM} group so that
- * they will be correctly ordered with application-defined menu items.
- * Deriving classes should always call through to the base implementation.
- *
+ * menu items. These are placed in the {@link Menu#CATEGORY_SYSTEM} group so that
+ * they will be correctly ordered with application-defined menu items.
+ * Deriving classes should always call through to the base implementation.
+ *
* <p>You can safely hold on to <var>menu</var> (and any items created
* from it), making modifications to it as desired, until the next
* time onCreateOptionsMenu() is called.
- *
+ *
* <p>When you add items to the menu, you can implement the Activity's
* {@link #onOptionsItemSelected} method to handle them there.
- *
+ *
* @param menu The options menu in which you place your items.
- *
+ *
* @return You must return true for the menu to be displayed;
* if you return false it will not be shown.
- *
+ *
* @see #onPrepareOptionsMenu
* @see #onOptionsItemSelected
*/
@@ -2973,17 +2976,17 @@
* called right before the menu is shown, every time it is shown. You can
* use this method to efficiently enable/disable items or otherwise
* dynamically modify the contents.
- *
+ *
* <p>The default implementation updates the system menu items based on the
* activity's state. Deriving classes should always call through to the
* base class implementation.
- *
+ *
* @param menu The options menu as last shown or first initialized by
* onCreateOptionsMenu().
- *
+ *
* @return You must return true for the menu to be displayed;
* if you return false it will not be shown.
- *
+ *
* @see #onCreateOptionsMenu
*/
public boolean onPrepareOptionsMenu(Menu menu) {
@@ -3000,15 +3003,15 @@
* its Handler as appropriate). You can use this method for any items
* for which you would like to do processing without those other
* facilities.
- *
+ *
* <p>Derived classes should call through to the base class for it to
* perform the default menu handling.</p>
- *
+ *
* @param item The menu item that was selected.
- *
+ *
* @return boolean Return false to allow normal menu processing to
* proceed, true to consume it here.
- *
+ *
* @see #onCreateOptionsMenu
*/
public boolean onOptionsItemSelected(MenuItem item) {
@@ -3125,7 +3128,7 @@
/**
* This hook is called whenever the options menu is being closed (either by the user canceling
* the menu with the back/menu button, or when an item is selected).
- *
+ *
* @param menu The options menu as last shown or first initialized by
* onCreateOptionsMenu().
*/
@@ -3134,7 +3137,7 @@
mParent.onOptionsMenuClosed(menu);
}
}
-
+
/**
* Programmatically opens the options menu. If the options menu is already
* open, this method does nothing.
@@ -3144,7 +3147,7 @@
mWindow.openPanel(Window.FEATURE_OPTIONS_PANEL, null);
}
}
-
+
/**
* Progammatically closes the options menu. If the options menu is already
* closed, this method does nothing.
@@ -3175,43 +3178,43 @@
* {@link OnCreateContextMenuListener} on the view to this activity, so
* {@link #onCreateContextMenu(ContextMenu, View, ContextMenuInfo)} will be
* called when it is time to show the context menu.
- *
+ *
* @see #unregisterForContextMenu(View)
* @param view The view that should show a context menu.
*/
public void registerForContextMenu(View view) {
view.setOnCreateContextMenuListener(this);
}
-
+
/**
* Prevents a context menu to be shown for the given view. This method will remove the
* {@link OnCreateContextMenuListener} on the view.
- *
+ *
* @see #registerForContextMenu(View)
* @param view The view that should stop showing a context menu.
*/
public void unregisterForContextMenu(View view) {
view.setOnCreateContextMenuListener(null);
}
-
+
/**
* Programmatically opens the context menu for a particular {@code view}.
* The {@code view} should have been added via
* {@link #registerForContextMenu(View)}.
- *
+ *
* @param view The view to show the context menu for.
*/
public void openContextMenu(View view) {
view.showContextMenu();
}
-
+
/**
* Programmatically closes the most recently opened context menu, if showing.
*/
public void closeContextMenu() {
mWindow.closePanel(Window.FEATURE_CONTEXT_MENU);
}
-
+
/**
* This hook is called whenever an item in a context menu is selected. The
* default implementation simply returns false to have the normal processing
@@ -3224,7 +3227,7 @@
* <p>
* Derived classes should call through to the base class for it to perform
* the default menu handling.
- *
+ *
* @param item The context menu item that was selected.
* @return boolean Return false to allow normal context menu processing to
* proceed, true to consume it here.
@@ -3240,7 +3243,7 @@
* This hook is called whenever the context menu is being closed (either by
* the user canceling the menu with the back/menu button, or when an item is
* selected).
- *
+ *
* @param menu The context menu that is being closed.
*/
public void onContextMenuClosed(Menu menu) {
@@ -3309,14 +3312,14 @@
* Provides an opportunity to prepare a managed dialog before it is being
* shown. The default implementation calls through to
* {@link #onPrepareDialog(int, Dialog)} for compatibility.
- *
+ *
* <p>
* Override this if you need to update a managed dialog based on the state
* of the application each time it is shown. For example, a time picker
* dialog might want to be updated with the current time. You should call
* through to the superclass's implementation. The default implementation
* will set this Activity as the owner activity on the Dialog.
- *
+ *
* @param id The id of the managed dialog.
* @param dialog The dialog.
* @param args The dialog arguments provided to {@link #showDialog(int, Bundle)}.
@@ -3367,7 +3370,7 @@
* If you need to rebuild the dialog, call {@link #removeDialog(int)} first.
* @return Returns true if the Dialog was created; false is returned if
* it is not created because {@link #onCreateDialog(int, Bundle)} returns false.
- *
+ *
* @see Dialog
* @see #onCreateDialog(int, Bundle)
* @see #onPrepareDialog(int, Dialog, Bundle)
@@ -3393,7 +3396,7 @@
}
mManagedDialogs.put(id, md);
}
-
+
md.mArgs = args;
onPrepareDialog(id, md.mDialog, args);
md.mDialog.show();
@@ -3422,7 +3425,7 @@
if (mManagedDialogs == null) {
throw missingDialog(id);
}
-
+
final ManagedDialog md = mManagedDialogs.get(id);
if (md == null) {
throw missingDialog(id);
@@ -3449,7 +3452,7 @@
* <p>As of {@link android.os.Build.VERSION_CODES#GINGERBREAD}, this function
* will not throw an exception if you try to remove an ID that does not
* currently have an associated dialog.</p>
- *
+ *
* @param id The id of the managed dialog.
*
* @see #onCreateDialog(int, Bundle)
@@ -3474,37 +3477,37 @@
/**
* This hook is called when the user signals the desire to start a search.
- *
+ *
* <p>You can use this function as a simple way to launch the search UI, in response to a
- * menu item, search button, or other widgets within your activity. Unless overidden,
+ * menu item, search button, or other widgets within your activity. Unless overidden,
* calling this function is the same as calling
* {@link #startSearch startSearch(null, false, null, false)}, which launches
* search for the current activity as specified in its manifest, see {@link SearchManager}.
- *
+ *
* <p>You can override this function to force global search, e.g. in response to a dedicated
* search key, or to block search entirely (by simply returning false).
- *
+ *
* @return Returns {@code true} if search launched, and {@code false} if activity blocks it.
* The default implementation always returns {@code true}.
- *
+ *
* @see android.app.SearchManager
*/
public boolean onSearchRequested() {
- startSearch(null, false, null, false);
+ startSearch(null, false, null, false);
return true;
}
-
+
/**
* This hook is called to launch the search UI.
- *
- * <p>It is typically called from onSearchRequested(), either directly from
- * Activity.onSearchRequested() or from an overridden version in any given
+ *
+ * <p>It is typically called from onSearchRequested(), either directly from
+ * Activity.onSearchRequested() or from an overridden version in any given
* Activity. If your goal is simply to activate search, it is preferred to call
* onSearchRequested(), which may have been overridden elsewhere in your Activity. If your goal
* is to inject specific data such as context data, it is preferred to <i>override</i>
* onSearchRequested(), so that any callers to it will benefit from the override.
- *
- * @param initialQuery Any non-null non-empty string will be inserted as
+ *
+ * @param initialQuery Any non-null non-empty string will be inserted as
* pre-entered text in the search query box.
* @param selectInitialQuery If true, the initial query will be preselected, which means that
* any further typing will replace it. This is useful for cases where an entire pre-formed
@@ -3512,15 +3515,15 @@
* inserted query. This is useful when the inserted query is text that the user entered,
* and the user would expect to be able to keep typing. <i>This parameter is only meaningful
* if initialQuery is a non-empty string.</i>
- * @param appSearchData An application can insert application-specific
- * context here, in order to improve quality or specificity of its own
+ * @param appSearchData An application can insert application-specific
+ * context here, in order to improve quality or specificity of its own
* searches. This data will be returned with SEARCH intent(s). Null if
* no extra data is required.
* @param globalSearch If false, this will only launch the search that has been specifically
- * defined by the application (which is usually defined as a local search). If no default
+ * defined by the application (which is usually defined as a local search). If no default
* search is defined in the current application or activity, global search will be launched.
* If true, this will always launch a platform-global (e.g. web-based) search instead.
- *
+ *
* @see android.app.SearchManager
* @see #onSearchRequested
*/
@@ -3528,7 +3531,7 @@
@Nullable Bundle appSearchData, boolean globalSearch) {
ensureSearchManager();
mSearchManager.startSearch(initialQuery, selectInitialQuery, getComponentName(),
- appSearchData, globalSearch);
+ appSearchData, globalSearch);
}
/**
@@ -3550,7 +3553,7 @@
* Request that key events come to this activity. Use this if your
* activity has no views with focus, but the activity still wants
* a chance to process key events.
- *
+ *
* @see android.view.Window#takeKeyEvents
*/
public void takeKeyEvents(boolean get) {
@@ -3560,12 +3563,12 @@
/**
* Enable extended window features. This is a convenience for calling
* {@link android.view.Window#requestFeature getWindow().requestFeature()}.
- *
+ *
* @param featureId The desired feature as defined in
* {@link android.view.Window}.
* @return Returns true if the requested feature is supported and now
* enabled.
- *
+ *
* @see android.view.Window#requestFeature
*/
public final boolean requestWindowFeature(int featureId) {
@@ -3677,7 +3680,7 @@
* Launch an activity for which you would like a result when it finished.
* When this activity exits, your
* onActivityResult() method will be called with the given requestCode.
- * Using a negative requestCode is the same as calling
+ * Using a negative requestCode is the same as calling
* {@link #startActivity} (the activity is not launched as a sub-activity).
*
* <p>Note that this method should only be used with Intent protocols
@@ -3687,7 +3690,7 @@
* are launching uses the singleTask launch mode, it will not run in your
* task and thus you will immediately receive a cancel result.
*
- * <p>As a special case, if you call startActivityForResult() with a requestCode
+ * <p>As a special case, if you call startActivityForResult() with a requestCode
* >= 0 during the initial onCreate(Bundle savedInstanceState)/onResume() of your
* activity, then your window will not be displayed until a result is
* returned back from the started activity. This is to avoid visible
@@ -3845,7 +3848,7 @@
* here; otherwise, its associated action will be executed (such as
* sending a broadcast) as if you had called
* {@link IntentSender#sendIntent IntentSender.sendIntent} on it.
- *
+ *
* @param intent The IntentSender to launch.
* @param requestCode If >= 0, this code will be returned in
* onActivityResult() when the activity exits.
@@ -3936,19 +3939,19 @@
* information, the {@link Intent#FLAG_ACTIVITY_NEW_TASK} launch flag is not
* required; if not specified, the new activity will be added to the
* task of the caller.
- *
+ *
* <p>This method throws {@link android.content.ActivityNotFoundException}
* if there was no Activity found to run the given Intent.
- *
- * @param intent The intent to start.
+ *
+ * @param intent The intent to start.
* @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.
- *
+ *
* @throws android.content.ActivityNotFoundException
*
* @see {@link #startActivity(Intent)}
- * @see #startActivityForResult
+ * @see #startActivityForResult
*/
@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
@@ -4008,7 +4011,7 @@
/**
* Same as calling {@link #startIntentSender(IntentSender, Intent, int, int, int, Bundle)}
* with no options.
- *
+ *
* @param intent The IntentSender to launch.
* @param fillInIntent If non-null, this will be provided as the
* intent parameter to {@link IntentSender#sendIntent}.
@@ -4081,19 +4084,19 @@
/**
* A special variation to launch an activity only if a new activity
* instance is needed to handle the given Intent. In other words, this is
- * just like {@link #startActivityForResult(Intent, int)} except: if you are
+ * just like {@link #startActivityForResult(Intent, int)} except: if you are
* using the {@link Intent#FLAG_ACTIVITY_SINGLE_TOP} flag, or
- * singleTask or singleTop
+ * singleTask or singleTop
* {@link android.R.styleable#AndroidManifestActivity_launchMode launchMode},
- * and the activity
- * that handles <var>intent</var> is the same as your currently running
- * activity, then a new instance is not needed. In this case, instead of
- * the normal behavior of calling {@link #onNewIntent} this function will
- * return and you can handle the Intent yourself.
- *
+ * and the activity
+ * that handles <var>intent</var> is the same as your currently running
+ * activity, then a new instance is not needed. In this case, instead of
+ * the normal behavior of calling {@link #onNewIntent} this function will
+ * return and you can handle the Intent yourself.
+ *
* <p>This function can only be called from a top-level activity; if it is
* called from a child activity, a runtime exception will be thrown.
- *
+ *
* @param intent The intent to start.
* @param requestCode If >= 0, this code will be returned in
* onActivityResult() when the activity exits, as described in
@@ -4101,10 +4104,10 @@
* @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.
- *
+ *
* @return If a new activity was launched then true is returned; otherwise
* false is returned and you must handle the Intent yourself.
- *
+ *
* @see #startActivity
* @see #startActivityForResult
*/
@@ -4167,7 +4170,7 @@
* other activity components. You can use this to hand the Intent off
* to the next Activity that can handle it. You typically call this in
* {@link #onCreate} with the Intent returned by {@link #getIntent}.
- *
+ *
* @param intent The intent to dispatch to the next activity. For
* correct behavior, this must be the same as the Intent that started
* your own activity; the only changes you can make are to the extras
@@ -4175,7 +4178,7 @@
* @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.
- *
+ *
* @return Returns a boolean indicating whether there was another Activity
* to start: true if there was a next activity to start, false if there
* wasn't. In general, if true is returned you will then want to call
@@ -4217,23 +4220,23 @@
}
/**
- * This is called when a child activity of this one calls its
+ * This is called when a child activity of this one calls its
* {@link #startActivity} or {@link #startActivityForResult} method.
- *
+ *
* <p>This method throws {@link android.content.ActivityNotFoundException}
* if there was no Activity found to run the given Intent.
- *
+ *
* @param child The activity making the call.
* @param intent The intent to start.
* @param requestCode Reply request code. < 0 if reply is not requested.
* @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.
- *
+ *
* @throws android.content.ActivityNotFoundException
- *
- * @see #startActivity
- * @see #startActivityForResult
+ *
+ * @see #startActivity
+ * @see #startActivityForResult
*/
public void startActivityFromChild(@NonNull Activity child, Intent intent,
int requestCode, @Nullable Bundle options) {
@@ -4267,24 +4270,24 @@
}
/**
- * This is called when a Fragment in this activity calls its
+ * This is called when a Fragment in this activity calls its
* {@link Fragment#startActivity} or {@link Fragment#startActivityForResult}
* method.
- *
+ *
* <p>This method throws {@link android.content.ActivityNotFoundException}
* if there was no Activity found to run the given Intent.
- *
+ *
* @param fragment The fragment making the call.
* @param intent The intent to start.
- * @param requestCode Reply request code. < 0 if reply is not requested.
+ * @param requestCode Reply request code. < 0 if reply is not requested.
* @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.
- *
+ *
* @throws android.content.ActivityNotFoundException
- *
- * @see Fragment#startActivity
- * @see Fragment#startActivityForResult
+ *
+ * @see Fragment#startActivity
+ * @see Fragment#startActivityForResult
*/
public void startActivityFromFragment(@NonNull Fragment fragment, Intent intent,
int requestCode, @Nullable Bundle options) {
@@ -4352,14 +4355,14 @@
} catch (RemoteException e) {
}
}
-
+
/**
* Call this to set the result that your activity will return to its
* caller.
- *
+ *
* @param resultCode The result code to propagate back to the originating
* activity, often RESULT_CANCELED or RESULT_OK
- *
+ *
* @see #RESULT_CANCELED
* @see #RESULT_OK
* @see #RESULT_FIRST_USER
@@ -4388,7 +4391,7 @@
* @param resultCode The result code to propagate back to the originating
* activity, often RESULT_CANCELED or RESULT_OK
* @param data The data to propagate back to the originating activity.
- *
+ *
* @see #RESULT_CANCELED
* @see #RESULT_OK
* @see #RESULT_FIRST_USER
@@ -4406,10 +4409,10 @@
* the data in {@link #setResult setResult()} will be sent to. You can
* use this information to validate that the recipient is allowed to
* receive the data.
- *
+ *
* <p class="note">Note: if the calling activity is not expecting a result (that is it
- * did not use the {@link #startActivityForResult}
- * form that includes a request code), then the calling package will be
+ * did not use the {@link #startActivityForResult}
+ * form that includes a request code), then the calling package will be
* null.</p>
*
* <p class="note">Note: prior to {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2},
@@ -4417,7 +4420,7 @@
* package was no longer running, it would return null instead of the proper package
* name. You can use {@link #getCallingActivity()} and retrieve the package name
* from that instead.</p>
- *
+ *
* @return The package of the activity that will receive your
* reply, or null if none.
*/
@@ -4435,12 +4438,12 @@
* who the data in {@link #setResult setResult()} will be sent to. You
* can use this information to validate that the recipient is allowed to
* receive the data.
- *
+ *
* <p class="note">Note: if the calling activity is not expecting a result (that is it
- * did not use the {@link #startActivityForResult}
- * form that includes a request code), then the calling package will be
- * null.
- *
+ * did not use the {@link #startActivityForResult}
+ * form that includes a request code), then the calling package will be
+ * null.
+ *
* @return The ComponentName of the activity that will receive your
* reply, or null if none.
*/
@@ -4459,7 +4462,7 @@
* UI itself, but can't just finish prior to onResume() because it needs
* to wait for a service binding or such. Setting this to false allows
* you to prevent your UI from being shown during that time.
- *
+ *
* <p>The default value for this is taken from the
* {@link android.R.attr#windowNoDisplay} attribute of the activity's theme.
*/
@@ -4472,7 +4475,7 @@
}
}
}
-
+
void makeVisible() {
if (!mWindowAdded) {
ViewManager wm = getWindowManager();
@@ -4481,16 +4484,16 @@
}
mDecor.setVisibility(View.VISIBLE);
}
-
+
/**
* Check to see whether this activity is in the process of finishing,
* either because you called {@link #finish} on it or someone else
* has requested that it finished. This is often used in
* {@link #onPause} to determine whether the activity is simply pausing or
* completely finishing.
- *
+ *
* @return If the activity is finishing, returns true; else returns false.
- *
+ *
* @see #finish
*/
public boolean isFinishing() {
@@ -4510,7 +4513,7 @@
* recreated with a new configuration. This is often used in
* {@link #onStop} to determine whether the state needs to be cleaned up or will be passed
* on to the next instance of the activity via {@link #onRetainNonConfigurationInstance()}.
- *
+ *
* @return If the activity is being torn down in order to be recreated with a new configuration,
* returns true; else returns false.
*/
@@ -4603,12 +4606,12 @@
}
/**
- * This is called when a child activity of this one calls its
+ * This is called when a child activity of this one calls its
* {@link #finish} method. The default implementation simply calls
* finish() on this activity (the parent), finishing the entire group.
- *
+ *
* @param child The activity making the call.
- *
+ *
* @see #finish
*/
public void finishFromChild(Activity child) {
@@ -4631,7 +4634,7 @@
/**
* Force finish another activity that you had previously started with
* {@link #startActivityForResult}.
- *
+ *
* @param requestCode The request code of the activity that you had
* given to startActivityForResult(). If there are multiple
* activities started with this request code, they
@@ -4653,7 +4656,7 @@
/**
* This is called when a child activity of this one calls its
* finishActivity().
- *
+ *
* @param child The activity making the call.
* @param requestCode Request code that had been used to start the
* activity.
@@ -4681,10 +4684,10 @@
* data from it. The <var>resultCode</var> will be
* {@link #RESULT_CANCELED} if the activity explicitly returned that,
* didn't return any result, or crashed during its operation.
- *
+ *
* <p>You will receive this call immediately before onResume() when your
* activity is re-starting.
- *
+ *
* @param requestCode The integer request code originally supplied to
* startActivityForResult(), allowing you to identify who this
* result came from.
@@ -4692,7 +4695,7 @@
* through its setResult().
* @param data An Intent, which can return result data to the caller
* (various data can be attached to Intent "extras").
- *
+ *
* @see #startActivityForResult
* @see #createPendingResult
* @see #setResult(int)
@@ -4722,12 +4725,12 @@
}
/**
- * Create a new PendingIntent object which you can hand to others
- * for them to use to send result data back to your
- * {@link #onActivityResult} callback. The created object will be either
- * one-shot (becoming invalid after a result is sent back) or multiple
- * (allowing any number of results to be sent through it).
- *
+ * Create a new PendingIntent object which you can hand to others
+ * for them to use to send result data back to your
+ * {@link #onActivityResult} callback. The created object will be either
+ * one-shot (becoming invalid after a result is sent back) or multiple
+ * (allowing any number of results to be sent through it).
+ *
* @param requestCode Private request code for the sender that will be
* associated with the result data when it is returned. The sender can not
* modify this value, allowing you to identify incoming results.
@@ -4740,12 +4743,12 @@
* or any of the flags as supported by
* {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts
* of the intent that can be supplied when the actual send happens.
- *
+ *
* @return Returns an existing or new PendingIntent matching the given
* parameters. May return null only if
* {@link PendingIntent#FLAG_NO_CREATE PendingIntent.FLAG_NO_CREATE} has been
* supplied.
- *
+ *
* @see PendingIntent
*/
public PendingIntent createPendingResult(int requestCode, @NonNull Intent data,
@@ -4772,7 +4775,7 @@
* orientation, the screen will immediately be changed (possibly causing
* the activity to be restarted). Otherwise, this will be used the next
* time the activity is visible.
- *
+ *
* @param requestedOrientation An orientation constant as used in
* {@link ActivityInfo#screenOrientation ActivityInfo.screenOrientation}.
*/
@@ -4788,13 +4791,13 @@
mParent.setRequestedOrientation(requestedOrientation);
}
}
-
+
/**
* Return the current requested orientation of the activity. This will
* either be the orientation requested in its component's manifest, or
* the last requested orientation given to
* {@link #setRequestedOrientation(int)}.
- *
+ *
* @return Returns an orientation constant as used in
* {@link ActivityInfo#screenOrientation ActivityInfo.screenOrientation}.
*/
@@ -4812,11 +4815,11 @@
}
return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
}
-
+
/**
* Return the identifier of the task this activity is in. This identifier
* will remain the same for the lifetime of the activity.
- *
+ *
* @return Task identifier, an opaque integer.
*/
public int getTaskId() {
@@ -4831,7 +4834,7 @@
/**
* Return whether this activity is the root of a task. The root is the
* first activity in a task.
- *
+ *
* @return True if this is the root activity, else false.
*/
public boolean isTaskRoot() {
@@ -4846,11 +4849,11 @@
/**
* Move the task containing this activity to the back of the activity
* stack. The activity's order within the task is unchanged.
- *
+ *
* @param nonRoot If false then this only works if the activity is the root
* of a task; if true it will work for any activity in
* a task.
- *
+ *
* @return If the task was moved (or it was already at the
* back) true is returned, else false.
*/
@@ -4867,7 +4870,7 @@
/**
* Returns class name for this activity with the package prefix removed.
* This is the default name used to read and write settings.
- *
+ *
* @return The local class name.
*/
@NonNull
@@ -4881,10 +4884,10 @@
}
return cls.substring(packageLen+1);
}
-
+
/**
* Returns complete component name of this activity.
- *
+ *
* @return Returns the complete component name for this activity
*/
public ComponentName getComponentName()
@@ -4897,9 +4900,9 @@
* that are private to this activity. This simply calls the underlying
* {@link #getSharedPreferences(String, int)} method by passing in this activity's
* class name as the preferences name.
- *
- * @param mode Operating mode. Use {@link #MODE_PRIVATE} for the default
- * operation, {@link #MODE_WORLD_READABLE} and
+ *
+ * @param mode Operating mode. Use {@link #MODE_PRIVATE} for the default
+ * operation, {@link #MODE_WORLD_READABLE} and
* {@link #MODE_WORLD_WRITEABLE} to control permissions.
*
* @return Returns the single SharedPreferences instance that can be used
@@ -4908,12 +4911,12 @@
public SharedPreferences getPreferences(int mode) {
return getSharedPreferences(getLocalClassName(), mode);
}
-
+
private void ensureSearchManager() {
if (mSearchManager != null) {
return;
}
-
+
mSearchManager = new SearchManager(this, null);
}
@@ -5031,7 +5034,7 @@
* <p>
* In order for the progress bar to be shown, the feature must be requested
* via {@link #requestWindowFeature(int)}.
- *
+ *
* @param visible Whether to show the progress bars in the title.
*/
public final void setProgressBarVisibility(boolean visible) {
@@ -5051,14 +5054,14 @@
getWindow().setFeatureInt(Window.FEATURE_INDETERMINATE_PROGRESS,
visible ? Window.PROGRESS_VISIBILITY_ON : Window.PROGRESS_VISIBILITY_OFF);
}
-
+
/**
* Sets whether the horizontal progress bar in the title should be indeterminate (the circular
* is always indeterminate).
* <p>
* In order for the progress bar to be shown, the feature must be requested
* via {@link #requestWindowFeature(int)}.
- *
+ *
* @param indeterminate Whether the horizontal progress bar should be indeterminate.
*/
public final void setProgressBarIndeterminate(boolean indeterminate) {
@@ -5066,13 +5069,13 @@
indeterminate ? Window.PROGRESS_INDETERMINATE_ON
: Window.PROGRESS_INDETERMINATE_OFF);
}
-
+
/**
* Sets the progress for the progress bars in the title.
* <p>
* In order for the progress bar to be shown, the feature must be requested
* via {@link #requestWindowFeature(int)}.
- *
+ *
* @param progress The progress for the progress bar. Valid ranges are from
* 0 to 10000 (both inclusive). If 10000 is given, the progress
* bar will be completely filled and will fade out.
@@ -5080,7 +5083,7 @@
public final void setProgress(int progress) {
getWindow().setFeatureInt(Window.FEATURE_PROGRESS, progress + Window.PROGRESS_START);
}
-
+
/**
* Sets the secondary progress for the progress bar in the title. This
* progress is drawn between the primary progress (set via
@@ -5090,7 +5093,7 @@
* <p>
* In order for the progress bar to be shown, the feature must be requested
* via {@link #requestWindowFeature(int)}.
- *
+ *
* @param secondaryProgress The secondary progress for the progress bar. Valid ranges are from
* 0 to 10000 (both inclusive).
*/
@@ -5104,16 +5107,16 @@
* volume controls.
* <p>
* The suggested audio stream will be tied to the window of this Activity.
- * If the Activity is switched, the stream set here is no longer the
- * suggested stream. The client does not need to save and restore the old
- * suggested stream value in onPause and onResume.
- *
+ * Volume requests which are received while the Activity is in the
+ * foreground will affect this stream.
+ * <p>
+ * It is not guaranteed that the hardware volume controls will always change
+ * this stream's volume (for example, if a call is in progress, its stream's
+ * volume may be changed instead). To reset back to the default, use
+ * {@link AudioManager#USE_DEFAULT_STREAM_TYPE}.
+ *
* @param streamType The type of the audio stream whose volume should be
- * changed by the hardware volume controls. It is not guaranteed that
- * the hardware volume controls will always change this stream's
- * volume (for example, if a call is in progress, its stream's volume
- * may be changed instead). To reset back to the default, use
- * {@link AudioManager#USE_DEFAULT_STREAM_TYPE}.
+ * changed by the hardware volume controls.
*/
public final void setVolumeControlStream(int streamType) {
getWindow().setVolumeControlStream(streamType);
@@ -5122,7 +5125,7 @@
/**
* Gets the suggested audio stream whose volume should be changed by the
* hardware volume controls.
- *
+ *
* @return The suggested audio stream type whose volume should be changed by
* the hardware volume controls.
* @see #setVolumeControlStream(int)
@@ -5130,7 +5133,40 @@
public final int getVolumeControlStream() {
return getWindow().getVolumeControlStream();
}
-
+
+ /**
+ * Sets a {@link MediaController} to send media keys and volume changes to.
+ * <p>
+ * The controller will be tied to the window of this Activity. Media key and
+ * volume events which are received while the Activity is in the foreground
+ * will be forwarded to the controller and used to invoke transport controls
+ * or adjust the volume. This may be used instead of or in addition to
+ * {@link #setVolumeControlStream} to affect a specific session instead of a
+ * specific stream.
+ * <p>
+ * It is not guaranteed that the hardware volume controls will always change
+ * this session's volume (for example, if a call is in progress, its
+ * stream's volume may be changed instead). To reset back to the default use
+ * null as the controller.
+ *
+ * @param controller The controller for the session which should receive
+ * media keys and volume changes.
+ */
+ public final void setMediaController(MediaController controller) {
+ getWindow().setMediaController(controller);
+ }
+
+ /**
+ * Gets the controller which should be receiving media key and volume events
+ * while this activity is in the foreground.
+ *
+ * @return The controller which should receive events.
+ * @see #setMediaController(android.media.session.MediaController)
+ */
+ public final MediaController getMediaController() {
+ return getWindow().getMediaController();
+ }
+
/**
* Runs the specified action on the UI thread. If the current thread is the UI
* thread, then the action is executed immediately. If the current thread is
@@ -5176,7 +5212,7 @@
if (!"fragment".equals(name)) {
return onCreateView(name, context, attrs);
}
-
+
return mFragments.onCreateView(parent, name, context, attrs);
}
@@ -5737,7 +5773,7 @@
}
// ------------------ Internal API ------------------
-
+
final void setParent(Activity parent) {
mParent = parent;
}
@@ -5751,7 +5787,7 @@
attachBaseContext(context);
mFragments.attachActivity(this, mContainer, null);
-
+
mWindow = PolicyManager.makeNewWindow(this);
mWindow.setCallback(this);
mWindow.setOnWindowDismissedCallback(this);
@@ -5846,7 +5882,7 @@
}
mActivityTransitionState.enterReady(this);
}
-
+
final void performRestart() {
mFragments.noteStateNotSaved();
@@ -5885,14 +5921,14 @@
performStart();
}
}
-
+
final void performResume() {
performRestart();
-
+
mFragments.execPendingActions();
-
+
mLastNonConfigurationInstances = null;
-
+
mCalled = false;
// mResumed is set by the instrumentation
mInstrumentation.callActivityOnResume(this);
@@ -5904,10 +5940,10 @@
// Now really resume, and install the current status bar and menu.
mCalled = false;
-
+
mFragments.dispatchResume();
mFragments.execPendingActions();
-
+
onPostResume();
if (!mCalled) {
throw new SuperNotCalledException(
@@ -5930,12 +5966,12 @@
}
mResumed = false;
}
-
+
final void performUserLeaving() {
onUserInteraction();
onUserLeaveHint();
}
-
+
final void performStop() {
mDoReportFullyDrawn = false;
if (mLoadersStarted) {
@@ -5948,7 +5984,7 @@
}
}
}
-
+
if (!mStopped) {
if (mWindow != null) {
mWindow.closeAllPanels();
@@ -5957,9 +5993,9 @@
if (mToken != null && mParent == null) {
WindowManagerGlobal.getInstance().setStoppedState(mToken, true);
}
-
+
mFragments.dispatchStop();
-
+
mCalled = false;
mInstrumentation.callActivityOnStop(this);
if (!mCalled) {
@@ -5967,7 +6003,7 @@
"Activity " + mComponent.toShortString() +
" did not call through to super.onStop()");
}
-
+
synchronized (mManagedCursors) {
final int N = mManagedCursors.size();
for (int i=0; i<N; i++) {
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index e1d0b86..c8cab6f 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -2456,7 +2456,10 @@
}
/**
- * @hide
+ * Return whether currently in lock task mode. When in this mode
+ * no new tasks can be created or switched to.
+ *
+ * @see Activity#startLockTask()
*/
public boolean isInLockTaskMode() {
try {
diff --git a/core/java/android/app/ActivityTransitionCoordinator.java b/core/java/android/app/ActivityTransitionCoordinator.java
index 15be9b1..e074219 100644
--- a/core/java/android/app/ActivityTransitionCoordinator.java
+++ b/core/java/android/app/ActivityTransitionCoordinator.java
@@ -403,20 +403,18 @@
view.layout(left, top, right, bottom);
}
- protected ArrayMap<ImageView, Pair<ImageView.ScaleType, Matrix>> setSharedElementState(
+ protected ArrayList<SharedElementOriginalState> setSharedElementState(
Bundle sharedElementState, final ArrayList<View> snapshots) {
- ArrayMap<ImageView, Pair<ImageView.ScaleType, Matrix>> originalImageState =
- new ArrayMap<ImageView, Pair<ImageView.ScaleType, Matrix>>();
+ ArrayList<SharedElementOriginalState> originalImageState =
+ new ArrayList<SharedElementOriginalState>();
if (sharedElementState != null) {
int[] tempLoc = new int[2];
for (int i = 0; i < mSharedElementNames.size(); i++) {
View sharedElement = mSharedElements.get(i);
String name = mSharedElementNames.get(i);
- Pair<ImageView.ScaleType, Matrix> originalState = getOldImageState(sharedElement,
+ SharedElementOriginalState originalState = getOldSharedElementState(sharedElement,
name, sharedElementState);
- if (originalState != null) {
- originalImageState.put((ImageView) sharedElement, originalState);
- }
+ originalImageState.add(originalState);
View parent = (View) sharedElement.getParent();
parent.getLocationOnScreen(tempLoc);
setSharedElementState(sharedElement, name, sharedElementState, tempLoc);
@@ -438,29 +436,34 @@
return originalImageState;
}
- private static Pair<ImageView.ScaleType, Matrix> getOldImageState(View view, String name,
+ private static SharedElementOriginalState getOldSharedElementState(View view, String name,
Bundle transitionArgs) {
+
+ SharedElementOriginalState state = new SharedElementOriginalState();
+ state.mLeft = view.getLeft();
+ state.mTop = view.getTop();
+ state.mRight = view.getRight();
+ state.mBottom = view.getBottom();
+ state.mMeasuredWidth = view.getMeasuredWidth();
+ state.mMeasuredHeight = view.getMeasuredHeight();
if (!(view instanceof ImageView)) {
- return null;
+ return state;
}
Bundle bundle = transitionArgs.getBundle(name);
if (bundle == null) {
- return null;
+ return state;
}
int scaleTypeInt = bundle.getInt(KEY_SCALE_TYPE, -1);
if (scaleTypeInt < 0) {
- return null;
+ return state;
}
ImageView imageView = (ImageView) view;
- ImageView.ScaleType originalScaleType = imageView.getScaleType();
-
- Matrix originalMatrix = null;
- if (originalScaleType == ImageView.ScaleType.MATRIX) {
- originalMatrix = new Matrix(imageView.getImageMatrix());
+ state.mScaleType = imageView.getScaleType();
+ if (state.mScaleType == ImageView.ScaleType.MATRIX) {
+ state.mMatrix = new Matrix(imageView.getImageMatrix());
}
-
- return Pair.create(originalScaleType, originalMatrix);
+ return state;
}
protected ArrayList<View> createSnapshots(Bundle state, Collection<String> names) {
@@ -489,13 +492,26 @@
return snapshots;
}
- protected static void setOriginalImageViewState(
- ArrayMap<ImageView, Pair<ImageView.ScaleType, Matrix>> originalState) {
+ protected static void setOriginalSharedElementState(ArrayList<View> sharedElements,
+ ArrayList<SharedElementOriginalState> originalState) {
for (int i = 0; i < originalState.size(); i++) {
- ImageView imageView = originalState.keyAt(i);
- Pair<ImageView.ScaleType, Matrix> state = originalState.valueAt(i);
- imageView.setScaleType(state.first);
- imageView.setImageMatrix(state.second);
+ View view = sharedElements.get(i);
+ SharedElementOriginalState state = originalState.get(i);
+ if (view instanceof ImageView && state.mScaleType != null) {
+ ImageView imageView = (ImageView) view;
+ imageView.setScaleType(state.mScaleType);
+ if (state.mScaleType == ImageView.ScaleType.MATRIX) {
+ imageView.setImageMatrix(state.mMatrix);
+ }
+ }
+ // origignal widthspec might be AT_MOST, but it should work for most
+ // cases.
+ int widthSpec = View.MeasureSpec.makeMeasureSpec(state.mMeasuredWidth,
+ View.MeasureSpec.EXACTLY);
+ int heightSpec = View.MeasureSpec.makeMeasureSpec(state.mMeasuredHeight,
+ View.MeasureSpec.EXACTLY);
+ view.measure(widthSpec, heightSpec);
+ view.layout(state.mLeft, state.mTop, state.mRight, state.mBottom);
}
}
@@ -622,4 +638,15 @@
}
}
+ static class SharedElementOriginalState {
+ int mLeft;
+ int mTop;
+ int mRight;
+ int mBottom;
+ int mMeasuredWidth;
+ int mMeasuredHeight;
+ ImageView.ScaleType mScaleType;
+ Matrix mMatrix;
+ }
+
}
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 2935b8e..4730559 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -33,6 +33,7 @@
import android.content.pm.IPackageMoveObserver;
import android.content.pm.IPackageStatsObserver;
import android.content.pm.InstrumentationInfo;
+import android.content.pm.KeySet;
import android.content.pm.ManifestDigest;
import android.content.pm.PackageInfo;
import android.content.pm.PackageInstaller;
@@ -52,6 +53,7 @@
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
+import android.os.IBinder;
import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
@@ -59,6 +61,7 @@
import android.util.ArrayMap;
import android.util.Log;
import android.view.Display;
+import com.android.internal.util.Preconditions;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
@@ -1447,6 +1450,62 @@
return false;
}
+ @Override
+ public KeySet getKeySetByAlias(String packageName, String alias) {
+ Preconditions.checkNotNull(packageName);
+ Preconditions.checkNotNull(alias);
+ IBinder keySetToken;
+ try {
+ keySetToken = mPM.getKeySetByAlias(packageName, alias);
+ } catch (RemoteException e) {
+ return null;
+ }
+ if (keySetToken == null) {
+ return null;
+ }
+ return new KeySet(keySetToken);
+ }
+
+ @Override
+ public KeySet getSigningKeySet(String packageName) {
+ Preconditions.checkNotNull(packageName);
+ IBinder keySetToken;
+ try {
+ keySetToken = mPM.getSigningKeySet(packageName);
+ } catch (RemoteException e) {
+ return null;
+ }
+ if (keySetToken == null) {
+ return null;
+ }
+ return new KeySet(keySetToken);
+ }
+
+
+ @Override
+ public boolean isSignedBy(String packageName, KeySet ks) {
+ Preconditions.checkNotNull(packageName);
+ Preconditions.checkNotNull(ks);
+ IBinder keySetToken = ks.getToken();
+ try {
+ return mPM.isPackageSignedByKeySet(packageName, keySetToken);
+ } catch (RemoteException e) {
+ return false;
+ }
+ }
+
+ @Override
+ public boolean isSignedByExactly(String packageName, KeySet ks) {
+ Preconditions.checkNotNull(packageName);
+ Preconditions.checkNotNull(ks);
+ IBinder keySetToken = ks.getToken();
+ try {
+ return mPM.isPackageSignedByKeySetExactly(packageName, keySetToken);
+ } catch (RemoteException e) {
+ return false;
+ }
+ }
+
/**
* @hide
*/
diff --git a/core/java/android/app/EnterTransitionCoordinator.java b/core/java/android/app/EnterTransitionCoordinator.java
index f50c93b..1326064 100644
--- a/core/java/android/app/EnterTransitionCoordinator.java
+++ b/core/java/android/app/EnterTransitionCoordinator.java
@@ -282,7 +282,7 @@
ArrayList<View> sharedElementSnapshots = createSnapshots(sharedElementState,
mSharedElementNames);
setTransitionAlpha(mSharedElements, 1);
- ArrayMap<ImageView, Pair<ImageView.ScaleType, Matrix>> originalImageViewState =
+ ArrayList<SharedElementOriginalState> originalImageViewState =
setSharedElementState(sharedElementState, sharedElementSnapshots);
requestLayoutForSharedElements();
@@ -294,7 +294,7 @@
startEnterTransition(transition);
}
- setOriginalImageViewState(originalImageViewState);
+ setOriginalSharedElementState(mSharedElements, originalImageViewState);
if (mResultReceiver != null) {
// We can't trust that the view will disappear on the same frame that the shared
diff --git a/core/java/android/app/PackageInstallObserver.java b/core/java/android/app/PackageInstallObserver.java
index 7117111..1b2504e 100644
--- a/core/java/android/app/PackageInstallObserver.java
+++ b/core/java/android/app/PackageInstallObserver.java
@@ -25,7 +25,7 @@
@Override
public void packageInstalled(String basePackageName, Bundle extras, int returnCode,
String msg) {
- PackageInstallObserver.this.packageInstalled(basePackageName, extras, returnCode);
+ PackageInstallObserver.this.packageInstalled(basePackageName, extras, returnCode, msg);
}
};
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 58d3526..3a98f5d 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -429,4 +429,9 @@
boolean setBlockUninstallForUser(String packageName, boolean blockUninstall, int userId);
boolean getBlockUninstallForUser(String packageName, int userId);
+
+ IBinder getKeySetByAlias(String packageName, String alias);
+ IBinder getSigningKeySet(String packageName);
+ boolean isPackageSignedByKeySet(String packageName, IBinder ks);
+ boolean isPackageSignedByKeySetExactly(String packageName, IBinder ks);
}
diff --git a/core/java/android/content/pm/KeySet.java b/core/java/android/content/pm/KeySet.java
index 0ef09a4..fcdaa18 100644
--- a/core/java/android/content/pm/KeySet.java
+++ b/core/java/android/content/pm/KeySet.java
@@ -16,19 +16,36 @@
package android.content.pm;
-import android.os.Binder;
+import android.os.IBinder;
-/** @hide */
+/**
+ * Represents a {@code KeySet} that has been declared in the AndroidManifest.xml
+ * file for the application. A {@code KeySet} can be used explicitly to
+ * represent a trust relationship with other applications on the device.
+ */
public class KeySet {
- private Binder token;
+ private IBinder token;
/** @hide */
- public KeySet(Binder token) {
+ public KeySet(IBinder token) {
+ if (token == null) {
+ throw new NullPointerException("null value for KeySet IBinder token");
+ }
this.token = token;
}
- Binder getToken() {
+ /** @hide */
+ public IBinder getToken() {
return token;
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (o instanceof KeySet) {
+ KeySet ks = (KeySet) o;
+ return token == ks.token;
+ }
+ return false;
+ }
}
\ No newline at end of file
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 03d4701..91ebbbf 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -3602,6 +3602,33 @@
public abstract boolean isSafeMode();
/**
+ * Return the {@link KeySet} associated with the String alias for this
+ * application.
+ *
+ * @param alias The alias for a given {@link KeySet} as defined in the
+ * application's AndroidManifest.xml.
+ */
+ public abstract KeySet getKeySetByAlias(String packageName, String alias);
+
+ /** Return the signing {@link KeySet} for this application. */
+ public abstract KeySet getSigningKeySet(String packageName);
+
+ /**
+ * Return whether the package denoted by packageName has been signed by all
+ * of the keys specified by the {@link KeySet} ks. This will return true if
+ * the package has been signed by additional keys (a superset) as well.
+ * Compare to {@link #isSignedByExactly(String packageName, KeySet ks)}.
+ */
+ public abstract boolean isSignedBy(String packageName, KeySet ks);
+
+ /**
+ * Return whether the package denoted by packageName has been signed by all
+ * of, and only, the keys specified by the {@link KeySet} ks. Compare to
+ * {@link #isSignedBy(String packageName, KeySet ks)}.
+ */
+ public abstract boolean isSignedByExactly(String packageName, KeySet ks);
+
+ /**
* Attempts to move package resources from internal to external media or vice versa.
* Since this may take a little while, the result will
* be posted back to the given observer. This call may fail if the calling context
diff --git a/core/java/android/printservice/PrintService.java b/core/java/android/printservice/PrintService.java
index 1557ab0..c5aee7b 100644
--- a/core/java/android/printservice/PrintService.java
+++ b/core/java/android/printservice/PrintService.java
@@ -230,7 +230,7 @@
*
* @see #EXTRA_PRINT_JOB_INFO
*/
- public static final String EXTRA_PRINTER_INFO = "android.intent.extra.print.PRINTER_INFO";
+ public static final String EXTRA_PRINTER_INFO = "android.intent.extra.print.EXTRA_PRINTER_INFO";
private Handler mHandler;
diff --git a/core/java/android/provider/VoicemailContract.java b/core/java/android/provider/VoicemailContract.java
index 6787fd0..d71ad03 100644
--- a/core/java/android/provider/VoicemailContract.java
+++ b/core/java/android/provider/VoicemailContract.java
@@ -188,6 +188,12 @@
*/
public static final String MIME_TYPE = "mime_type";
/**
+ * The transcription of the voicemail entry. This will only be populated if the voicemail
+ * entry has a valid transcription.
+ * <P>Type: TEXT</P>
+ */
+ public static final String TRANSCRIPTION = "transcription";
+ /**
* Path to the media content file. Internal only field.
* @hide
*/
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index aa71ed8..c169d35 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -23,6 +23,8 @@
import android.content.res.TypedArray;
import android.graphics.PixelFormat;
import android.graphics.drawable.Drawable;
+import android.media.session.MediaController;
+import android.media.session.MediaSession;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
@@ -157,7 +159,7 @@
private static final String PROPERTY_HARDWARE_UI = "persist.sys.ui.hw";
private final Context mContext;
-
+
private TypedArray mWindowStyle;
private Callback mCallback;
private OnWindowDismissedCallback mOnWindowDismissedCallback;
@@ -181,7 +183,7 @@
private int mDefaultWindowFormat = PixelFormat.OPAQUE;
private boolean mHasSoftInputMode = false;
-
+
private boolean mDestroyed;
// The current window attributes.
@@ -227,7 +229,7 @@
* @return boolean Return true if this event was consumed.
*/
public boolean dispatchTouchEvent(MotionEvent event);
-
+
/**
* Called to process trackball events. At the very least your
* implementation must call
@@ -313,14 +315,14 @@
* Called when a panel's menu is opened by the user. This may also be
* called when the menu is changing from one type to another (for
* example, from the icon menu to the expanded menu).
- *
+ *
* @param featureId The panel that the menu is in.
* @param menu The menu that is opened.
* @return Return true to allow the menu to open, or false to prevent
* the menu from opening.
*/
public boolean onMenuOpened(int featureId, Menu menu);
-
+
/**
* Called when a panel's menu item has been selected by the user.
*
@@ -364,31 +366,31 @@
* for more information.
*/
public void onAttachedToWindow();
-
+
/**
* Called when the window has been attached to the window manager.
* See {@link View#onDetachedFromWindow() View.onDetachedFromWindow()}
* for more information.
*/
public void onDetachedFromWindow();
-
+
/**
* Called when a panel is being closed. If another logical subsequent
* panel is being opened (and this panel is being closed to make room for the subsequent
* panel), this method will NOT be called.
- *
+ *
* @param featureId The panel that is being displayed.
* @param menu If onCreatePanelView() returned null, this is the Menu
* being displayed in the panel.
*/
public void onPanelClosed(int featureId, Menu menu);
-
+
/**
* Called when the user signals the desire to start a search.
- *
+ *
* @return true if search launched, false if activity refuses (blocks)
- *
- * @see android.app.Activity#onSearchRequested()
+ *
+ * @see android.app.Activity#onSearchRequested()
*/
public boolean onSearchRequested();
@@ -457,7 +459,7 @@
return mWindowStyle;
}
}
-
+
/**
* Set the container for this window. If not set, the DecorWindow
* operates as a top-level window; otherwise, it negotiates with the
@@ -488,7 +490,7 @@
public final boolean hasChildren() {
return mHasChildren;
}
-
+
/** @hide */
public final void destroy() {
mDestroyed = true;
@@ -622,14 +624,14 @@
* callback will be used to tell you about state changes to the surface.
*/
public abstract void takeSurface(SurfaceHolder.Callback2 callback);
-
+
/**
* Take ownership of this window's InputQueue. The window will no
* longer read and dispatch input events from the queue; it is your
* responsibility to do so.
*/
public abstract void takeInputQueue(InputQueue.Callback callback);
-
+
/**
* Return whether this window is being displayed with a floating style
* (based on the {@link android.R.attr#windowIsFloating} attribute in
@@ -740,7 +742,7 @@
}
dispatchWindowAttributesChanged(attrs);
}
-
+
/**
* Convenience function to set the flag bits as specified in flags, as
* per {@link #setFlags}.
@@ -756,7 +758,7 @@
public void addPrivateFlags(int flags) {
setPrivateFlags(flags, flags);
}
-
+
/**
* Convenience function to clear the flag bits as specified in flags, as
* per {@link #setFlags}.
@@ -772,7 +774,7 @@
* Set the flags of the window, as per the
* {@link WindowManager.LayoutParams WindowManager.LayoutParams}
* flags.
- *
+ *
* <p>Note that some flags must be set before the window decoration is
* created (by the first call to
* {@link #setContentView(View, android.view.ViewGroup.LayoutParams)} or
@@ -859,20 +861,20 @@
protected final int getForcedWindowFlags() {
return mForcedWindowFlags;
}
-
+
/**
* Has the app specified their own soft input mode?
*/
protected final boolean hasSoftInputMode() {
return mHasSoftInputMode;
}
-
+
/** @hide */
public void setCloseOnTouchOutside(boolean close) {
mCloseOnTouchOutside = close;
mSetCloseOnTouchOutside = true;
}
-
+
/** @hide */
public void setCloseOnTouchOutsideIfNotSet(boolean close) {
if (!mSetCloseOnTouchOutside) {
@@ -880,10 +882,10 @@
mSetCloseOnTouchOutside = true;
}
}
-
+
/** @hide */
public abstract void alwaysReadCloseOnTouchAttr();
-
+
/** @hide */
public boolean shouldCloseOnTouch(Context context, MotionEvent event) {
if (mCloseOnTouchOutside && event.getAction() == MotionEvent.ACTION_DOWN
@@ -892,7 +894,7 @@
}
return false;
}
-
+
private boolean isOutOfBounds(Context context, MotionEvent event) {
final int x = (int) event.getX();
final int y = (int) event.getY();
@@ -902,7 +904,7 @@
|| (x > (decorView.getWidth()+slop))
|| (y > (decorView.getHeight()+slop));
}
-
+
/**
* Enable extended screen features. This must be called before
* setContentView(). May be called as many times as desired as long as it
@@ -989,7 +991,7 @@
* of the window that can not, from this point forward, be changed: the
* features that have been requested with {@link #requestFeature(int)},
* and certain window flags as described in {@link #setFlags(int, int)}.
- *
+ *
* @param view The desired content to display.
* @param params Layout parameters for the view.
*/
@@ -1037,7 +1039,7 @@
public abstract void togglePanel(int featureId, KeyEvent event);
public abstract void invalidatePanelMenu(int featureId);
-
+
public abstract boolean performPanelShortcut(int featureId,
int keyCode,
KeyEvent event,
@@ -1052,17 +1054,17 @@
/**
* Should be called when the configuration is changed.
- *
+ *
* @param newConfig The new configuration.
*/
public abstract void onConfigurationChanged(Configuration newConfig);
-
+
/**
* Change the background of this window to a Drawable resource. Setting the
* background to null will make the window be opaque. To make the window
* transparent, you can use an empty drawable (for instance a ColorDrawable
* with the color 0 or the system drawable android:drawable/empty.)
- *
+ *
* @param resid The resource identifier of a drawable resource which will be
* installed as the new background.
*/
@@ -1173,7 +1175,7 @@
*
*/
public abstract boolean superDispatchTouchEvent(MotionEvent event);
-
+
/**
* Used by custom windows, such as Dialog, to pass the trackball event
* further down the view hierarchy. Application developers should
@@ -1181,7 +1183,7 @@
*
*/
public abstract boolean superDispatchTrackballEvent(MotionEvent event);
-
+
/**
* Used by custom windows, such as Dialog, to pass the generic motion event
* further down the view hierarchy. Application developers should
@@ -1194,11 +1196,11 @@
* Retrieve the top-level window decor view (containing the standard
* window frame/decorations and the client's content inside of that), which
* can be added as a window to the window manager.
- *
+ *
* <p><em>Note that calling this function for the first time "locks in"
* various window characteristics as described in
* {@link #setContentView(View, android.view.ViewGroup.LayoutParams)}.</em></p>
- *
+ *
* @return Returns the top-level window decor view.
*/
public abstract View getDecorView();
@@ -1206,16 +1208,16 @@
/**
* Retrieve the current decor view, but only if it has already been created;
* otherwise returns null.
- *
+ *
* @return Returns the top-level window decor or null.
* @see #getDecorView
*/
public abstract View peekDecorView();
public abstract Bundle saveHierarchyState();
-
+
public abstract void restoreHierarchyState(Bundle savedInstanceState);
-
+
protected abstract void onActive();
/**
@@ -1233,10 +1235,10 @@
{
return mFeatures;
}
-
+
/**
* Query for the availability of a certain feature.
- *
+ *
* @param feature The feature ID to check
* @return true if the feature is enabled, false otherwise.
*/
@@ -1290,9 +1292,9 @@
* @param event the {@link android.view.KeyEvent} to use to help check.
*/
public abstract boolean isShortcutKey(int keyCode, KeyEvent event);
-
+
/**
- * @see android.app.Activity#setVolumeControlStream(int)
+ * @see android.app.Activity#setVolumeControlStream(int)
*/
public abstract void setVolumeControlStream(int streamType);
@@ -1302,6 +1304,19 @@
public abstract int getVolumeControlStream();
/**
+ * @see android.app.Activity#setMediaController(android.media.session.MediaController)
+ */
+ public void setMediaController(MediaController controller) {
+ }
+
+ /**
+ * @see android.app.Activity#getMediaController()
+ */
+ public MediaController getMediaController() {
+ return null;
+ }
+
+ /**
* Set extra options that will influence the UI for this window.
* @param uiOptions Flags specifying extra options for this window.
*/
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 9701c6f..aa0b94f 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -36,7 +36,6 @@
import android.util.AttributeSet;
import android.util.Log;
import android.util.LongSparseArray;
-import android.util.MathUtils;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
import android.util.StateSet;
@@ -61,8 +60,6 @@
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityNodeInfo.CollectionInfo;
-import android.view.animation.AccelerateDecelerateInterpolator;
-import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
import android.view.animation.LinearInterpolator;
import android.view.inputmethod.BaseInputConnection;
@@ -7269,290 +7266,4 @@
}
}
}
-
- /**
- * Abstract position scroller that handles sub-position scrolling but has no
- * understanding of layout.
- */
- abstract class AbsSubPositionScroller extends AbsPositionScroller {
- private static final int DURATION_AUTO = -1;
-
- private static final int DURATION_AUTO_MIN = 100;
- private static final int DURATION_AUTO_MAX = 500;
-
- private final SubScroller mSubScroller = new SubScroller();
-
- /**
- * The target offset in pixels between the top of the list and the top
- * of the target position.
- */
- private int mOffset;
-
- /**
- * Scroll the minimum amount to get the target view entirely on-screen.
- */
- private void scrollToPosition(final int targetPosition, final boolean useOffset,
- final int offset, final int boundPosition, final int duration) {
- stop();
-
- if (mDataChanged) {
- // Wait until we're back in a stable state to try this.
- mPositionScrollAfterLayout = new Runnable() {
- @Override
- public void run() {
- scrollToPosition(
- targetPosition, useOffset, offset, boundPosition, duration);
- }
- };
- return;
- }
-
- if (mAdapter == null) {
- // Can't scroll anywhere without an adapter.
- return;
- }
-
- final int itemCount = getCount();
- final int clampedPosition = MathUtils.constrain(targetPosition, 0, itemCount - 1);
- final int clampedBoundPosition = MathUtils.constrain(boundPosition, -1, itemCount - 1);
- final int firstPosition = getFirstVisiblePosition();
- final int lastPosition = firstPosition + getChildCount();
- final int targetRow = getRowForPosition(clampedPosition);
- final int firstRow = getRowForPosition(firstPosition);
- final int lastRow = getRowForPosition(lastPosition);
- if (useOffset || targetRow <= firstRow) {
- // Offset so the target row is top-aligned.
- mOffset = offset;
- } else if (targetRow >= lastRow - 1) {
- // Offset so the target row is bottom-aligned.
- final int listHeight = getHeight() - getPaddingTop() - getPaddingBottom();
- mOffset = getHeightForPosition(clampedPosition) - listHeight;
- } else {
- // Don't scroll, target is entirely on-screen.
- return;
- }
-
- float endSubRow = targetRow;
- if (clampedBoundPosition != INVALID_POSITION) {
- final int boundRow = getRowForPosition(clampedBoundPosition);
- if (boundRow >= firstRow && boundRow < lastRow && boundRow != targetRow) {
- endSubRow = computeBoundSubRow(targetRow, boundRow);
- }
- }
-
- final View firstChild = getChildAt(0);
- if (firstChild == null) {
- return;
- }
-
- final int firstChildHeight = firstChild.getHeight();
- final float startOffsetRatio;
- if (firstChildHeight == 0) {
- startOffsetRatio = 0;
- } else {
- startOffsetRatio = -firstChild.getTop() / (float) firstChildHeight;
- }
-
- final float startSubRow = MathUtils.constrain(
- firstRow + startOffsetRatio, 0, getCount());
- if (startSubRow == endSubRow && mOffset == 0) {
- // Don't scroll, target is already in position.
- return;
- }
-
- final int durationMillis;
- if (duration == DURATION_AUTO) {
- final float subRowDelta = Math.abs(startSubRow - endSubRow);
- durationMillis = (int) MathUtils.lerp(
- DURATION_AUTO_MIN, DURATION_AUTO_MAX, subRowDelta / getCount());
- } else {
- durationMillis = duration;
- }
-
- mSubScroller.startScroll(startSubRow, endSubRow, durationMillis);
-
- postOnAnimation(mAnimationFrame);
- }
-
- /**
- * Given a target row and offset, computes the sub-row position that
- * aligns with the top of the list. If the offset is negative, the
- * resulting sub-row will be smaller than the target row.
- */
- private float resolveOffset(int targetRow, int offset) {
- // Compute the target sub-row position by finding the actual row
- // indicated by the target and offset.
- int remainingOffset = offset;
- int targetHeight = getHeightForRow(targetRow);
- if (offset < 0) {
- // Subtract row heights until we find the right row.
- while (targetRow > 0 && remainingOffset < 0) {
- remainingOffset += targetHeight;
- targetRow--;
- targetHeight = getHeightForRow(targetRow);
- }
- } else if (offset > 0) {
- // Add row heights until we find the right row.
- while (targetRow < getCount() - 1 && remainingOffset > targetHeight) {
- remainingOffset -= targetHeight;
- targetRow++;
- targetHeight = getHeightForRow(targetRow);
- }
- }
-
- final float targetOffsetRatio;
- if (remainingOffset < 0 || targetHeight == 0) {
- targetOffsetRatio = 0;
- } else {
- targetOffsetRatio = remainingOffset / (float) targetHeight;
- }
-
- return targetRow + targetOffsetRatio;
- }
-
- private float computeBoundSubRow(int targetRow, int boundRow) {
- final float targetSubRow = resolveOffset(targetRow, mOffset);
- mOffset = 0;
-
- // The target row is below the bound row, so the end position would
- // push the bound position above the list. Abort!
- if (targetSubRow >= boundRow) {
- return boundRow;
- }
-
- // Compute the closest possible sub-position that wouldn't push the
- // bound position's view further below the list.
- final int listHeight = getHeight() - getPaddingTop() - getPaddingBottom();
- final int boundHeight = getHeightForRow(boundRow);
- final float boundSubRow = resolveOffset(boundRow, -listHeight + boundHeight);
-
- return Math.max(boundSubRow, targetSubRow);
- }
-
- @Override
- public void start(int position) {
- scrollToPosition(position, false, 0, INVALID_POSITION, DURATION_AUTO);
- }
-
- @Override
- public void start(int position, int boundPosition) {
- scrollToPosition(position, false, 0, boundPosition, DURATION_AUTO);
- }
-
- @Override
- public void startWithOffset(int position, int offset) {
- scrollToPosition(position, true, offset, INVALID_POSITION, DURATION_AUTO);
- }
-
- @Override
- public void startWithOffset(int position, int offset, int duration) {
- scrollToPosition(position, true, offset, INVALID_POSITION, duration);
- }
-
- @Override
- public void stop() {
- removeCallbacks(mAnimationFrame);
- }
-
- /**
- * Returns the height of a row, which is computed as the maximum height of
- * the items in the row.
- *
- * @param row the row index
- * @return row height in pixels
- */
- public abstract int getHeightForRow(int row);
-
- /**
- * Returns the row for the specified item position.
- *
- * @param position the item position
- * @return the row index
- */
- public abstract int getRowForPosition(int position);
-
- /**
- * Returns the first item position within the specified row.
- *
- * @param row the row
- * @return the position of the first item in the row
- */
- public abstract int getFirstPositionForRow(int row);
-
- private void onAnimationFrame() {
- final boolean shouldPost = mSubScroller.computePosition();
- final float subRow = mSubScroller.getPosition();
-
- final int row = (int) subRow;
- final int position = getFirstPositionForRow(row);
- if (position >= getCount()) {
- // Invalid position, abort scrolling.
- return;
- }
-
- final int rowHeight = getHeightForRow(row);
- final int offset = (int) (rowHeight * (subRow - row));
- final int addOffset = (int) (mOffset * mSubScroller.getInterpolatedValue());
- setSelectionFromTop(position, -offset - addOffset);
-
- if (shouldPost) {
- postOnAnimation(mAnimationFrame);
- }
- }
-
- private Runnable mAnimationFrame = new Runnable() {
- @Override
- public void run() {
- onAnimationFrame();
- }
- };
- }
-
- /**
- * Scroller capable of returning floating point positions.
- */
- static class SubScroller {
- private static final Interpolator INTERPOLATOR = new AccelerateDecelerateInterpolator();
-
- private float mStartPosition;
- private float mEndPosition;
- private long mStartTime;
- private long mDuration;
-
- private float mPosition;
- private float mInterpolatedValue;
-
- public void startScroll(float startPosition, float endPosition, int duration) {
- mStartPosition = startPosition;
- mEndPosition = endPosition;
- mDuration = duration;
-
- mStartTime = AnimationUtils.currentAnimationTimeMillis();
- mPosition = startPosition;
- mInterpolatedValue = 0;
- }
-
- public boolean computePosition() {
- final long elapsed = AnimationUtils.currentAnimationTimeMillis() - mStartTime;
- final float value;
- if (mDuration <= 0) {
- value = 1;
- } else {
- value = MathUtils.constrain(elapsed / (float) mDuration, 0, 1);
- }
-
- mInterpolatedValue = INTERPOLATOR.getInterpolation(value);
- mPosition = (mEndPosition - mStartPosition) * mInterpolatedValue + mStartPosition;
-
- return elapsed < mDuration;
- }
-
- public float getPosition() {
- return mPosition;
- }
-
- public float getInterpolatedValue() {
- return mInterpolatedValue;
- }
- }
}
diff --git a/core/java/android/widget/GridView.java b/core/java/android/widget/GridView.java
index 93810b3..33cc66e 100644
--- a/core/java/android/widget/GridView.java
+++ b/core/java/android/widget/GridView.java
@@ -1029,11 +1029,6 @@
}
@Override
- AbsPositionScroller createPositionScroller() {
- return new GridViewPositionScroller();
- }
-
- @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// Sets up mListPadding
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
@@ -2392,33 +2387,4 @@
column, 1, row, 1, isHeading, isSelected);
info.setCollectionItemInfo(itemInfo);
}
-
- /**
- * Sub-position scroller that understands the layout of a GridView.
- */
- class GridViewPositionScroller extends AbsSubPositionScroller {
- @Override
- public int getRowForPosition(int position) {
- return position / mNumColumns;
- }
-
- @Override
- public int getFirstPositionForRow(int row) {
- return row * mNumColumns;
- }
-
- @Override
- public int getHeightForRow(int row) {
- final int firstRowPosition = row * mNumColumns;
- final int lastRowPosition = Math.min(getCount(), firstRowPosition + mNumColumns);
- int maxHeight = 0;
- for (int i = firstRowPosition; i < lastRowPosition; i++) {
- final int height = getHeightForPosition(i);
- if (height > maxHeight) {
- maxHeight = height;
- }
- }
- return maxHeight;
- }
- }
}
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index 1baeca8..9db1e05 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -3872,11 +3872,6 @@
}
@Override
- AbsPositionScroller createPositionScroller() {
- return new ListViewPositionScroller();
- }
-
- @Override
public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
super.onInitializeAccessibilityEvent(event);
event.setClassName(ListView.class.getName());
@@ -3905,24 +3900,4 @@
0, 1, position, 1, isHeading, isSelected);
info.setCollectionItemInfo(itemInfo);
}
-
- /**
- * Sub-position scroller that understands the layout of a ListView.
- */
- class ListViewPositionScroller extends AbsSubPositionScroller {
- @Override
- public int getRowForPosition(int position) {
- return position;
- }
-
- @Override
- public int getFirstPositionForRow(int row) {
- return row;
- }
-
- @Override
- public int getHeightForRow(int row) {
- return getHeightForPosition(row);
- }
- }
}
diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml
index a2cc40c..b524177 100644
--- a/core/tests/coretests/AndroidManifest.xml
+++ b/core/tests/coretests/AndroidManifest.xml
@@ -1257,4 +1257,11 @@
<instrumentation android:name="android.test.InstrumentationTestRunner"
android:targetPackage="com.android.frameworks.coretests"
android:label="Frameworks Core Tests" />
+ <key-sets>
+ <key-set android:name="A" >
+ <public-key android:name="keyA"
+ android:value="MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJoN1Nsgqf0V4C/bbN8wo8O2X/S5D76+5Mb9mlIsHkUTUTbHCNk+LxHIUYLm89YbP9zImrV0bUHLUAZUyoMUCiMCAwEAAQ=="/>
+ </key-set>
+ <upgrade-key-set android:name="A"/>
+ </key-sets>
</manifest>
diff --git a/core/tests/coretests/apks/keyset/Android.mk b/core/tests/coretests/apks/keyset/Android.mk
index e44ac6c..306dc90 100644
--- a/core/tests/coretests/apks/keyset/Android.mk
+++ b/core/tests/coretests/apks/keyset/Android.mk
@@ -88,4 +88,21 @@
LOCAL_CERTIFICATE := $(LOCAL_PATH)/../../certs/keyset_A
LOCAL_ADDITIONAL_CERTIFICATES := $(LOCAL_PATH)/../../certs/keyset_B
LOCAL_MANIFEST_FILE := uB/AndroidManifest.xml
+include $(FrameworkCoreTests_BUILD_PACKAGE)
+
+#apks signed by platform only
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+LOCAL_PACKAGE_NAME := keyset_splat_api
+LOCAL_CERTIFICATE := platform
+LOCAL_MANIFEST_FILE := api_test/AndroidManifest.xml
+include $(FrameworkCoreTests_BUILD_PACKAGE)
+
+#apks signed by platform and keyset_A
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+LOCAL_PACKAGE_NAME := keyset_splata_api
+LOCAL_CERTIFICATE := platform
+LOCAL_ADDITIONAL_CERTIFICATES := $(LOCAL_PATH)/../../certs/keyset_A
+LOCAL_MANIFEST_FILE := api_test/AndroidManifest.xml
include $(FrameworkCoreTests_BUILD_PACKAGE)
\ No newline at end of file
diff --git a/core/tests/coretests/apks/keyset/api_test/AndroidManifest.xml b/core/tests/coretests/apks/keyset/api_test/AndroidManifest.xml
new file mode 100644
index 0000000..4c7e968
--- /dev/null
+++ b/core/tests/coretests/apks/keyset/api_test/AndroidManifest.xml
@@ -0,0 +1,20 @@
+<?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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.frameworks.coretests.keysets_api">
+ <application android:hasCode="false">
+ </application>
+</manifest>
diff --git a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
index 0244425..3a80309 100644
--- a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
+++ b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
@@ -26,6 +26,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.pm.KeySet;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
@@ -33,6 +34,7 @@
import android.content.res.Resources;
import android.content.res.Resources.NotFoundException;
import android.net.Uri;
+import android.os.Binder;
import android.os.Bundle;
import android.os.Environment;
import android.os.FileUtils;
@@ -3328,6 +3330,174 @@
}
/**
+ * The following tests are related to testing KeySets-based API
+ */
+
+ /*
+ * testGetSigningKeySetNull - ensure getSigningKeySet() returns null on null
+ * input and when calling a package other than that which made the call.
+ */
+ public void testGetSigningKeySet() throws Exception {
+ PackageManager pm = getPm();
+ String mPkgName = mContext.getPackageName();
+ String otherPkgName = "com.android.frameworks.coretests.keysets_api";
+ KeySet ks;
+ try {
+ ks = pm.getSigningKeySet(null);
+ assertTrue(false); // should have thrown
+ } catch (NullPointerException e) {
+ }
+ try {
+ ks = pm.getSigningKeySet("keysets.test.bogus.package");
+ assertTrue(false); // should have thrown
+ } catch (IllegalArgumentException e) {
+ }
+ installFromRawResource("keysetApi.apk", R.raw.keyset_splat_api,
+ 0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
+ try {
+ ks = pm.getSigningKeySet(otherPkgName);
+ assertTrue(false); // should have thrown
+ } catch (SecurityException e) {
+ }
+ cleanUpInstall(otherPkgName);
+ ks = pm.getSigningKeySet(mContext.getPackageName());
+ assertNotNull(ks);
+ }
+
+ /*
+ * testGetKeySetByAlias - same as getSigningKeySet, but for keysets defined
+ * by this package.
+ */
+ public void testGetKeySetByAlias() throws Exception {
+ PackageManager pm = getPm();
+ String mPkgName = mContext.getPackageName();
+ String otherPkgName = "com.android.frameworks.coretests.keysets_api";
+ KeySet ks;
+ try {
+ ks = pm.getKeySetByAlias(null, null);
+ assertTrue(false); // should have thrown
+ } catch (NullPointerException e) {
+ }
+ try {
+ ks = pm.getKeySetByAlias(null, "keysetBogus");
+ assertTrue(false); // should have thrown
+ } catch (NullPointerException e) {
+ }
+ try {
+ ks = pm.getKeySetByAlias("keysets.test.bogus.package", null);
+ assertTrue(false); // should have thrown
+ } catch (NullPointerException e) {
+ }
+ try {
+ ks = pm.getKeySetByAlias("keysets.test.bogus.package", "A");
+ assertTrue(false); // should have thrown
+ } catch(IllegalArgumentException e) {
+ }
+ try {
+ ks = pm.getKeySetByAlias(mPkgName, "keysetBogus");
+ assertTrue(false); // should have thrown
+ } catch(IllegalArgumentException e) {
+ }
+ installFromRawResource("keysetApi.apk", R.raw.keyset_splat_api,
+ 0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
+ try {
+ ks = pm.getKeySetByAlias(otherPkgName, "A");
+ assertTrue(false); // should have thrown
+ } catch (SecurityException e) {
+ }
+ cleanUpInstall(otherPkgName);
+ ks = pm.getKeySetByAlias(mPkgName, "A");
+ assertNotNull(ks);
+ }
+
+ public void testIsSignedBy() throws Exception {
+ PackageManager pm = getPm();
+ String mPkgName = mContext.getPackageName();
+ String otherPkgName = "com.android.frameworks.coretests.keysets_api";
+ KeySet mSigningKS = pm.getSigningKeySet(mPkgName);
+ KeySet mDefinedKS = pm.getKeySetByAlias(mPkgName, "A");
+
+ try {
+ assertFalse(pm.isSignedBy(null, null));
+ assertTrue(false); // should have thrown
+ } catch (NullPointerException e) {
+ }
+ try {
+ assertFalse(pm.isSignedBy(null, mSigningKS));
+ assertTrue(false); // should have thrown
+ } catch (NullPointerException e) {
+ }
+ try {
+ assertFalse(pm.isSignedBy(mPkgName, null));
+ assertTrue(false); // should have thrown
+ } catch (NullPointerException e) {
+ }
+ try {
+ assertFalse(pm.isSignedBy("keysets.test.bogus.package", mDefinedKS));
+ } catch(IllegalArgumentException e) {
+ }
+ assertFalse(pm.isSignedBy(mPkgName, mDefinedKS));
+ assertFalse(pm.isSignedBy(mPkgName, new KeySet(new Binder())));
+ assertTrue(pm.isSignedBy(mPkgName, mSigningKS));
+
+ installFromRawResource("keysetApi.apk", R.raw.keyset_splat_api,
+ 0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
+ assertFalse(pm.isSignedBy(otherPkgName, mDefinedKS));
+ assertTrue(pm.isSignedBy(otherPkgName, mSigningKS));
+ cleanUpInstall(otherPkgName);
+
+ installFromRawResource("keysetApi.apk", R.raw.keyset_splata_api,
+ 0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
+ assertTrue(pm.isSignedBy(otherPkgName, mDefinedKS));
+ assertTrue(pm.isSignedBy(otherPkgName, mSigningKS));
+ cleanUpInstall(otherPkgName);
+ }
+
+ public void testIsSignedByExactly() throws Exception {
+ PackageManager pm = getPm();
+ String mPkgName = mContext.getPackageName();
+ String otherPkgName = "com.android.frameworks.coretests.keysets_api";
+ KeySet mSigningKS = pm.getSigningKeySet(mPkgName);
+ KeySet mDefinedKS = pm.getKeySetByAlias(mPkgName, "A");
+ try {
+ assertFalse(pm.isSignedBy(null, null));
+ assertTrue(false); // should have thrown
+ } catch (NullPointerException e) {
+ }
+ try {
+ assertFalse(pm.isSignedBy(null, mSigningKS));
+ assertTrue(false); // should have thrown
+ } catch (NullPointerException e) {
+ }
+ try {
+ assertFalse(pm.isSignedBy(mPkgName, null));
+ assertTrue(false); // should have thrown
+ } catch (NullPointerException e) {
+ }
+ try {
+ assertFalse(pm.isSignedByExactly("keysets.test.bogus.package", mDefinedKS));
+ } catch(IllegalArgumentException e) {
+ }
+ assertFalse(pm.isSignedByExactly(mPkgName, mDefinedKS));
+ assertFalse(pm.isSignedByExactly(mPkgName, new KeySet(new Binder())));
+ assertTrue(pm.isSignedByExactly(mPkgName, mSigningKS));
+
+ installFromRawResource("keysetApi.apk", R.raw.keyset_splat_api,
+ 0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
+ assertFalse(pm.isSignedByExactly(otherPkgName, mDefinedKS));
+ assertTrue(pm.isSignedByExactly(otherPkgName, mSigningKS));
+ cleanUpInstall(otherPkgName);
+
+ installFromRawResource("keysetApi.apk", R.raw.keyset_splata_api,
+ 0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
+ assertFalse(pm.isSignedByExactly(otherPkgName, mDefinedKS));
+ assertFalse(pm.isSignedByExactly(otherPkgName, mSigningKS));
+ cleanUpInstall(otherPkgName);
+ }
+
+
+
+ /**
* The following tests are related to testing the checkSignatures api.
*/
private void checkSignatures(int apk1, int apk2, int expMatchResult) throws Exception {
diff --git a/media/java/android/media/RemoteControlClient.java b/media/java/android/media/RemoteControlClient.java
index 73bc61a..740a9d3 100644
--- a/media/java/android/media/RemoteControlClient.java
+++ b/media/java/android/media/RemoteControlClient.java
@@ -682,9 +682,13 @@
// USE_SESSIONS
if (mSession != null) {
int pbState = PlaybackState.getStateFromRccState(state);
- mSessionPlaybackState.setState(pbState, hasPosition ?
- mPlaybackPositionMs : PlaybackState.PLAYBACK_POSITION_UNKNOWN,
- playbackSpeed);
+ long position = hasPosition ? mPlaybackPositionMs
+ : PlaybackState.PLAYBACK_POSITION_UNKNOWN;
+
+ PlaybackState.Builder bob = new PlaybackState.Builder(mSessionPlaybackState);
+ bob.setState(pbState, position, playbackSpeed, SystemClock.elapsedRealtime());
+ bob.setErrorMessage(null);
+ mSessionPlaybackState = bob.build();
mSession.setPlaybackState(mSessionPlaybackState);
}
}
@@ -745,8 +749,9 @@
// USE_SESSIONS
if (mSession != null) {
- mSessionPlaybackState.setActions(PlaybackState
- .getActionsFromRccControlFlags(transportControlFlags));
+ PlaybackState.Builder bob = new PlaybackState.Builder(mSessionPlaybackState);
+ bob.setActions(PlaybackState.getActionsFromRccControlFlags(transportControlFlags));
+ mSessionPlaybackState = bob.build();
mSession.setPlaybackState(mSessionPlaybackState);
}
}
@@ -946,7 +951,7 @@
/**
* Cache for the current playback state using Session APIs.
*/
- private final PlaybackState mSessionPlaybackState = new PlaybackState();
+ private PlaybackState mSessionPlaybackState = null;
/**
* Cache for metadata using Session APIs. This is re-initialized in apply().
diff --git a/media/java/android/media/RemoteController.java b/media/java/android/media/RemoteController.java
index 1f5b216..9ea3f26 100644
--- a/media/java/android/media/RemoteController.java
+++ b/media/java/android/media/RemoteController.java
@@ -1020,7 +1020,7 @@
l.onClientPlaybackStateUpdate(playstate);
} else {
l.onClientPlaybackStateUpdate(playstate, state.getLastPositionUpdateTime(),
- state.getPosition(), state.getPlaybackRate());
+ state.getPosition(), state.getPlaybackSpeed());
}
if (state != null) {
l.onClientTransportControlUpdate(PlaybackState.getRccControlFlagsFromActions(state
diff --git a/media/java/android/media/session/PlaybackState.java b/media/java/android/media/session/PlaybackState.java
index 9ae2436..f7e7176 100644
--- a/media/java/android/media/session/PlaybackState.java
+++ b/media/java/android/media/session/PlaybackState.java
@@ -184,41 +184,29 @@
*/
public final static long PLAYBACK_POSITION_UNKNOWN = -1;
- private int mState;
- private long mPosition;
- private long mBufferPosition;
- private float mRate;
- private long mActions;
- private CharSequence mErrorMessage;
- private long mUpdateTime;
+ private final int mState;
+ private final long mPosition;
+ private final long mBufferPosition;
+ private final float mSpeed;
+ private final long mActions;
+ private final CharSequence mErrorMessage;
+ private final long mUpdateTime;
- /**
- * Create an empty PlaybackState. At minimum a state and actions should be
- * set before publishing a PlaybackState.
- */
- public PlaybackState() {
- }
-
- /**
- * Create a new PlaybackState from an existing PlaybackState. All fields
- * will be copied to the new state.
- *
- * @param from The PlaybackState to duplicate
- */
- public PlaybackState(PlaybackState from) {
- mState = from.mState;
- mPosition = from.mPosition;
- mRate = from.mRate;
- mUpdateTime = from.mUpdateTime;
- mBufferPosition = from.mBufferPosition;
- mActions = from.mActions;
- mErrorMessage = from.mErrorMessage;
+ private PlaybackState(int state, long position, long updateTime, float speed,
+ long bufferPosition, long actions, CharSequence error) {
+ mState = state;
+ mPosition = position;
+ mSpeed = speed;
+ mUpdateTime = updateTime;
+ mBufferPosition = bufferPosition;
+ mActions = actions;
+ mErrorMessage = error;
}
private PlaybackState(Parcel in) {
mState = in.readInt();
mPosition = in.readLong();
- mRate = in.readFloat();
+ mSpeed = in.readFloat();
mUpdateTime = in.readLong();
mBufferPosition = in.readLong();
mActions = in.readLong();
@@ -232,7 +220,7 @@
bob.append("state=").append(mState);
bob.append(", position=").append(mPosition);
bob.append(", buffered position=").append(mBufferPosition);
- bob.append(", rate=").append(mRate);
+ bob.append(", speed=").append(mSpeed);
bob.append(", updated=").append(mUpdateTime);
bob.append(", actions=").append(mActions);
bob.append(", error=").append(mErrorMessage);
@@ -249,7 +237,7 @@
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mState);
dest.writeLong(mPosition);
- dest.writeFloat(mRate);
+ dest.writeFloat(mSpeed);
dest.writeLong(mUpdateTime);
dest.writeLong(mBufferPosition);
dest.writeLong(mActions);
@@ -271,41 +259,6 @@
public int getState() {
return mState;
}
-
- /**
- * Set the current state of playback.
- * <p>
- * The position must be in ms and indicates the current playback position
- * within the track. If the position is unknown use
- * {@link #PLAYBACK_POSITION_UNKNOWN}.
- * <p>
- * The rate is a multiple of normal playback and should be 0 when paused and
- * negative when rewinding. Normal playback rate is 1.0.
- * <p>
- * The state must be one of the following:
- * <ul>
- * <li> {@link PlaybackState#STATE_NONE}</li>
- * <li> {@link PlaybackState#STATE_STOPPED}</li>
- * <li> {@link PlaybackState#STATE_PLAYING}</li>
- * <li> {@link PlaybackState#STATE_PAUSED}</li>
- * <li> {@link PlaybackState#STATE_FAST_FORWARDING}</li>
- * <li> {@link PlaybackState#STATE_REWINDING}</li>
- * <li> {@link PlaybackState#STATE_BUFFERING}</li>
- * <li> {@link PlaybackState#STATE_ERROR}</li>
- * </ul>
- *
- * @param state The current state of playback.
- * @param position The position in the current track in ms.
- * @param playbackRate The current rate of playback as a multiple of normal
- * playback.
- */
- public void setState(int state, long position, float playbackRate) {
- this.mState = state;
- this.mPosition = position;
- this.mRate = playbackRate;
- mUpdateTime = SystemClock.elapsedRealtime();
- }
-
/**
* Get the current playback position in ms.
*/
@@ -323,23 +276,14 @@
}
/**
- * Set the current buffer position in ms. This is the farthest playback
- * point that can be reached from the current position using only buffered
- * content.
- */
- public void setBufferPosition(long bufferPosition) {
- mBufferPosition = bufferPosition;
- }
-
- /**
- * Get the current playback rate as a multiple of normal playback. This
+ * Get the current playback speed as a multiple of normal playback. This
* should be negative when rewinding. A value of 1 means normal playback and
* 0 means paused.
*
- * @return The current rate of playback.
+ * @return The current speed of playback.
*/
- public float getPlaybackRate() {
- return mRate;
+ public float getPlaybackSpeed() {
+ return mSpeed;
}
/**
@@ -362,25 +306,6 @@
}
/**
- * Set the current capabilities available on this session. This should use a
- * bitmask of the available capabilities.
- * <ul>
- * <li> {@link PlaybackState#ACTION_SKIP_TO_PREVIOUS}</li>
- * <li> {@link PlaybackState#ACTION_REWIND}</li>
- * <li> {@link PlaybackState#ACTION_PLAY}</li>
- * <li> {@link PlaybackState#ACTION_PAUSE}</li>
- * <li> {@link PlaybackState#ACTION_STOP}</li>
- * <li> {@link PlaybackState#ACTION_FAST_FORWARD}</li>
- * <li> {@link PlaybackState#ACTION_SKIP_TO_NEXT}</li>
- * <li> {@link PlaybackState#ACTION_SEEK_TO}</li>
- * <li> {@link PlaybackState#ACTION_SET_RATING}</li>
- * </ul>
- */
- public void setActions(long capabilities) {
- mActions = capabilities;
- }
-
- /**
* Get a user readable error message. This should be set when the state is
* {@link PlaybackState#STATE_ERROR}.
*/
@@ -393,21 +318,12 @@
* position has never been set this will return 0;
*
* @return The last time the position was updated.
- * @hide
*/
public long getLastPositionUpdateTime() {
return mUpdateTime;
}
/**
- * Set a user readable error message. This should be set when the state is
- * {@link PlaybackState#STATE_ERROR}.
- */
- public void setErrorMessage(CharSequence errorMessage) {
- mErrorMessage = errorMessage;
- }
-
- /**
* Get the {@link PlaybackState} state for the given
* {@link RemoteControlClient} state.
*
@@ -574,4 +490,175 @@
return new PlaybackState[size];
}
};
+
+ /**
+ * Builder for {@link PlaybackState} objects.
+ */
+ public static final class Builder {
+ private int mState;
+ private long mPosition;
+ private long mBufferPosition;
+ private float mSpeed;
+ private long mActions;
+ private CharSequence mErrorMessage;
+ private long mUpdateTime;
+
+ /**
+ * Creates an initially empty state builder.
+ */
+ public Builder() {
+ }
+
+ /**
+ * Creates a builder with the same initial values as those in the from
+ * state.
+ *
+ * @param from The state to use for initializing the builder.
+ */
+ public Builder(PlaybackState from) {
+ if (from == null) {
+ return;
+ }
+ mState = from.mState;
+ mPosition = from.mPosition;
+ mBufferPosition = from.mBufferPosition;
+ mSpeed = from.mSpeed;
+ mActions = from.mActions;
+ mErrorMessage = from.mErrorMessage;
+ mUpdateTime = from.mUpdateTime;
+ }
+
+ /**
+ * Set the current state of playback.
+ * <p>
+ * The position must be in ms and indicates the current playback
+ * position within the track. If the position is unknown use
+ * {@link #PLAYBACK_POSITION_UNKNOWN}. When not using an unknown
+ * position the time at which the position was updated must be provided.
+ * It is okay to use {@link SystemClock#elapsedRealtime()} if the
+ * current position was just retrieved.
+ * <p>
+ * The speed is a multiple of normal playback and should be 0 when
+ * paused and negative when rewinding. Normal playback speed is 1.0.
+ * <p>
+ * The state must be one of the following:
+ * <ul>
+ * <li> {@link PlaybackState#STATE_NONE}</li>
+ * <li> {@link PlaybackState#STATE_STOPPED}</li>
+ * <li> {@link PlaybackState#STATE_PLAYING}</li>
+ * <li> {@link PlaybackState#STATE_PAUSED}</li>
+ * <li> {@link PlaybackState#STATE_FAST_FORWARDING}</li>
+ * <li> {@link PlaybackState#STATE_REWINDING}</li>
+ * <li> {@link PlaybackState#STATE_BUFFERING}</li>
+ * <li> {@link PlaybackState#STATE_ERROR}</li>
+ * </ul>
+ *
+ * @param state The current state of playback.
+ * @param position The position in the current track in ms.
+ * @param playbackSpeed The current speed of playback as a multiple of
+ * normal playback.
+ * @param updateTime The time in the {@link SystemClock#elapsedRealtime}
+ * timebase that the position was updated at.
+ * @return this
+ */
+ public Builder setState(int state, long position, float playbackSpeed, long updateTime) {
+ mState = state;
+ mPosition = position;
+ mUpdateTime = updateTime;
+ mSpeed = playbackSpeed;
+ return this;
+ }
+
+ /**
+ * Set the current state of playback.
+ * <p>
+ * The position must be in ms and indicates the current playback
+ * position within the track. If the position is unknown use
+ * {@link #PLAYBACK_POSITION_UNKNOWN}. The update time will be set to
+ * the current {@link SystemClock#elapsedRealtime()}.
+ * <p>
+ * The speed is a multiple of normal playback and should be 0 when
+ * paused and negative when rewinding. Normal playback speed is 1.0.
+ * <p>
+ * The state must be one of the following:
+ * <ul>
+ * <li> {@link PlaybackState#STATE_NONE}</li>
+ * <li> {@link PlaybackState#STATE_STOPPED}</li>
+ * <li> {@link PlaybackState#STATE_PLAYING}</li>
+ * <li> {@link PlaybackState#STATE_PAUSED}</li>
+ * <li> {@link PlaybackState#STATE_FAST_FORWARDING}</li>
+ * <li> {@link PlaybackState#STATE_REWINDING}</li>
+ * <li> {@link PlaybackState#STATE_BUFFERING}</li>
+ * <li> {@link PlaybackState#STATE_ERROR}</li>
+ * </ul>
+ *
+ * @param state The current state of playback.
+ * @param position The position in the current track in ms.
+ * @param playbackSpeed The current speed of playback as a multiple of
+ * normal playback.
+ * @return this
+ */
+ public Builder setState(int state, long position, float playbackSpeed) {
+ return setState(state, position, playbackSpeed, SystemClock.elapsedRealtime());
+ }
+
+ /**
+ * Set the current actions available on this session. This should use a
+ * bitmask of possible actions.
+ * <ul>
+ * <li> {@link PlaybackState#ACTION_SKIP_TO_PREVIOUS}</li>
+ * <li> {@link PlaybackState#ACTION_REWIND}</li>
+ * <li> {@link PlaybackState#ACTION_PLAY}</li>
+ * <li> {@link PlaybackState#ACTION_PAUSE}</li>
+ * <li> {@link PlaybackState#ACTION_STOP}</li>
+ * <li> {@link PlaybackState#ACTION_FAST_FORWARD}</li>
+ * <li> {@link PlaybackState#ACTION_SKIP_TO_NEXT}</li>
+ * <li> {@link PlaybackState#ACTION_SEEK_TO}</li>
+ * <li> {@link PlaybackState#ACTION_SET_RATING}</li>
+ * </ul>
+ *
+ * @param actions The set of actions allowed.
+ * @return this
+ */
+ public Builder setActions(long actions) {
+ mActions = actions;
+ return this;
+ }
+
+ /**
+ * Set the current buffer position in ms. This is the farthest playback
+ * point that can be reached from the current position using only
+ * buffered content.
+ *
+ * @param bufferPosition The position in ms that playback is buffered
+ * to.
+ * @return this
+ */
+ public Builder setBufferPosition(long bufferPosition) {
+ mBufferPosition = bufferPosition;
+ return this;
+ }
+
+ /**
+ * Set a user readable error message. This should be set when the state
+ * is {@link PlaybackState#STATE_ERROR}.
+ *
+ * @param error The error message for display to the user.
+ * @return this
+ */
+ public Builder setErrorMessage(CharSequence error) {
+ mErrorMessage = error;
+ return this;
+ }
+
+ /**
+ * Build and return the PlaybackState instance with these values.
+ *
+ * @return A new state instance.
+ */
+ public PlaybackState build() {
+ return new PlaybackState(mState, mPosition, mUpdateTime, mSpeed, mBufferPosition,
+ mActions, mErrorMessage);
+ }
+ }
}
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/FusedPrintersProvider.java b/packages/PrintSpooler/src/com/android/printspooler/ui/FusedPrintersProvider.java
index e4716da..8a65a2e 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/FusedPrintersProvider.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/FusedPrintersProvider.java
@@ -27,6 +27,7 @@
import android.print.PrinterId;
import android.print.PrinterInfo;
import android.printservice.PrintServiceInfo;
+import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.AtomicFile;
@@ -68,10 +69,10 @@
private static final int MAX_FAVORITE_PRINTER_COUNT = 4;
private final List<PrinterInfo> mPrinters =
- new ArrayList<PrinterInfo>();
+ new ArrayList<>();
private final List<PrinterInfo> mFavoritePrinters =
- new ArrayList<PrinterInfo>();
+ new ArrayList<>();
private final PersistenceManager mPersistenceManager;
@@ -92,7 +93,7 @@
private void computeAndDeliverResult(ArrayMap<PrinterId, PrinterInfo> discoveredPrinters,
ArrayMap<PrinterId, PrinterInfo> favoritePrinters) {
- List<PrinterInfo> printers = new ArrayList<PrinterInfo>();
+ List<PrinterInfo> printers = new ArrayList<>();
// Add the updated favorite printers.
final int favoritePrinterCount = favoritePrinters.size();
@@ -142,7 +143,7 @@
// The contract is that if we already have a valid,
// result the we have to deliver it immediately.
if (!mPrinters.isEmpty()) {
- deliverResult(new ArrayList<PrinterInfo>(mPrinters));
+ deliverResult(new ArrayList<>(mPrinters));
}
// Always load the data to ensure discovery period is
// started and to make sure obsolete printers are updated.
@@ -184,11 +185,12 @@
+ mDiscoverySession.getPrinters().size()
+ " " + FusedPrintersProvider.this.hashCode());
}
+
updatePrinters(mDiscoverySession.getPrinters(), mFavoritePrinters);
}
});
final int favoriteCount = mFavoritePrinters.size();
- List<PrinterId> printerIds = new ArrayList<PrinterId>(favoriteCount);
+ List<PrinterId> printerIds = new ArrayList<>(favoriteCount);
for (int i = 0; i < favoriteCount; i++) {
printerIds.add(mFavoritePrinters.get(i).getId());
}
@@ -208,16 +210,19 @@
mPrintersUpdatedBefore = true;
- ArrayMap<PrinterId, PrinterInfo> printersMap =
- new ArrayMap<PrinterId, PrinterInfo>();
+ // Some of the found printers may have be a printer that is in the
+ // history but with its name changed. Hence, we try to update the
+ // printer to use its current name instead of the historical one.
+ mPersistenceManager.updatePrintersHistoricalNamesIfNeeded(printers);
+
+ ArrayMap<PrinterId, PrinterInfo> printersMap = new ArrayMap<>();
final int printerCount = printers.size();
for (int i = 0; i < printerCount; i++) {
PrinterInfo printer = printers.get(i);
printersMap.put(printer.getId(), printer);
}
- ArrayMap<PrinterId, PrinterInfo> favoritePrintersMap =
- new ArrayMap<PrinterId, PrinterInfo>();
+ ArrayMap<PrinterId, PrinterInfo> favoritePrintersMap = new ArrayMap<>();
final int favoritePrinterCount = favoritePrinters.size();
for (int i = 0; i < favoritePrinterCount; i++) {
PrinterInfo favoritePrinter = favoritePrinters.get(i);
@@ -310,7 +315,7 @@
for (int i = 0; i < favoritePrinterCount; i++) {
PrinterInfo favoritePrinter = mFavoritePrinters.get(i);
if (favoritePrinter.getId().equals(printerId)) {
- newFavoritePrinters = new ArrayList<PrinterInfo>();
+ newFavoritePrinters = new ArrayList<>();
newFavoritePrinters.addAll(mPrinters);
newFavoritePrinters.remove(i);
break;
@@ -344,7 +349,7 @@
private final AtomicFile mStatePersistFile;
- private List<PrinterInfo> mHistoricalPrinters = new ArrayList<PrinterInfo>();
+ private List<PrinterInfo> mHistoricalPrinters = new ArrayList<>();
private boolean mReadHistoryCompleted;
private boolean mReadHistoryInProgress;
@@ -382,17 +387,42 @@
mReadTask.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, (Void[]) null);
}
- @SuppressWarnings("unchecked")
+ public void updatePrintersHistoricalNamesIfNeeded(List<PrinterInfo> printers) {
+ boolean writeHistory = false;
+
+ final int printerCount = printers.size();
+ for (int i = 0; i < printerCount; i++) {
+ PrinterInfo printer = printers.get(i);
+ writeHistory |= renamePrinterIfNeeded(printer);
+ }
+
+ if (writeHistory) {
+ writePrinterHistory();
+ }
+ }
+
+ public boolean renamePrinterIfNeeded(PrinterInfo printer) {
+ boolean renamed = false;
+ final int printerCount = mHistoricalPrinters.size();
+ for (int i = 0; i < printerCount; i++) {
+ PrinterInfo historicalPrinter = mHistoricalPrinters.get(i);
+ if (historicalPrinter.getId().equals(printer.getId())
+ && !TextUtils.equals(historicalPrinter.getName(), printer.getName())) {
+ mHistoricalPrinters.set(i, printer);
+ renamed = true;
+ }
+ }
+ return renamed;
+ }
+
public void addPrinterAndWritePrinterHistory(PrinterInfo printer) {
if (mHistoricalPrinters.size() >= MAX_HISTORY_LENGTH) {
mHistoricalPrinters.remove(0);
}
mHistoricalPrinters.add(printer);
- new WriteTask().executeOnExecutor(AsyncTask.SERIAL_EXECUTOR,
- new ArrayList<PrinterInfo>(mHistoricalPrinters));
+ writePrinterHistory();
}
- @SuppressWarnings("unchecked")
public void removeHistoricalPrinterAndWritePrinterHistory(PrinterId printerId) {
boolean writeHistory = false;
final int printerCount = mHistoricalPrinters.size();
@@ -404,18 +434,22 @@
}
}
if (writeHistory) {
- new WriteTask().executeOnExecutor(AsyncTask.SERIAL_EXECUTOR,
- new ArrayList<PrinterInfo>(mHistoricalPrinters));
+ writePrinterHistory();
}
}
+ @SuppressWarnings("unchecked")
+ private void writePrinterHistory() {
+ new WriteTask().executeOnExecutor(AsyncTask.SERIAL_EXECUTOR,
+ new ArrayList<>(mHistoricalPrinters));
+ }
+
public boolean isHistoryChanged() {
return mLastReadHistoryTimestamp != mStatePersistFile.getBaseFile().lastModified();
}
private List<PrinterInfo> computeFavoritePrinters(List<PrinterInfo> printers) {
- Map<PrinterId, PrinterRecord> recordMap =
- new ArrayMap<PrinterId, PrinterRecord>();
+ Map<PrinterId, PrinterRecord> recordMap = new ArrayMap<>();
// Recompute the weights.
float currentWeight = 1.0f;
@@ -433,14 +467,14 @@
}
// Soft the favorite printers.
- List<PrinterRecord> favoriteRecords = new ArrayList<PrinterRecord>(
+ List<PrinterRecord> favoriteRecords = new ArrayList<>(
recordMap.values());
Collections.sort(favoriteRecords);
// Write the favorites to the output.
final int favoriteCount = Math.min(favoriteRecords.size(),
MAX_FAVORITE_PRINTER_COUNT);
- List<PrinterInfo> favoritePrinters = new ArrayList<PrinterInfo>(favoriteCount);
+ List<PrinterInfo> favoritePrinters = new ArrayList<>(favoriteCount);
for (int i = 0; i < favoriteCount; i++) {
PrinterInfo printer = favoriteRecords.get(i).printer;
favoritePrinters.add(printer);
@@ -482,7 +516,7 @@
List<PrintServiceInfo> services = printManager
.getEnabledPrintServices();
- Set<ComponentName> enabledComponents = new ArraySet<ComponentName>();
+ Set<ComponentName> enabledComponents = new ArraySet<>();
final int installedServiceCount = services.size();
for (int i = 0; i < installedServiceCount; i++) {
ServiceInfo serviceInfo = services.get(i).getResolveInfo().serviceInfo;
@@ -528,28 +562,23 @@
Log.i(LOG_TAG, "No existing printer history "
+ FusedPrintersProvider.this.hashCode());
}
- return new ArrayList<PrinterInfo>();
+ return new ArrayList<>();
}
try {
- List<PrinterInfo> printers = new ArrayList<PrinterInfo>();
+ List<PrinterInfo> printers = new ArrayList<>();
XmlPullParser parser = Xml.newPullParser();
parser.setInput(in, null);
parseState(parser, printers);
// Take a note which version of the history was read.
mLastReadHistoryTimestamp = mStatePersistFile.getBaseFile().lastModified();
return printers;
- } catch (IllegalStateException ise) {
- Slog.w(LOG_TAG, "Failed parsing ", ise);
- } catch (NullPointerException npe) {
- Slog.w(LOG_TAG, "Failed parsing ", npe);
- } catch (NumberFormatException nfe) {
- Slog.w(LOG_TAG, "Failed parsing ", nfe);
- } catch (XmlPullParserException xppe) {
- Slog.w(LOG_TAG, "Failed parsing ", xppe);
- } catch (IOException ioe) {
- Slog.w(LOG_TAG, "Failed parsing ", ioe);
- } catch (IndexOutOfBoundsException iobe) {
- Slog.w(LOG_TAG, "Failed parsing ", iobe);
+ } catch (IllegalStateException
+ | NullPointerException
+ | NumberFormatException
+ | XmlPullParserException
+ | IOException
+ | IndexOutOfBoundsException e) {
+ Slog.w(LOG_TAG, "Failed parsing ", e);
} finally {
IoUtils.closeQuietly(in);
}
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PageAdapter.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PageAdapter.java
index eaf268d..094edf8 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/PageAdapter.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PageAdapter.java
@@ -389,6 +389,7 @@
mSelectedPages = selectedPages;
mSelectedPageCount = PageRangeUtils.getNormalizedPageCount(
mSelectedPages, mDocumentPageCount);
+ updatePreviewAreaAndPageSize();
notifyDataSetChanged();
}
return mSelectedPages;
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index b79dbbe..d4feccd 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -516,6 +516,10 @@
<string name="quick_settings_time_label">Time</string>
<!-- QuickSettings: User [CHAR LIMIT=NONE] -->
<string name="quick_settings_user_label">Me</string>
+ <!-- QuickSettings: Title of the user detail panel [CHAR LIMIT=NONE] -->
+ <string name="quick_settings_user_title">User</string>
+ <!-- QuickSettings: Label on the item for adding a new user [CHAR LIMIT=NONE] -->
+ <string name="quick_settings_user_new_user">New user</string>
<!-- QuickSettings: Wifi [CHAR LIMIT=NONE] -->
<string name="quick_settings_wifi_label">Wi-Fi</string>
<!-- QuickSettings: Wifi (Not connected) [CHAR LIMIT=NONE] -->
diff --git a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
index a9a606f..b6d7d7e 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
@@ -64,11 +64,9 @@
Context mContext;
SystemServicesProxy mSystemServicesProxy;
-
- // Recents service binding
Handler mHandler;
- boolean mBootCompleted = false;
- boolean mStartAnimationTriggered = false;
+ boolean mBootCompleted;
+ boolean mStartAnimationTriggered;
// Task launching
RecentsConfiguration mConfig;
@@ -95,9 +93,7 @@
}
public void onStart() {
- if (Console.Enabled) {
- Console.log(Constants.Log.App.RecentsComponent, "[RecentsComponent|start]");
- }
+ // Do nothing
}
public void onBootCompleted() {
@@ -106,9 +102,6 @@
/** Shows the recents */
public void onShowRecents(boolean triggeredFromAltTab, View statusBarView) {
- if (Console.Enabled) {
- Console.log(Constants.Log.App.RecentsComponent, "[RecentsComponent|showRecents]");
- }
mStatusBarView = statusBarView;
mTriggeredFromAltTab = triggeredFromAltTab;
@@ -121,10 +114,6 @@
/** Hides the recents */
public void onHideRecents(boolean triggeredFromAltTab) {
- if (Console.Enabled) {
- Console.log(Constants.Log.App.RecentsComponent, "[RecentsComponent|hideRecents]");
- }
-
if (mBootCompleted) {
if (isRecentsTopMost(getTopMostTask(), null)) {
// Notify recents to hide itself
@@ -139,13 +128,6 @@
/** Toggles the alternate recents activity */
public void onToggleRecents(View statusBarView) {
- if (Console.Enabled) {
- Console.logStartTracingTime(Constants.Log.App.TimeRecentsStartup,
- Constants.Log.App.TimeRecentsStartupKey);
- Console.logStartTracingTime(Constants.Log.App.TimeRecentsLaunchTask,
- Constants.Log.App.TimeRecentsLaunchKey);
- Console.log(Constants.Log.App.RecentsComponent, "[RecentsComponent|toggleRecents]", "");
- }
mStatusBarView = statusBarView;
mTriggeredFromAltTab = false;
@@ -223,14 +205,6 @@
intent.setPackage(mContext.getPackageName());
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
mContext.sendBroadcast(intent);
-
- // Time this path
- if (Console.Enabled) {
- Console.logTraceTime(Constants.Log.App.TimeRecentsStartup,
- Constants.Log.App.TimeRecentsStartupKey, "receivedToggleRecents");
- Console.logTraceTime(Constants.Log.App.TimeRecentsLaunchTask,
- Constants.Log.App.TimeRecentsLaunchKey, "receivedToggleRecents");
- }
mLastToggleTime = System.currentTimeMillis();
return;
} else {
@@ -395,11 +369,6 @@
startAlternateRecentsActivity(topTask, opts, null);
}
}
-
- if (Console.Enabled) {
- Console.logTraceTime(Constants.Log.App.TimeRecentsStartup,
- Constants.Log.App.TimeRecentsStartupKey, "startRecentsActivity");
- }
mLastToggleTime = System.currentTimeMillis();
}
@@ -417,10 +386,9 @@
intent.putExtra(EXTRA_TRIGGERED_FROM_ALT_TAB, mTriggeredFromAltTab);
intent.putExtra(EXTRA_TRIGGERED_FROM_TASK_ID, (topTask != null) ? topTask.id : -1);
if (opts != null) {
- mContext.startActivityAsUser(intent, opts.toBundle(), new UserHandle(
- UserHandle.USER_CURRENT));
+ mContext.startActivityAsUser(intent, opts.toBundle(), UserHandle.CURRENT);
} else {
- mContext.startActivityAsUser(intent, new UserHandle(UserHandle.USER_CURRENT));
+ mContext.startActivityAsUser(intent, UserHandle.CURRENT);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Constants.java b/packages/SystemUI/src/com/android/systemui/recents/Constants.java
index e7ac2e1..c49e244 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Constants.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Constants.java
@@ -52,43 +52,6 @@
}
}
- public static class Log {
- public static class App {
- public static final String TimeRecentsStartupKey = "startup";
- public static final String TimeRecentsLaunchKey = "launchTask";
- public static final String TimeRecentsScreenshotTransitionKey = "screenshot";
- public static final boolean TimeRecentsStartup = false;
- public static final boolean TimeRecentsLaunchTask = false;
- public static final boolean TimeRecentsScreenshotTransition = false;
-
-
- public static final boolean RecentsComponent = false;
- public static final boolean TaskDataLoader = false;
- public static final boolean SystemUIHandshake = false;
- public static final boolean TimeSystemCalls = false;
- public static final boolean Memory = false;
- public static final boolean Search = false;
- }
-
- public static class UI {
- public static final boolean Draw = false;
- public static final boolean ClickEvents = false;
- public static final boolean TouchEvents = false;
- public static final boolean MeasureAndLayout = false;
- public static final boolean HwLayers = false;
- public static final boolean Focus = false;
- }
-
- public static class TaskStack {
- public static final boolean SynchronizeViewsWithModel = false;
- }
-
- public static class ViewPool {
- public static final boolean PoolCallbacks = false;
- }
- }
-
- /** XXX: We are going to move almost all of these into a resource once they are nailed down. */
public static class Values {
public static class App {
public static int AppWidgetHostId = 1024;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index 1e581c1..29a0262 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -52,16 +52,23 @@
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
-/* Activity */
+/**
+ * The main Recents activity that is started from AlternateRecentsComponent.
+ */
public class RecentsActivity extends Activity implements RecentsView.RecentsViewCallbacks,
RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks,
FullscreenTransitionOverlayView.FullScreenTransitionViewCallbacks {
+ // Actions and Extras sent from AlternateRecentsComponent
final static String EXTRA_TRIGGERED_FROM_ALT_TAB = "extra_triggered_from_alt_tab";
final static String ACTION_START_ENTER_ANIMATION = "action_start_enter_animation";
final static String ACTION_TOGGLE_RECENTS_ACTIVITY = "action_toggle_recents_activity";
final static String ACTION_HIDE_RECENTS_ACTIVITY = "action_hide_recents_activity";
+ RecentsConfiguration mConfig;
+ boolean mVisible;
+
+ // Top level views
RecentsView mRecentsView;
SystemBarScrimViews mScrimViews;
ViewStub mEmptyViewStub;
@@ -69,29 +76,29 @@
ViewStub mFullscreenOverlayStub;
FullscreenTransitionOverlayView mFullScreenOverlayView;
- RecentsConfiguration mConfig;
-
+ // Search AppWidget
RecentsAppWidgetHost mAppWidgetHost;
AppWidgetProviderInfo mSearchAppWidgetInfo;
AppWidgetHostView mSearchAppWidgetHostView;
- boolean mVisible;
// Runnables to finish the Recents activity
- FinishRecentsRunnable mFinishRunnable = new FinishRecentsRunnable(true);
+ FinishRecentsRunnable mFinishRunnable = new FinishRecentsRunnable();
FinishRecentsRunnable mFinishLaunchHomeRunnable;
/**
- * A Runnable to finish Recents either with/without a transition, and either by calling finish()
- * or just launching the specified intent.
+ * A common Runnable to finish Recents either by calling finish() (with a custom animation) or
+ * launching Home with some ActivityOptions. Generally we always launch home when we exit
+ * Recents rather than just finishing the activity since we don't know what is behind Recents in
+ * the task stack. The only case where we finish() directly is when we are cancelling the full
+ * screen transition from the app.
*/
class FinishRecentsRunnable implements Runnable {
- boolean mUseCustomFinishTransition;
Intent mLaunchIntent;
ActivityOptions mLaunchOpts;
- public FinishRecentsRunnable(boolean withTransition) {
- mUseCustomFinishTransition = withTransition;
+ public FinishRecentsRunnable() {
+ // Do nothing
}
/**
@@ -111,77 +118,66 @@
// Finish Recents
if (mLaunchIntent != null) {
if (mLaunchOpts != null) {
- startActivityAsUser(mLaunchIntent, new UserHandle(UserHandle.USER_CURRENT));
+ startActivityAsUser(mLaunchIntent, UserHandle.CURRENT);
} else {
- startActivityAsUser(mLaunchIntent, mLaunchOpts.toBundle(),
- new UserHandle(UserHandle.USER_CURRENT));
+ startActivityAsUser(mLaunchIntent, mLaunchOpts.toBundle(), UserHandle.CURRENT);
}
} else {
finish();
- if (mUseCustomFinishTransition) {
- overridePendingTransition(R.anim.recents_to_launcher_enter,
- R.anim.recents_to_launcher_exit);
- }
+ overridePendingTransition(R.anim.recents_to_launcher_enter,
+ R.anim.recents_to_launcher_exit);
}
}
}
- // Broadcast receiver to handle messages from AlternateRecentsComponent
+ /**
+ * Broadcast receiver to handle messages from AlternateRecentsComponent.
+ */
final BroadcastReceiver mServiceBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
- if (Console.Enabled) {
- Console.log(Constants.Log.App.SystemUIHandshake,
- "[RecentsActivity|serviceBroadcast]", action, Console.AnsiRed);
- }
if (action.equals(ACTION_HIDE_RECENTS_ACTIVITY)) {
if (intent.getBooleanExtra(EXTRA_TRIGGERED_FROM_ALT_TAB, false)) {
- // Dismiss recents, launching the focused task
- dismissRecentsIfVisible();
+ // If we are hiding from releasing Alt-Tab, dismiss Recents to the focused app
+ dismissRecentsToFocusedTaskOrHome(false);
} else {
- // If we are mid-animation into Recents, then reverse it and finish
- if (mFullScreenOverlayView == null ||
- !mFullScreenOverlayView.cancelAnimateOnEnterRecents(mFinishRunnable)) {
- // Otherwise, either finish Recents, or launch Home directly
- ReferenceCountedTrigger exitTrigger = new ReferenceCountedTrigger(context,
- null, mFinishLaunchHomeRunnable, null);
- mRecentsView.startExitToHomeAnimation(
- new ViewAnimation.TaskViewExitContext(exitTrigger));
- }
+ // Otherwise, dismiss Recents to Home
+ dismissRecentsToHome(true);
}
} else if (action.equals(ACTION_TOGGLE_RECENTS_ACTIVITY)) {
- // Try and unfilter and filtered stacks
- if (!mRecentsView.unfilterFilteredStacks()) {
- // If there are no filtered stacks, dismiss recents and launch the first task
- dismissRecentsIfVisible();
- }
+ // If we are toggling Recents, then first unfilter any filtered stacks first
+ dismissRecentsToFocusedTaskOrHome(true);
} else if (action.equals(ACTION_START_ENTER_ANIMATION)) {
// Try and start the enter animation (or restart it on configuration changed)
ReferenceCountedTrigger t = new ReferenceCountedTrigger(context, null, null, null);
mRecentsView.startEnterRecentsAnimation(new ViewAnimation.TaskViewEnterContext(
mFullScreenOverlayView, t));
- // Call our callback
onEnterAnimationTriggered();
}
}
};
- // Broadcast receiver to handle messages from the system
+ /**
+ * Broadcast receiver to handle messages from the system
+ */
final BroadcastReceiver mSystemBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
- if (action.equals(Intent.ACTION_SCREEN_OFF) && mVisible) {
- mFinishLaunchHomeRunnable.run();
+ if (action.equals(Intent.ACTION_SCREEN_OFF)) {
+ // When the screen turns off, dismiss Recents to Home
+ dismissRecentsToHome(false);
} else if (action.equals(SearchManager.INTENT_GLOBAL_SEARCH_ACTIVITY_CHANGED)) {
- // Refresh the search widget
+ // When the search activity changes, update the Search widget
refreshSearchWidget();
}
}
};
- // Debug trigger
+ /**
+ * A custom debug trigger to listen for a debug key chord.
+ */
final DebugTrigger mDebugTrigger = new DebugTrigger(new Runnable() {
@Override
public void run() {
@@ -211,15 +207,17 @@
mConfig.launchedToTaskId = launchIntent.getIntExtra(
AlternateRecentsComponent.EXTRA_TRIGGERED_FROM_TASK_ID, -1);
- // Add the default no-recents layout
- if (mEmptyView == null) {
- mEmptyView = mEmptyViewStub.inflate();
- }
+ // Update the top level view's visibilities
if (mConfig.launchedWithNoRecentTasks) {
+ if (mEmptyView == null) {
+ mEmptyView = mEmptyViewStub.inflate();
+ }
mEmptyView.setVisibility(View.VISIBLE);
mRecentsView.setSearchBarVisibility(View.GONE);
} else {
- mEmptyView.setVisibility(View.GONE);
+ if (mEmptyView != null) {
+ mEmptyView.setVisibility(View.GONE);
+ }
if (mRecentsView.hasSearchBar()) {
mRecentsView.setSearchBarVisibility(View.VISIBLE);
} else {
@@ -227,7 +225,7 @@
}
}
- // Show the scrim if we animate into Recents without window transitions
+ // Animate the SystemUI scrims into view
mScrimViews.prepareEnterRecentsAnimation();
}
@@ -250,12 +248,6 @@
ssp.unbindSearchAppWidget(mAppWidgetHost, appWidgetId);
appWidgetId = -1;
}
- if (Console.Enabled) {
- Console.log(Constants.Log.App.SystemUIHandshake,
- "[RecentsActivity|onCreate|settings|appWidgetId]",
- "Id: " + appWidgetId,
- Console.AnsiBlue);
- }
}
// If there is no id, then bind a new search app widget
@@ -263,13 +255,6 @@
Pair<Integer, AppWidgetProviderInfo> widgetInfo =
ssp.bindSearchAppWidget(mAppWidgetHost);
if (widgetInfo != null) {
- if (Console.Enabled) {
- Console.log(Constants.Log.App.SystemUIHandshake,
- "[RecentsActivity|onCreate|searchWidget]",
- "Id: " + widgetInfo.first + " Info: " + widgetInfo.second,
- Console.AnsiBlue);
- }
-
// Save the app widget id into the settings
mConfig.updateSearchBarAppWidgetId(this, widgetInfo.first);
mSearchAppWidgetInfo = widgetInfo.second;
@@ -283,12 +268,6 @@
if (Constants.DebugFlags.App.EnableSearchLayout) {
int appWidgetId = mConfig.searchBarAppWidgetId;
if (appWidgetId >= 0) {
- if (Console.Enabled) {
- Console.log(Constants.Log.App.SystemUIHandshake,
- "[RecentsActivity|onCreate|addSearchAppWidgetView]",
- "Id: " + appWidgetId,
- Console.AnsiBlue);
- }
mSearchAppWidgetHostView = mAppWidgetHost.createView(this, appWidgetId,
mSearchAppWidgetInfo);
Bundle opts = new Bundle();
@@ -305,28 +284,50 @@
}
/** Dismisses recents if we are already visible and the intent is to toggle the recents view */
- boolean dismissRecentsIfVisible() {
+ boolean dismissRecentsToFocusedTaskOrHome(boolean checkFilteredStackState) {
if (mVisible) {
- // If we are mid-animation into Recents, then reverse it and finish
- if (mFullScreenOverlayView == null ||
- !mFullScreenOverlayView.cancelAnimateOnEnterRecents(mFinishRunnable)) {
- // If we have a focused task, then launch that task
- if (!mRecentsView.launchFocusedTask()) {
- if (mConfig.launchedFromHome) {
- // Just start the animation out of recents
- ReferenceCountedTrigger exitTrigger = new ReferenceCountedTrigger(this,
- null, mFinishLaunchHomeRunnable, null);
- mRecentsView.startExitToHomeAnimation(
- new ViewAnimation.TaskViewExitContext(exitTrigger));
- } else {
- // Otherwise, try and launch the first task
- if (!mRecentsView.launchFirstTask()) {
- // If there are no tasks, then just finish recents
- mFinishLaunchHomeRunnable.run();
- }
- }
- }
+ // If we are mid-animation into Recents, reverse the animation now
+ if (mFullScreenOverlayView != null &&
+ mFullScreenOverlayView.cancelAnimateOnEnterRecents(mFinishRunnable)) return true;
+ // If we currently have filtered stacks, then unfilter those first
+ if (checkFilteredStackState &&
+ mRecentsView.unfilterFilteredStacks()) return true;
+ // If we have a focused Task, launch that Task now
+ if (mRecentsView.launchFocusedTask()) return true;
+ // If we launched from Home, then return to Home
+ if (mConfig.launchedFromHome) {
+ dismissRecentsToHomeRaw(true);
+ return true;
}
+ // Otherwise, try and return to the first Task in the stack
+ if (mRecentsView.launchFirstTask()) return true;
+ // If none of the other cases apply, then just go Home
+ dismissRecentsToHomeRaw(true);
+ return true;
+ }
+ return false;
+ }
+
+ /** Dismisses Recents directly to Home. */
+ void dismissRecentsToHomeRaw(boolean animated) {
+ if (animated) {
+ ReferenceCountedTrigger exitTrigger = new ReferenceCountedTrigger(this,
+ null, mFinishLaunchHomeRunnable, null);
+ mRecentsView.startExitToHomeAnimation(
+ new ViewAnimation.TaskViewExitContext(exitTrigger));
+ } else {
+ mFinishLaunchHomeRunnable.run();
+ }
+ }
+
+ /** Dismisses Recents directly to Home if we currently aren't transitioning. */
+ boolean dismissRecentsToHome(boolean animated) {
+ if (mVisible) {
+ // If we are mid-animation into Recents, reverse the animation now
+ if (mFullScreenOverlayView != null &&
+ mFullScreenOverlayView.cancelAnimateOnEnterRecents(mFinishRunnable)) return true;
+ // Return to Home
+ dismissRecentsToHomeRaw(animated);
return true;
}
return false;
@@ -336,13 +337,6 @@
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- if (Console.Enabled) {
- Console.logDivider(Constants.Log.App.SystemUIHandshake);
- Console.log(Constants.Log.App.SystemUIHandshake, "[RecentsActivity|onCreate]",
- getIntent().getAction() + " visible: " + mVisible, Console.AnsiRed);
- Console.logTraceTime(Constants.Log.App.TimeRecentsStartup,
- Constants.Log.App.TimeRecentsStartupKey, "onCreate");
- }
// Initialize the loader and the configuration
RecentsTaskLoader.initialize(this);
@@ -410,11 +404,13 @@
}
void onConfigurationChange() {
+ // Update RecentsConfiguration
+ mConfig = RecentsConfiguration.reinitialize(this);
+
// Try and start the enter animation (or restart it on configuration changed)
ReferenceCountedTrigger t = new ReferenceCountedTrigger(this, null, null, null);
mRecentsView.startEnterRecentsAnimation(new ViewAnimation.TaskViewEnterContext(
mFullScreenOverlayView, t));
- // Call our callback
onEnterAnimationTriggered();
}
@@ -423,18 +419,6 @@
super.onNewIntent(intent);
setIntent(intent);
- if (Console.Enabled) {
- Console.logDivider(Constants.Log.App.SystemUIHandshake);
- Console.log(Constants.Log.App.SystemUIHandshake, "[RecentsActivity|onNewIntent]",
- intent.getAction() + " visible: " + mVisible, Console.AnsiRed);
- Console.logTraceTime(Constants.Log.App.TimeRecentsStartup,
- Constants.Log.App.TimeRecentsStartupKey, "onNewIntent");
- }
-
- // Initialize the loader and the configuration
- RecentsTaskLoader.initialize(this);
- mConfig = RecentsConfiguration.reinitialize(this);
-
// Update the recent tasks
updateRecentsTasks(intent);
@@ -446,10 +430,6 @@
@Override
protected void onStart() {
- if (Console.Enabled) {
- Console.log(Constants.Log.App.SystemUIHandshake, "[RecentsActivity|onStart]", "",
- Console.AnsiRed);
- }
super.onStart();
// Register the broadcast receiver to handle messages from our service
@@ -462,10 +442,6 @@
@Override
protected void onResume() {
- if (Console.Enabled) {
- Console.log(Constants.Log.App.SystemUIHandshake, "[RecentsActivity|onResume]", "",
- Console.AnsiRed);
- }
super.onResume();
// Start listening for widget package changes if there is one bound, post it since we don't
@@ -484,64 +460,28 @@
}, 1);
}
+ // Mark Recents as visible
mVisible = true;
}
@Override
- public void onAttachedToWindow() {
- if (Console.Enabled) {
- Console.log(Constants.Log.App.SystemUIHandshake,
- "[RecentsActivity|onAttachedToWindow]", "",
- Console.AnsiRed);
- }
- super.onAttachedToWindow();
- }
-
- @Override
- public void onDetachedFromWindow() {
- if (Console.Enabled) {
- Console.log(Constants.Log.App.SystemUIHandshake,
- "[RecentsActivity|onDetachedFromWindow]", "",
- Console.AnsiRed);
- }
- super.onDetachedFromWindow();
- }
-
- @Override
- protected void onPause() {
- if (Console.Enabled) {
- Console.log(Constants.Log.App.SystemUIHandshake, "[RecentsActivity|onPause]", "",
- Console.AnsiRed);
- }
- super.onPause();
- }
-
- @Override
protected void onStop() {
- if (Console.Enabled) {
- Console.log(Constants.Log.App.SystemUIHandshake, "[RecentsActivity|onStop]", "",
- Console.AnsiRed);
- }
super.onStop();
// Unregister the RecentsService receiver
unregisterReceiver(mServiceBroadcastReceiver);
// Stop listening for widget package changes if there was one bound
- if (mConfig.searchBarAppWidgetId >= 0) {
+ if (mAppWidgetHost.isListening()) {
mAppWidgetHost.stopListening();
}
}
@Override
protected void onDestroy() {
- if (Console.Enabled) {
- Console.log(Constants.Log.App.SystemUIHandshake, "[RecentsActivity|onDestroy]", "",
- Console.AnsiRed);
- }
super.onDestroy();
- // Unregister the screen off receiver
+ // Unregister the system broadcast receivers
unregisterReceiver(mSystemBroadcastReceiver);
RecentsTaskLoader.getInstance().unregisterReceivers();
}
@@ -583,26 +523,8 @@
// Test mode where back does not do anything
if (mConfig.debugModeEnabled) return;
- // If we are mid-animation into Recents, then reverse it and finish
- if (mFullScreenOverlayView == null ||
- !mFullScreenOverlayView.cancelAnimateOnEnterRecents(mFinishRunnable)) {
- // If we are currently filtering in any stacks, unfilter them first
- if (!mRecentsView.unfilterFilteredStacks()) {
- if (mConfig.launchedFromHome) {
- // Just start the animation out of recents
- ReferenceCountedTrigger exitTrigger = new ReferenceCountedTrigger(this,
- null, mFinishLaunchHomeRunnable, null);
- mRecentsView.startExitToHomeAnimation(
- new ViewAnimation.TaskViewExitContext(exitTrigger));
- } else {
- // Otherwise, try and launch the first task
- if (!mRecentsView.launchFirstTask()) {
- // If there are no tasks, then just finish recents
- mFinishLaunchHomeRunnable.run();
- }
- }
- }
- }
+ // Dismiss Recents to the focused Task or Home
+ dismissRecentsToFocusedTaskOrHome(true);
}
/** Called when debug mode is triggered */
@@ -623,7 +545,7 @@
/** Called when the enter recents animation is triggered. */
public void onEnterAnimationTriggered() {
- // Animate the scrims in
+ // Animate the SystemUI scrim views
mScrimViews.startEnterRecentsAnimation();
}
@@ -644,7 +566,7 @@
@Override
public void onExitToHomeAnimationTriggered() {
- // Animate the scrims out
+ // Animate the SystemUI scrim views out
mScrimViews.startExitRecentsAnimation();
}
@@ -664,7 +586,6 @@
@Override
public void refreshSearchWidget() {
- // Load the Search widget again
bindSearchBarAppWidget();
addSearchBarAppWidgetView();
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsAppWidgetHost.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsAppWidgetHost.java
index 43d7a54..a63e167 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsAppWidgetHost.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsAppWidgetHost.java
@@ -33,6 +33,7 @@
Context mContext;
RecentsAppWidgetHostCallbacks mCb;
RecentsConfiguration mConfig;
+ boolean mIsListening;
public RecentsAppWidgetHost(Context context, int hostId) {
super(context, hostId);
@@ -42,6 +43,7 @@
public void startListening(RecentsAppWidgetHostCallbacks cb) {
mCb = cb;
+ mIsListening = true;
super.startListening();
}
@@ -51,6 +53,11 @@
// Ensure that we release any references to the callbacks
mCb = null;
mContext = null;
+ mIsListening = false;
+ }
+
+ public boolean isListening() {
+ return mIsListening;
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
index e62d989..439765e 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
@@ -35,6 +35,7 @@
* NOTE: We should not hold any references to a Context from a static instance */
public class RecentsConfiguration {
static RecentsConfiguration sInstance;
+ static int sPrevConfigurationHashCode;
DisplayMetrics mDisplayMetrics;
@@ -138,7 +139,11 @@
if (sInstance == null) {
sInstance = new RecentsConfiguration(context);
}
- sInstance.update(context);
+ int configHashCode = context.getResources().getConfiguration().hashCode();
+ if (sPrevConfigurationHashCode != configHashCode) {
+ sInstance.update(context);
+ sPrevConfigurationHashCode = configHashCode;
+ }
return sInstance;
}
@@ -179,10 +184,8 @@
transposeRecentsLayoutWithOrientation =
res.getBoolean(R.bool.recents_transpose_layout_with_orientation);
- // Search bar
+ // Search Bar
searchBarSpaceHeightPx = res.getDimensionPixelSize(R.dimen.recents_search_bar_space_height);
-
- // Update the search widget id
searchBarAppWidgetId = settings.getInt(Constants.Values.App.Key_SearchAppWidgetId, -1);
// Task stack
@@ -242,12 +245,6 @@
// Nav bar scrim
navBarScrimEnterDuration =
res.getInteger(R.integer.recents_nav_bar_scrim_enter_duration);
-
- if (Console.Enabled) {
- Console.log(Constants.Log.UI.MeasureAndLayout,
- "[RecentsConfiguration|orientation]", isLandscape ? "Landscape" : "Portrait",
- Console.AnsiGreen);
- }
}
/** Updates the system insets */
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
index b8beda6f..ced4043 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -31,6 +31,7 @@
import android.content.pm.ActivityInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
+import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
@@ -80,6 +81,8 @@
ComponentName mAssistComponent;
Bitmap mDummyIcon;
+ int mDummyThumbnailWidth;
+ int mDummyThumbnailHeight;
Paint mBgProtectionPaint;
Canvas mBgProtectionCanvas;
@@ -96,6 +99,13 @@
mDisplay = mWm.getDefaultDisplay();
mRecentsPackage = context.getPackageName();
+ // Get the dummy thumbnail width/heights
+ Resources res = context.getResources();
+ int wId = com.android.internal.R.dimen.thumbnail_width;
+ int hId = com.android.internal.R.dimen.thumbnail_height;
+ mDummyThumbnailWidth = res.getDimensionPixelSize(wId);
+ mDummyThumbnailHeight = res.getDimensionPixelSize(hId);
+
// Create the protection paints
mBgProtectionPaint = new Paint();
mBgProtectionPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_ATOP));
@@ -213,7 +223,8 @@
// If we are mocking, then just return a dummy thumbnail
if (Constants.DebugFlags.App.EnableSystemServicesProxy) {
- Bitmap thumbnail = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
+ Bitmap thumbnail = Bitmap.createBitmap(mDummyThumbnailWidth, mDummyThumbnailHeight,
+ Bitmap.Config.ARGB_8888);
thumbnail.eraseColor(0xff333333);
return thumbnail;
}
@@ -239,6 +250,8 @@
*/
public static Bitmap getThumbnail(ActivityManager activityManager, int taskId) {
ActivityManager.TaskThumbnail taskThumbnail = activityManager.getTaskThumbnail(taskId);
+ if (taskThumbnail == null) return null;
+
Bitmap thumbnail = taskThumbnail.mainThumbnail;
ParcelFileDescriptor descriptor = taskThumbnail.thumbnailFileDescriptor;
if (thumbnail == null && descriptor != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
index cbb8892..71979c4 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
@@ -29,7 +29,6 @@
import android.os.UserHandle;
import com.android.systemui.recents.Constants;
import com.android.systemui.recents.RecentsConfiguration;
-import com.android.systemui.recents.misc.Console;
import com.android.systemui.recents.misc.SystemServicesProxy;
import java.util.Collections;
@@ -44,9 +43,6 @@
/** Adds a new task to the load queue */
void addTask(Task t) {
- if (Console.Enabled) {
- Console.log(Constants.Log.App.TaskDataLoader, " [TaskResourceLoadQueue|addTask]");
- }
if (!mQueue.contains(t)) {
mQueue.add(t);
}
@@ -60,25 +56,16 @@
* force reloaded.
*/
Task nextTask() {
- if (Console.Enabled) {
- Console.log(Constants.Log.App.TaskDataLoader, " [TaskResourceLoadQueue|nextTask]");
- }
return mQueue.poll();
}
/** Removes a task from the load queue */
void removeTask(Task t) {
- if (Console.Enabled) {
- Console.log(Constants.Log.App.TaskDataLoader, " [TaskResourceLoadQueue|removeTask]");
- }
mQueue.remove(t);
}
/** Clears all the tasks from the load queue */
void clearTasks() {
- if (Console.Enabled) {
- Console.log(Constants.Log.App.TaskDataLoader, " [TaskResourceLoadQueue|clearTasks]");
- }
mQueue.clear();
}
@@ -124,9 +111,6 @@
/** Restarts the loader thread */
void start(Context context) {
- if (Console.Enabled) {
- Console.log(Constants.Log.App.TaskDataLoader, "[TaskResourceLoader|start]");
- }
mContext = context;
mCancelled = false;
mSystemServicesProxy = new SystemServicesProxy(context);
@@ -138,9 +122,6 @@
/** Requests the loader thread to stop after the current iteration */
void stop() {
- if (Console.Enabled) {
- Console.log(Constants.Log.App.TaskDataLoader, "[TaskResourceLoader|stop]");
- }
// Mark as cancelled for the thread to pick up
mCancelled = true;
mSystemServicesProxy = null;
@@ -154,25 +135,13 @@
@Override
public void run() {
while (true) {
- if (Console.Enabled) {
- Console.log(Constants.Log.App.TaskDataLoader,
- "[TaskResourceLoader|run|" + Thread.currentThread().getId() + "]");
- }
if (mCancelled) {
- if (Console.Enabled) {
- Console.log(Constants.Log.App.TaskDataLoader,
- "[TaskResourceLoader|cancel|" + Thread.currentThread().getId() + "]");
- }
// We have to unset the context here, since the background thread may be using it
// when we call stop()
mContext = null;
// If we are cancelled, then wait until we are started again
synchronized(mLoadThread) {
try {
- if (Console.Enabled) {
- Console.log(Constants.Log.App.TaskDataLoader,
- "[TaskResourceLoader|waitOnLoadThreadCancelled]");
- }
mLoadThread.wait();
} catch (InterruptedException ie) {
ie.printStackTrace();
@@ -186,11 +155,6 @@
if (t != null) {
Drawable cachedIcon = mApplicationIconCache.getCheckLastActiveTime(t.key);
Bitmap cachedThumbnail = mThumbnailCache.getCheckLastActiveTime(t.key);
- if (Console.Enabled) {
- Console.log(Constants.Log.App.TaskDataLoader,
- " [TaskResourceLoader|load]",
- t + " icon: " + cachedIcon + " thumbnail: " + cachedThumbnail);
- }
// Load the application icon if it is stale or we haven't cached one yet
if (cachedIcon == null) {
Drawable icon = null;
@@ -198,10 +162,6 @@
t.userId);
if (info != null) {
icon = ssp.getActivityIcon(info, t.userId);
- if (Console.Enabled) {
- Console.log(Constants.Log.App.TaskDataLoader,
- " [TaskResourceLoader|loadedIcon]", icon);
- }
}
// If we can't load the icon, then set the default application icon into the
// cache. This will remain until the task's last active time is updated.
@@ -213,10 +173,6 @@
Bitmap thumbnail = ssp.getTaskThumbnail(t.key.id);
if (thumbnail != null) {
thumbnail.setHasAlpha(false);
- if (Console.Enabled) {
- Console.log(Constants.Log.App.TaskDataLoader,
- " [TaskResourceLoader|loadedThumbnail]", thumbnail);
- }
}
// Even if we can't load the icon, we set the default thumbnail into the
// cache. This will remain until the task's last active time is updated.
@@ -240,10 +196,6 @@
if (!mCancelled && mLoadQueue.isEmpty()) {
synchronized(mLoadQueue) {
try {
- if (Console.Enabled) {
- Console.log(Constants.Log.App.TaskDataLoader,
- "[TaskResourceLoader|waitOnLoadQueue]");
- }
mWaitingOnLoadQueue = true;
mLoadQueue.wait();
mWaitingOnLoadQueue = false;
@@ -290,12 +242,6 @@
int thumbnailCacheSize = Constants.DebugFlags.App.DisableBackgroundCache ? 1 :
mMaxThumbnailCacheSize;
- if (Console.Enabled) {
- Console.log(Constants.Log.App.TaskDataLoader,
- "[RecentsTaskLoader|init]", "thumbnailCache: " + thumbnailCacheSize +
- " iconCache: " + iconCacheSize);
- }
-
// Create the default assets
Bitmap icon = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
icon.eraseColor(0x00000000);
@@ -315,13 +261,6 @@
mThumbnailCache = new BitmapLruCache(thumbnailCacheSize);
mLoader = new TaskResourceLoader(mLoadQueue, mApplicationIconCache, mThumbnailCache,
mDefaultThumbnail, mDefaultApplicationIcon);
-
- if (Console.Enabled) {
- Console.log(Constants.Log.App.TaskDataLoader,
- "[RecentsTaskLoader|defaultBitmaps]",
- "icon: " + mDefaultApplicationIcon +
- " default thumbnail: " + mDefaultThumbnail, Console.AnsiRed);
- }
}
/** Initializes the recents task loader */
@@ -343,29 +282,15 @@
}
private static List<ActivityManager.RecentTaskInfo> getRecentTasks(SystemServicesProxy ssp) {
- long t1 = System.currentTimeMillis();
-
List<ActivityManager.RecentTaskInfo> tasks =
ssp.getRecentTasks(50, UserHandle.CURRENT.getIdentifier());
Collections.reverse(tasks);
- if (Console.Enabled) {
- Console.log(Constants.Log.App.TimeSystemCalls,
- "[RecentsTaskLoader|getRecentTasks]",
- "" + (System.currentTimeMillis() - t1) + "ms");
- Console.log(Constants.Log.App.TaskDataLoader,
- "[RecentsTaskLoader|tasks]", "" + tasks.size());
- }
return tasks;
}
/** Reload the set of recent tasks */
public SpaceNode reload(Context context, int preloadCount) {
- long t1 = System.currentTimeMillis();
-
- if (Console.Enabled) {
- Console.log(Constants.Log.App.TaskDataLoader, "[RecentsTaskLoader|reload]");
- }
RecentsConfiguration config = RecentsConfiguration.getInstance();
Resources res = context.getResources();
LinkedHashSet<Task> tasksToLoad = new LinkedHashSet<Task>();
@@ -378,7 +303,6 @@
List<ActivityManager.RecentTaskInfo> tasks = getRecentTasks(ssp);
// Add each task to the task stack
- t1 = System.currentTimeMillis();
int taskCount = tasks.size();
for (int i = 0; i < taskCount; i++) {
ActivityManager.RecentTaskInfo t = tasks.get(i);
@@ -408,12 +332,6 @@
// Preload the specified number of apps
if (i >= (taskCount - preloadCount)) {
- if (Console.Enabled) {
- Console.log(Constants.Log.App.TaskDataLoader,
- "[RecentsTaskLoader|preloadTask]",
- "i: " + i + " task: " + t.baseIntent.getComponent().getPackageName());
- }
-
// Load the icon from the cache if possible
task.applicationIcon = mApplicationIconCache.getCheckLastActiveTime(task.key);
if (task.applicationIcon == null) {
@@ -436,10 +354,6 @@
// Load the thumbnail (if possible and not the foremost task, from the cache)
task.thumbnail = mThumbnailCache.getCheckLastActiveTime(task.key);
if (task.thumbnail == null) {
- if (Console.Enabled) {
- Console.log(Constants.Log.App.TaskDataLoader,
- "[RecentsTaskLoader|loadingTaskThumbnail]");
- }
if (isForemostTask) {
// We force loading the thumbnail icon for the foremost task
task.thumbnail = ssp.getTaskThumbnail(task.key.id);
@@ -460,17 +374,8 @@
}
// Add the task to the stack
- if (Console.Enabled) {
- Console.log(Constants.Log.App.TaskDataLoader,
- " [RecentsTaskLoader|task]", t.baseIntent.getComponent().getPackageName());
- }
stack.addTask(task);
}
- if (Console.Enabled) {
- Console.log(Constants.Log.App.TimeSystemCalls,
- "[RecentsTaskLoader|getAllTaskTopThumbnail]",
- "" + (System.currentTimeMillis() - t1) + "ms");
- }
// Simulate the groupings that we describe
stack.createAffiliatedGroupings();
@@ -512,12 +417,6 @@
Drawable applicationIcon = mApplicationIconCache.get(t.key);
Bitmap thumbnail = mThumbnailCache.get(t.key);
- if (Console.Enabled) {
- Console.log(Constants.Log.App.TaskDataLoader, "[RecentsTaskLoader|loadTask]",
- t + " applicationIcon: " + applicationIcon + " thumbnail: " + thumbnail +
- " thumbnailCacheSize: " + mThumbnailCache.size());
- }
-
boolean requiresLoad = false;
if (applicationIcon == null) {
applicationIcon = mDefaultApplicationIcon;
@@ -535,23 +434,12 @@
/** Releases the task resource data back into the pool. */
public void unloadTaskData(Task t) {
- if (Console.Enabled) {
- Console.log(Constants.Log.App.TaskDataLoader,
- "[RecentsTaskLoader|unloadTask]", t +
- " thumbnailCacheSize: " + mThumbnailCache.size());
- }
-
mLoadQueue.removeTask(t);
t.notifyTaskDataUnloaded(mDefaultThumbnail, mDefaultApplicationIcon);
}
/** Completely removes the resource data from the pool. */
public void deleteTaskData(Task t, boolean notifyTaskDataUnloaded) {
- if (Console.Enabled) {
- Console.log(Constants.Log.App.TaskDataLoader,
- "[RecentsTaskLoader|deleteTask]", t);
- }
-
mLoadQueue.removeTask(t);
mThumbnailCache.remove(t.key);
mApplicationIconCache.remove(t.key);
@@ -562,9 +450,6 @@
/** Stops the task loader and clears all pending tasks */
void stopLoader() {
- if (Console.Enabled) {
- Console.log(Constants.Log.App.TaskDataLoader, "[RecentsTaskLoader|stopLoader]");
- }
mLoader.stop();
mLoadQueue.clearTasks();
}
@@ -585,11 +470,6 @@
* out of memory.
*/
public void onTrimMemory(int level) {
- if (Console.Enabled) {
- Console.log(Constants.Log.App.Memory, "[RecentsTaskLoader|onTrimMemory]",
- Console.trimMemoryLevelToString(level));
- }
-
switch (level) {
case ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN:
// Stop the loader immediately when the UI is no longer visible
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/FullscreenTransitionOverlayView.java b/packages/SystemUI/src/com/android/systemui/recents/views/FullscreenTransitionOverlayView.java
index 57b8ea4..63f59be 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/FullscreenTransitionOverlayView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/FullscreenTransitionOverlayView.java
@@ -22,8 +22,6 @@
import android.animation.ObjectAnimator;
import android.content.Context;
import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
@@ -34,9 +32,7 @@
import android.widget.FrameLayout;
import android.widget.ImageView;
import com.android.systemui.R;
-import com.android.systemui.recents.Constants;
import com.android.systemui.recents.RecentsConfiguration;
-import com.android.systemui.recents.misc.Console;
/**
@@ -152,11 +148,6 @@
public void prepareAnimateOnEnterRecents(Bitmap screenshot) {
if (!mConfig.launchedFromAppWithScreenshot) return;
- if (Console.Enabled) {
- Console.logStartTracingTime(Constants.Log.App.TimeRecentsScreenshotTransition,
- Constants.Log.App.TimeRecentsScreenshotTransitionKey);
- }
-
setClipTop(0);
setClipBottom(getMeasuredHeight());
setDim(0);
@@ -180,11 +171,6 @@
/** Animates this view as it enters recents */
public void animateOnEnterRecents(ViewAnimation.TaskViewEnterContext ctx,
final Runnable postAnimRunnable) {
- if (Console.Enabled) {
- Console.logTraceTime(Constants.Log.App.TimeRecentsScreenshotTransition,
- Constants.Log.App.TimeRecentsScreenshotTransitionKey, "Starting");
- }
-
// Cancel the current animation
if (mEnterAnimation != null) {
mEnterAnimation.removeAllListeners();
@@ -226,11 +212,6 @@
mCb.onEnterAnimationComplete();
// Run the given post-anim runnable
postAnimRunnable.run();
-
- if (Console.Enabled) {
- Console.logTraceTime(Constants.Log.App.TimeRecentsScreenshotTransition,
- Constants.Log.App.TimeRecentsScreenshotTransitionKey, "Completed");
- }
}
});
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
index 73bbf86..7bb6144 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -141,20 +141,12 @@
TaskView tv = (TaskView) stackView.getChildAt(j);
Task task = tv.getTask();
if (tv.isFocusedTask()) {
- if (Console.Enabled) {
- Console.log(Constants.Log.UI.Focus, "[RecentsView|launchFocusedTask]",
- "Found focused Task");
- }
onTaskViewClicked(stackView, tv, stack, task, false);
return true;
}
}
}
}
- if (Console.Enabled) {
- Console.log(Constants.Log.UI.Focus, "[RecentsView|launchFocusedTask]",
- "No Tasks focused");
- }
return false;
}
@@ -228,12 +220,6 @@
if (searchBar != null) {
mSearchBar = searchBar;
addView(mSearchBar);
-
- if (Console.Enabled) {
- Console.log(Constants.Log.App.SystemUIHandshake, "[RecentsView|setSearchBar]",
- "" + (mSearchBar.getVisibility() == View.VISIBLE),
- Console.AnsiBlue);
- }
}
}
}
@@ -260,13 +246,6 @@
int height = MeasureSpec.getSize(heightMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
- if (Console.Enabled) {
- Console.log(Constants.Log.UI.MeasureAndLayout, "[RecentsView|measure]",
- "width: " + width + " height: " + height, Console.AnsiGreen);
- Console.logTraceTime(Constants.Log.App.TimeRecentsStartup,
- Constants.Log.App.TimeRecentsStartupKey, "RecentsView.onMeasure");
- }
-
// Get the search bar bounds and measure the search bar layout
if (mSearchBar != null) {
Rect searchBarSpaceBounds = new Rect();
@@ -303,13 +282,6 @@
*/
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
- if (Console.Enabled) {
- Console.log(Constants.Log.UI.MeasureAndLayout, "[RecentsView|layout]",
- new Rect(left, top, right, bottom) + " changed: " + changed, Console.AnsiGreen);
- Console.logTraceTime(Constants.Log.App.TimeRecentsStartup,
- Constants.Log.App.TimeRecentsStartupKey, "RecentsView.onLayout");
- }
-
// Get the search bar bounds so that we lay it out
if (mSearchBar != null) {
Rect searchBarSpaceBounds = new Rect();
@@ -351,11 +323,6 @@
@Override
public WindowInsets onApplyWindowInsets(WindowInsets insets) {
- if (Console.Enabled) {
- Console.log(Constants.Log.UI.MeasureAndLayout,
- "[RecentsView|fitSystemWindows]", "insets: " + insets, Console.AnsiGreen);
- }
-
// Update the configuration with the latest system insets and trigger a relayout
mConfig.updateSystemInsets(insets.getSystemWindowInsets());
requestLayout();
@@ -482,11 +449,6 @@
final Runnable launchRunnable = new Runnable() {
@Override
public void run() {
- if (Console.Enabled) {
- Console.logTraceTime(Constants.Log.App.TimeRecentsLaunchTask,
- Constants.Log.App.TimeRecentsLaunchKey, "preStartActivity");
- }
-
if (task.isActive) {
// Bring an active task to the foreground
RecentsTaskLoader.getInstance().getSystemServicesProxy()
@@ -515,19 +477,9 @@
// And clean up the old task
onTaskViewDismissed(task);
}
-
- if (Console.Enabled) {
- Console.logTraceTime(Constants.Log.App.TimeRecentsLaunchTask,
- Constants.Log.App.TimeRecentsLaunchKey, "startActivity");
- }
}
};
- if (Console.Enabled) {
- Console.logTraceTime(Constants.Log.App.TimeRecentsLaunchTask,
- Constants.Log.App.TimeRecentsLaunchKey, "onTaskLaunched");
- }
-
// Launch the app right away if there is no task view, otherwise, animate the icon out first
if (tv == null) {
post(launchRunnable);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/recents/views/SwipeHelper.java
index 8409227..e0298ab 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/SwipeHelper.java
@@ -28,8 +28,6 @@
import android.view.VelocityTracker;
import android.view.View;
import android.view.animation.LinearInterpolator;
-import com.android.systemui.recents.misc.Console;
-import com.android.systemui.recents.Constants;
/**
* This class facilitates swipe to dismiss. It defines an interface to be implemented by the
@@ -178,11 +176,6 @@
}
public boolean onInterceptTouchEvent(MotionEvent ev) {
- if (Console.Enabled) {
- Console.log(Constants.Log.UI.TouchEvents,
- "[SwipeHelper|interceptTouchEvent]",
- Console.motionEventActionToString(ev.getAction()), Console.AnsiBlue);
- }
final int action = ev.getAction();
switch (action) {
@@ -294,12 +287,6 @@
}
public boolean onTouchEvent(MotionEvent ev) {
- if (Console.Enabled) {
- Console.log(Constants.Log.UI.TouchEvents,
- "[SwipeHelper|touchEvent]",
- Console.motionEventActionToString(ev.getAction()), Console.AnsiBlue);
- }
-
if (!mDragging) {
if (!onInterceptTouchEvent(ev)) {
return mCanCurrViewBeDimissed;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
index adc808a..7b52163 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -167,10 +167,6 @@
requestSynchronizeStackViewsWithModel(0);
}
void requestSynchronizeStackViewsWithModel(int duration) {
- if (Console.Enabled) {
- Console.log(Constants.Log.TaskStack.SynchronizeViewsWithModel,
- "[TaskStackView|requestSynchronize]", "" + duration + "ms", Console.AnsiYellow);
- }
if (!mStackViewsDirty) {
invalidate(mStackAlgorithm.mStackRect);
}
@@ -266,11 +262,6 @@
if (visibleRangeOut != null) {
visibleRangeOut[0] = frontMostVisibleIndex;
visibleRangeOut[1] = backMostVisibleIndex;
- if (Console.Enabled) {
- Console.log(Constants.Log.TaskStack.SynchronizeViewsWithModel,
- "[TaskStackView|updateStackTransforms]",
- "Back: " + backMostVisibleIndex + " Front: " + frontMostVisibleIndex);
- }
}
}
@@ -290,11 +281,6 @@
/** Synchronizes the views with the model */
void synchronizeStackViewsWithModel() {
- if (Console.Enabled) {
- Console.log(Constants.Log.TaskStack.SynchronizeViewsWithModel,
- "[TaskStackView|synchronizeViewsWithModel]",
- "mStackViewsDirty: " + mStackViewsDirty, Console.AnsiYellow);
- }
if (mStackViewsDirty) {
// Get all the task transforms
ArrayList<Task> tasks = mStack.getTasks();
@@ -344,11 +330,6 @@
mStackViewsAnimationDuration);
}
- if (Console.Enabled) {
- Console.log(Constants.Log.TaskStack.SynchronizeViewsWithModel,
- " [TaskStackView|viewChildren]", "" + getChildCount());
- }
-
mStackViewsAnimationDuration = 0;
mStackViewsDirty = false;
}
@@ -537,11 +518,6 @@
mMaxScroll = mStackAlgorithm.mMaxScroll;
// Debug logging
- if (Constants.Log.UI.MeasureAndLayout) {
- Console.log(" [TaskStack|minScroll] " + mMinScroll);
- Console.log(" [TaskStack|maxScroll] " + mMaxScroll);
- }
-
if (boundScrollToNewMinMax) {
boundScroll();
}
@@ -563,9 +539,6 @@
/** Focuses the task at the specified index in the stack */
void focusTask(int taskIndex, boolean scrollToNewPosition) {
- if (Console.Enabled) {
- Console.log(Constants.Log.UI.Focus, "[TaskStackView|focusTask]", "" + taskIndex);
- }
if (0 <= taskIndex && taskIndex < mStack.getTaskCount()) {
mFocusedTaskIndex = taskIndex;
@@ -575,9 +548,6 @@
Runnable postScrollRunnable = null;
if (tv != null) {
tv.setFocusedTask();
- if (Console.Enabled) {
- Console.log(Constants.Log.UI.Focus, "[TaskStackView|focusTask]", "Requesting focus");
- }
} else {
postScrollRunnable = new Runnable() {
@Override
@@ -586,10 +556,6 @@
TaskView tv = getChildViewForTask(t);
if (tv != null) {
tv.setFocusedTask();
- if (Console.Enabled) {
- Console.log(Constants.Log.UI.Focus, "[TaskStackView|focusTask]",
- "Requesting focus after scroll animation");
- }
}
}
};
@@ -611,11 +577,6 @@
/** Focuses the next task in the stack */
void focusNextTask(boolean forward) {
- if (Console.Enabled) {
- Console.log(Constants.Log.UI.Focus, "[TaskStackView|focusNextTask]", "" +
- mFocusedTaskIndex);
- }
-
// Find the next index to focus
int numTasks = mStack.getTaskCount();
if (mFocusedTaskIndex < 0) {
@@ -630,24 +591,12 @@
/** Enables the hw layers and increments the hw layer requirement ref count */
void addHwLayersRefCount(String reason) {
- if (Console.Enabled) {
- int refCount = mHwLayersTrigger.getCount();
- Console.log(Constants.Log.UI.HwLayers,
- "[TaskStackView|addHwLayersRefCount] refCount: " +
- refCount + "->" + (refCount + 1) + " " + reason);
- }
mHwLayersTrigger.increment();
}
/** Decrements the hw layer requirement ref count and disables the hw layers when we don't
need them anymore. */
void decHwLayersRefCount(String reason) {
- if (Console.Enabled) {
- int refCount = mHwLayersTrigger.getCount();
- Console.log(Constants.Log.UI.HwLayers,
- "[TaskStackView|decHwLayersRefCount] refCount: " +
- refCount + "->" + (refCount - 1) + " " + reason);
- }
mHwLayersTrigger.decrement();
}
@@ -676,10 +625,6 @@
@Override
public void dispatchDraw(Canvas canvas) {
- if (Console.Enabled) {
- Console.log(Constants.Log.UI.Draw, "[TaskStackView|dispatchDraw]", "",
- Console.AnsiPurple);
- }
synchronizeStackViewsWithModel();
clipTaskViews();
super.dispatchDraw(canvas);
@@ -703,25 +648,12 @@
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
- if (Console.Enabled) {
- Console.log(Constants.Log.UI.MeasureAndLayout, "[TaskStackView|measure]",
- "width: " + width + " height: " + height +
- " awaitingFirstLayout: " + mAwaitingFirstLayout, Console.AnsiGreen);
- }
// Compute our stack/task rects
Rect taskStackBounds = new Rect();
mConfig.getTaskStackBounds(width, height, taskStackBounds);
computeRects(width, height, taskStackBounds.left, mConfig.systemInsets.bottom);
- // Debug logging
- if (Constants.Log.UI.MeasureAndLayout) {
- Console.log(" [TaskStack|fullRect] " + mStackAlgorithm.mRect);
- Console.log(" [TaskStack|stackRect] " + mStackAlgorithm.mStackRect);
- Console.log(" [TaskStack|stackRectSansPeek] " + mStackAlgorithm.mStackRectSansPeek);
- Console.log(" [TaskStack|taskRect] " + mStackAlgorithm.mTaskRect);
- }
-
// If this is the first layout, then scroll to the front of the stack and synchronize the
// stack views immediately
if (mAwaitingFirstLayout) {
@@ -749,19 +681,6 @@
*/
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
- if (Console.Enabled) {
- Console.log(Constants.Log.UI.MeasureAndLayout, "[TaskStackView|layout]",
- "" + new Rect(left, top, right, bottom), Console.AnsiGreen);
- }
-
- // Debug logging
- if (Constants.Log.UI.MeasureAndLayout) {
- Console.log(" [TaskStack|fullRect] " + mStackAlgorithm.mRect);
- Console.log(" [TaskStack|stackRect] " + mStackAlgorithm.mStackRect);
- Console.log(" [TaskStack|stackRectSansPeek] " + mStackAlgorithm.mStackRectSansPeek);
- Console.log(" [TaskStack|taskRect] " + mStackAlgorithm.mTaskRect);
- }
-
// Layout each of the children
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
@@ -1021,19 +940,12 @@
@Override
public TaskView createView(Context context) {
- if (Console.Enabled) {
- Console.log(Constants.Log.ViewPool.PoolCallbacks, "[TaskStackView|createPoolView]");
- }
return (TaskView) mInflater.inflate(R.layout.recents_task_view, this, false);
}
@Override
public void prepareViewToEnterPool(TaskView tv) {
Task task = tv.getTask();
- if (Console.Enabled) {
- Console.log(Constants.Log.ViewPool.PoolCallbacks, "[TaskStackView|returnToPool]",
- tv.getTask() + " tv: " + tv);
- }
// Report that this tasks's data is no longer being used
RecentsTaskLoader.getInstance().unloadTaskData(task);
@@ -1050,11 +962,6 @@
@Override
public void prepareViewToLeavePool(TaskView tv, Task task, boolean isNewView) {
- if (Console.Enabled) {
- Console.log(Constants.Log.ViewPool.PoolCallbacks, "[TaskStackView|leavePool]",
- "isNewView: " + isNewView);
- }
-
// Rebind the task and request that this task's data be filled into the TaskView
tv.onTaskBound(task);
RecentsTaskLoader.getInstance().loadTaskData(task);
@@ -1083,10 +990,6 @@
}
// Add/attach the view to the hierarchy
- if (Console.Enabled) {
- Console.log(Constants.Log.ViewPool.PoolCallbacks, " [TaskStackView|insertIndex]",
- "" + insertIndex);
- }
if (isNewView) {
addView(tv, insertIndex);
@@ -1112,11 +1015,6 @@
@Override
public void onTaskViewAppIconClicked(TaskView tv) {
- if (Console.Enabled) {
- Console.log(Constants.Log.UI.ClickEvents, "[TaskStack|Clicked|Icon]",
- tv.getTask() + " is currently filtered: " + mStack.hasFilteredTasks(),
- Console.AnsiCyan);
- }
if (Constants.DebugFlags.App.EnableTaskFiltering) {
if (mStack.hasFilteredTasks()) {
mStack.unfilterTasks();
@@ -1135,11 +1033,6 @@
@Override
public void onTaskViewClicked(TaskView tv, Task task, boolean lockToTask) {
- if (Console.Enabled) {
- Console.log(Constants.Log.UI.ClickEvents, "[TaskStack|Clicked|Thumbnail]",
- task + " cb: " + mCb);
- }
-
// Cancel any doze triggers
mUIDozeTrigger.stopDozing();
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
index 15ace13..bd4ea90 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
@@ -22,7 +22,6 @@
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewParent;
-import com.android.systemui.recents.misc.Console;
import com.android.systemui.recents.Constants;
/* Handles touch events for a TaskStackView. */
@@ -100,12 +99,6 @@
/** Touch preprocessing for handling below */
public boolean onInterceptTouchEvent(MotionEvent ev) {
- if (Console.Enabled) {
- Console.log(Constants.Log.UI.TouchEvents,
- "[TaskStackViewTouchHandler|interceptTouchEvent]",
- Console.motionEventActionToString(ev.getAction()), Console.AnsiBlue);
- }
-
// Return early if we have no children
boolean hasChildren = (mSv.getChildCount() > 0);
if (!hasChildren) {
@@ -186,12 +179,6 @@
/** Handles touch events once we have intercepted them */
public boolean onTouchEvent(MotionEvent ev) {
- if (Console.Enabled) {
- Console.log(Constants.Log.UI.TouchEvents,
- "[TaskStackViewTouchHandler|touchEvent]",
- Console.motionEventActionToString(ev.getAction()), Console.AnsiBlue);
- }
-
// Short circuit if we have no children
boolean hasChildren = (mSv.getChildCount() > 0);
if (!hasChildren) {
@@ -290,16 +277,6 @@
int overscrollRange = (int) (Math.min(1f,
Math.abs((float) velocity / mMaximumVelocity)) *
Constants.Values.TaskStackView.TaskStackOverscrollRange);
-
- if (Console.Enabled) {
- Console.log(Constants.Log.UI.TouchEvents,
- "[TaskStackViewTouchHandler|fling]",
- "scroll: " + mSv.getStackScroll() + " velocity: " + velocity +
- " maxVelocity: " + mMaximumVelocity +
- " overscrollRange: " + overscrollRange,
- Console.AnsiGreen);
- }
-
// Fling scroll
mSv.mScroller.fling(0, mSv.getStackScroll(),
0, -velocity,
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
index ab14863..7e30047 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -175,11 +175,6 @@
/** Synchronizes this view's properties with the task's transform */
void updateViewPropertiesToTaskTransform(TaskViewTransform toTransform, int duration) {
- if (Console.Enabled) {
- Console.log(Constants.Log.UI.Draw, "[TaskView|updateViewPropertiesToTaskTransform]",
- "duration: " + duration, Console.AnsiPurple);
- }
-
// Update the bar view
mBarView.updateViewPropertiesToTaskTransform(toTransform, duration);
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index adfa1f2..2e7d331 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -49,6 +49,9 @@
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.media.AudioManager;
+import android.media.session.MediaController;
+import android.media.session.MediaSession;
+import android.media.session.MediaSessionLegacyHelper;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
@@ -224,6 +227,7 @@
private boolean mClosingActionMenu;
private int mVolumeControlStreamType = AudioManager.USE_DEFAULT_STREAM_TYPE;
+ private MediaController mMediaController;
private AudioManager mAudioManager;
private KeyguardManager mKeyguardManager;
@@ -1688,15 +1692,42 @@
switch (keyCode) {
case KeyEvent.KEYCODE_VOLUME_UP:
- case KeyEvent.KEYCODE_VOLUME_DOWN:
+ case KeyEvent.KEYCODE_VOLUME_DOWN: {
+ int direction = keyCode == KeyEvent.KEYCODE_VOLUME_UP ? AudioManager.ADJUST_RAISE
+ : AudioManager.ADJUST_LOWER;
+ // If we have a session send it the volume command, otherwise
+ // use the suggested stream.
+ if (mMediaController != null) {
+ mMediaController.adjustVolumeBy(direction, AudioManager.FLAG_SHOW_UI);
+ } else {
+ MediaSessionLegacyHelper.getHelper(getContext()).sendAdjustVolumeBy(
+ mVolumeControlStreamType, direction, AudioManager.FLAG_SHOW_UI);
+ }
+ return true;
+ }
case KeyEvent.KEYCODE_VOLUME_MUTE: {
- // Similar code is in PhoneFallbackEventHandler in case the window
- // doesn't have one of these. In this case, we execute it here and
- // eat the event instead, because we have mVolumeControlStreamType
- // and they don't.
getAudioManager().handleKeyDown(event, mVolumeControlStreamType);
return true;
}
+ // These are all the recognized media key codes in
+ // KeyEvent.isMediaKey()
+ case KeyEvent.KEYCODE_MEDIA_PLAY:
+ case KeyEvent.KEYCODE_MEDIA_PAUSE:
+ case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
+ case KeyEvent.KEYCODE_MUTE:
+ case KeyEvent.KEYCODE_HEADSETHOOK:
+ case KeyEvent.KEYCODE_MEDIA_STOP:
+ case KeyEvent.KEYCODE_MEDIA_NEXT:
+ case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
+ case KeyEvent.KEYCODE_MEDIA_REWIND:
+ case KeyEvent.KEYCODE_MEDIA_RECORD:
+ case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD: {
+ if (mMediaController != null) {
+ if (mMediaController.dispatchMediaButtonEvent(event)) {
+ return true;
+ }
+ }
+ }
case KeyEvent.KEYCODE_MENU: {
onKeyDownPanel((featureId < 0) ? FEATURE_OPTIONS_PANEL : featureId, event);
@@ -1750,7 +1781,19 @@
switch (keyCode) {
case KeyEvent.KEYCODE_VOLUME_UP:
- case KeyEvent.KEYCODE_VOLUME_DOWN:
+ case KeyEvent.KEYCODE_VOLUME_DOWN: {
+ // If we have a session send it the volume command, otherwise
+ // use the suggested stream.
+ if (mMediaController != null) {
+ mMediaController.adjustVolumeBy(0, AudioManager.FLAG_PLAY_SOUND
+ | AudioManager.FLAG_VIBRATE);
+ } else {
+ MediaSessionLegacyHelper.getHelper(getContext()).sendAdjustVolumeBy(
+ mVolumeControlStreamType, 0,
+ AudioManager.FLAG_PLAY_SOUND | AudioManager.FLAG_VIBRATE);
+ }
+ return true;
+ }
case KeyEvent.KEYCODE_VOLUME_MUTE: {
// Similar code is in PhoneFallbackEventHandler in case the window
// doesn't have one of these. In this case, we execute it here and
@@ -1759,6 +1802,25 @@
getAudioManager().handleKeyUp(event, mVolumeControlStreamType);
return true;
}
+ // These are all the recognized media key codes in
+ // KeyEvent.isMediaKey()
+ case KeyEvent.KEYCODE_MEDIA_PLAY:
+ case KeyEvent.KEYCODE_MEDIA_PAUSE:
+ case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
+ case KeyEvent.KEYCODE_MUTE:
+ case KeyEvent.KEYCODE_HEADSETHOOK:
+ case KeyEvent.KEYCODE_MEDIA_STOP:
+ case KeyEvent.KEYCODE_MEDIA_NEXT:
+ case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
+ case KeyEvent.KEYCODE_MEDIA_REWIND:
+ case KeyEvent.KEYCODE_MEDIA_RECORD:
+ case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD: {
+ if (mMediaController != null) {
+ if (mMediaController.dispatchMediaButtonEvent(event)) {
+ return true;
+ }
+ }
+ }
case KeyEvent.KEYCODE_MENU: {
onKeyUpPanel(featureId < 0 ? FEATURE_OPTIONS_PANEL : featureId,
@@ -3773,6 +3835,16 @@
return mVolumeControlStreamType;
}
+ @Override
+ public void setMediaController(MediaController controller) {
+ mMediaController = controller;
+ }
+
+ @Override
+ public MediaController getMediaController() {
+ return mMediaController;
+ }
+
private boolean isTranslucent() {
TypedArray a = getWindowStyle();
return a.getBoolean(a.getResourceId(
diff --git a/services/core/java/com/android/server/location/GpsLocationProvider.java b/services/core/java/com/android/server/location/GpsLocationProvider.java
index 8222155..b3419c1 100644
--- a/services/core/java/com/android/server/location/GpsLocationProvider.java
+++ b/services/core/java/com/android/server/location/GpsLocationProvider.java
@@ -62,6 +62,7 @@
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
+import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.WorkSource;
import android.provider.Settings;
@@ -70,6 +71,7 @@
import android.telephony.SmsMessage;
import android.telephony.TelephonyManager;
import android.telephony.gsm.GsmCellLocation;
+import android.text.TextUtils;
import android.util.Log;
import android.util.NtpTrustedTime;
@@ -85,6 +87,8 @@
import java.util.Map.Entry;
import java.util.Properties;
+import libcore.io.IoUtils;
+
/**
* A GPS implementation of LocationProvider used by LocationManager.
*
@@ -201,7 +205,9 @@
private static final int AGPS_SETID_TYPE_IMSI = 1;
private static final int AGPS_SETID_TYPE_MSISDN = 2;
- private static final String PROPERTIES_FILE = "/etc/gps.conf";
+ private static final String PROPERTIES_FILE_PREFIX = "/etc/gps";
+ private static final String PROPERTIES_FILE_SUFFIX = ".conf";
+ private static final String DEFAULT_PROPERTIES_FILE = PROPERTIES_FILE_PREFIX + PROPERTIES_FILE_SUFFIX;
private static final int GPS_GEOFENCE_UNAVAILABLE = 1<<0L;
private static final int GPS_GEOFENCE_AVAILABLE = 1<<1L;
@@ -441,6 +447,44 @@
return native_is_supported();
}
+ private boolean loadPropertiesFile(String filename) {
+ mProperties = new Properties();
+ try {
+ File file = new File(filename);
+ FileInputStream stream = null;
+ try {
+ stream = new FileInputStream(file);
+ mProperties.load(stream);
+ } finally {
+ IoUtils.closeQuietly(stream);
+ }
+
+ mSuplServerHost = mProperties.getProperty("SUPL_HOST");
+ String portString = mProperties.getProperty("SUPL_PORT");
+ if (mSuplServerHost != null && portString != null) {
+ try {
+ mSuplServerPort = Integer.parseInt(portString);
+ } catch (NumberFormatException e) {
+ Log.e(TAG, "unable to parse SUPL_PORT: " + portString);
+ }
+ }
+
+ mC2KServerHost = mProperties.getProperty("C2K_HOST");
+ portString = mProperties.getProperty("C2K_PORT");
+ if (mC2KServerHost != null && portString != null) {
+ try {
+ mC2KServerPort = Integer.parseInt(portString);
+ } catch (NumberFormatException e) {
+ Log.e(TAG, "unable to parse C2K_PORT: " + portString);
+ }
+ }
+ } catch (IOException e) {
+ Log.w(TAG, "Could not open GPS configuration file " + filename);
+ return false;
+ }
+ return true;
+ }
+
public GpsLocationProvider(Context context, ILocationManager ilocationManager,
Looper looper) {
mContext = context;
@@ -469,34 +513,15 @@
mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService(
BatteryStats.SERVICE_NAME));
- mProperties = new Properties();
- try {
- File file = new File(PROPERTIES_FILE);
- FileInputStream stream = new FileInputStream(file);
- mProperties.load(stream);
- stream.close();
+ boolean propertiesLoaded = false;
+ final String gpsHardware = SystemProperties.get("ro.hardware.gps");
+ if (!TextUtils.isEmpty(gpsHardware)) {
+ final String propFilename = PROPERTIES_FILE_PREFIX + "." + gpsHardware + PROPERTIES_FILE_SUFFIX;
+ propertiesLoaded = loadPropertiesFile(propFilename);
+ }
- mSuplServerHost = mProperties.getProperty("SUPL_HOST");
- String portString = mProperties.getProperty("SUPL_PORT");
- if (mSuplServerHost != null && portString != null) {
- try {
- mSuplServerPort = Integer.parseInt(portString);
- } catch (NumberFormatException e) {
- Log.e(TAG, "unable to parse SUPL_PORT: " + portString);
- }
- }
-
- mC2KServerHost = mProperties.getProperty("C2K_HOST");
- portString = mProperties.getProperty("C2K_PORT");
- if (mC2KServerHost != null && portString != null) {
- try {
- mC2KServerPort = Integer.parseInt(portString);
- } catch (NumberFormatException e) {
- Log.e(TAG, "unable to parse C2K_PORT: " + portString);
- }
- }
- } catch (IOException e) {
- Log.w(TAG, "Could not open GPS configuration file " + PROPERTIES_FILE);
+ if (!propertiesLoaded) {
+ loadPropertiesFile(DEFAULT_PROPERTIES_FILE);
}
// construct handler, listen for events
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index 341c7a9..01a21f4 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -505,16 +505,19 @@
|| state.getState() == PlaybackState.STATE_FAST_FORWARDING
|| state.getState() == PlaybackState.STATE_REWINDING) {
long updateTime = state.getLastPositionUpdateTime();
+ long currentTime = SystemClock.elapsedRealtime();
if (updateTime > 0) {
- long position = (long) (state.getPlaybackRate()
- * (SystemClock.elapsedRealtime() - updateTime)) + state.getPosition();
+ long position = (long) (state.getPlaybackSpeed()
+ * (currentTime - updateTime)) + state.getPosition();
if (duration >= 0 && position > duration) {
position = duration;
} else if (position < 0) {
position = 0;
}
- result = new PlaybackState(state);
- result.setState(state.getState(), position, state.getPlaybackRate());
+ PlaybackState.Builder builder = new PlaybackState.Builder(state);
+ builder.setState(state.getState(), position, state.getPlaybackSpeed(),
+ currentTime);
+ result = builder.build();
}
}
}
diff --git a/services/core/java/com/android/server/pm/KeySetHandle.java b/services/core/java/com/android/server/pm/KeySetHandle.java
new file mode 100644
index 0000000..640feb3
--- /dev/null
+++ b/services/core/java/com/android/server/pm/KeySetHandle.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2014 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.server.pm;
+
+import android.os.Binder;
+
+public class KeySetHandle extends Binder {
+}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/pm/KeySetManagerService.java b/services/core/java/com/android/server/pm/KeySetManagerService.java
index c19951f..37bedf3 100644
--- a/services/core/java/com/android/server/pm/KeySetManagerService.java
+++ b/services/core/java/com/android/server/pm/KeySetManagerService.java
@@ -16,7 +16,6 @@
package com.android.server.pm;
-import android.content.pm.KeySet;
import android.content.pm.PackageParser;
import android.os.Binder;
import android.util.ArraySet;
@@ -52,7 +51,7 @@
/** Sentinel value returned when public key is not found. */
protected static final long PUBLIC_KEY_NOT_FOUND = -1;
- private final LongSparseArray<KeySet> mKeySets;
+ private final LongSparseArray<KeySetHandle> mKeySets;
private final LongSparseArray<PublicKey> mPublicKeys;
@@ -65,7 +64,7 @@
private static long lastIssuedKeyId = 0;
public KeySetManagerService(Map<String, PackageSetting> packages) {
- mKeySets = new LongSparseArray<KeySet>();
+ mKeySets = new LongSparseArray<KeySetHandle>();
mPublicKeys = new LongSparseArray<PublicKey>();
mKeySetMapping = new LongSparseArray<ArraySet<Long>>();
mPackages = packages;
@@ -82,7 +81,7 @@
*
* Note that this can return true for multiple KeySets.
*/
- public boolean packageIsSignedByLPr(String packageName, KeySet ks) {
+ public boolean packageIsSignedByLPr(String packageName, KeySetHandle ks) {
PackageSetting pkg = mPackages.get(packageName);
if (pkg == null) {
throw new NullPointerException("Invalid package name");
@@ -91,16 +90,42 @@
throw new NullPointerException("Package has no KeySet data");
}
long id = getIdByKeySetLPr(ks);
+ if (id == KEYSET_NOT_FOUND) {
+ return false;
+ }
return pkg.keySetData.packageIsSignedBy(id);
}
/**
+ * Determine if a package is signed by the given KeySet.
+ *
+ * Returns false if the package was not signed by all the
+ * keys in the KeySet, or if the package was signed by keys
+ * not in the KeySet.
+ *
+ * Note that this can return only for one KeySet.
+ */
+ public boolean packageIsSignedByExactlyLPr(String packageName, KeySetHandle ks) {
+ PackageSetting pkg = mPackages.get(packageName);
+ if (pkg == null) {
+ throw new NullPointerException("Invalid package name");
+ }
+ if (pkg.keySetData == null
+ || pkg.keySetData.getProperSigningKeySet()
+ == PackageKeySetData.KEYSET_UNASSIGNED) {
+ throw new NullPointerException("Package has no KeySet data");
+ }
+ long id = getIdByKeySetLPr(ks);
+ return pkg.keySetData.getProperSigningKeySet() == id;
+ }
+
+ /**
* This informs the system that the given package has defined a KeySet
* in its manifest that a) contains the given keys and b) is named
* alias by that package.
*/
public void addDefinedKeySetToPackageLPw(String packageName,
- Set<PublicKey> keys, String alias) {
+ ArraySet<PublicKey> keys, String alias) {
if ((packageName == null) || (keys == null) || (alias == null)) {
Slog.w(TAG, "Got null argument for a defined keyset, ignoring!");
return;
@@ -110,7 +135,7 @@
throw new NullPointerException("Unknown package");
}
// Add to KeySets, then to package
- KeySet ks = addKeySetLPw(keys);
+ KeySetHandle ks = addKeySetLPw(keys);
long id = getIdByKeySetLPr(ks);
pkg.keySetData.addDefinedKeySet(id, alias);
}
@@ -137,19 +162,18 @@
* was signed by the provided KeySet.
*/
public void addSigningKeySetToPackageLPw(String packageName,
- Set<PublicKey> signingKeys) {
+ ArraySet<PublicKey> signingKeys) {
if ((packageName == null) || (signingKeys == null)) {
Slog.w(TAG, "Got null argument for a signing keyset, ignoring!");
return;
}
// add the signing KeySet
- KeySet ks = addKeySetLPw(signingKeys);
+ KeySetHandle ks = addKeySetLPw(signingKeys);
long id = getIdByKeySetLPr(ks);
- Set<Long> publicKeyIds = mKeySetMapping.get(id);
+ ArraySet<Long> publicKeyIds = mKeySetMapping.get(id);
if (publicKeyIds == null) {
throw new NullPointerException("Got invalid KeySet id");
}
-
// attach it to the package
PackageSetting pkg = mPackages.get(packageName);
if (pkg == null) {
@@ -160,7 +184,7 @@
// KeySet id to the package's signing KeySets
for (int keySetIndex = 0; keySetIndex < mKeySets.size(); keySetIndex++) {
long keySetID = mKeySets.keyAt(keySetIndex);
- Set<Long> definedKeys = mKeySetMapping.get(keySetID);
+ ArraySet<Long> definedKeys = mKeySetMapping.get(keySetID);
if (publicKeyIds.containsAll(definedKeys)) {
pkg.keySetData.addSigningKeySet(keySetID);
}
@@ -171,9 +195,9 @@
* Fetches the stable identifier associated with the given KeySet. Returns
* {@link #KEYSET_NOT_FOUND} if the KeySet... wasn't found.
*/
- private long getIdByKeySetLPr(KeySet ks) {
+ private long getIdByKeySetLPr(KeySetHandle ks) {
for (int keySetIndex = 0; keySetIndex < mKeySets.size(); keySetIndex++) {
- KeySet value = mKeySets.valueAt(keySetIndex);
+ KeySetHandle value = mKeySets.valueAt(keySetIndex);
if (ks.equals(value)) {
return mKeySets.keyAt(keySetIndex);
}
@@ -187,25 +211,24 @@
* Returns {@link #KEYSET_NOT_FOUND} if the identifier doesn't
* identify a {@link KeySet}.
*/
- public KeySet getKeySetByIdLPr(long id) {
+ public KeySetHandle getKeySetByIdLPr(long id) {
return mKeySets.get(id);
}
/**
- * Fetches the {@link KeySet} that a given package refers to by the provided alias.
- *
- * @throws IllegalArgumentException if the package has no keyset data.
- * @throws NullPointerException if the package is unknown.
+ * Fetches the {@link KeySetHandle} that a given package refers to by the
+ * provided alias. Returns null if the package is unknown or does not have a
+ * KeySet corresponding to that alias.
*/
- public KeySet getKeySetByAliasAndPackageNameLPr(String packageName, String alias) {
+ public KeySetHandle getKeySetByAliasAndPackageNameLPr(String packageName, String alias) {
PackageSetting p = mPackages.get(packageName);
- if (p == null) {
- throw new NullPointerException("Unknown package");
+ if (p == null || p.keySetData == null) {
+ return null;
}
- if (p.keySetData == null) {
- throw new IllegalArgumentException("Package has no keySet data");
+ Long keySetId = p.keySetData.getAliases().get(alias);
+ if (keySetId == null) {
+ throw new IllegalArgumentException("Unknown KeySet alias: " + alias);
}
- long keySetId = p.keySetData.getAliases().get(alias);
return mKeySets.get(keySetId);
}
@@ -214,7 +237,7 @@
* KeySet id.
*
* Returns {@code null} if the identifier doesn't
- * identify a {@link KeySet}.
+ * identify a {@link KeySetHandle}.
*/
public ArraySet<PublicKey> getPublicKeysFromKeySetLPr(long id) {
if(mKeySetMapping.get(id) == null) {
@@ -228,36 +251,32 @@
}
/**
- * Fetches all the known {@link KeySet KeySets} that signed the given
+ * Fetches the proper {@link KeySetHandle KeySet} that signed the given
* package.
*
* @throws IllegalArgumentException if the package has no keyset data.
* @throws NullPointerException if the package is unknown.
*/
- public Set<KeySet> getSigningKeySetsByPackageNameLPr(String packageName) {
- Set<KeySet> signingKeySets = new ArraySet<KeySet>();
+ public KeySetHandle getSigningKeySetByPackageNameLPr(String packageName) {
PackageSetting p = mPackages.get(packageName);
- if (p == null) {
- throw new NullPointerException("Unknown package");
+ if (p == null
+ || p.keySetData == null
+ || p.keySetData.getProperSigningKeySet()
+ == PackageKeySetData.KEYSET_UNASSIGNED) {
+ return null;
}
- if (p.keySetData == null || p.keySetData.getSigningKeySets() == null) {
- throw new IllegalArgumentException("Package has no keySet data");
- }
- for (long l : p.keySetData.getSigningKeySets()) {
- signingKeySets.add(mKeySets.get(l));
- }
- return signingKeySets;
+ return mKeySets.get(p.keySetData.getProperSigningKeySet());
}
/**
- * Fetches all the known {@link KeySet KeySets} that may upgrade the given
+ * Fetches all the known {@link KeySetHandle KeySets} that may upgrade the given
* package.
*
* @throws IllegalArgumentException if the package has no keyset data.
* @throws NullPointerException if the package is unknown.
*/
- public ArraySet<KeySet> getUpgradeKeySetsByPackageNameLPr(String packageName) {
- ArraySet<KeySet> upgradeKeySets = new ArraySet<KeySet>();
+ public ArraySet<KeySetHandle> getUpgradeKeySetsByPackageNameLPr(String packageName) {
+ ArraySet<KeySetHandle> upgradeKeySets = new ArraySet<KeySetHandle>();
PackageSetting p = mPackages.get(packageName);
if (p == null) {
throw new NullPointerException("Unknown package");
@@ -287,7 +306,7 @@
*
* Throws if the provided set is {@code null}.
*/
- private KeySet addKeySetLPw(Set<PublicKey> keys) {
+ private KeySetHandle addKeySetLPw(ArraySet<PublicKey> keys) {
if (keys == null) {
throw new NullPointerException("Provided keys cannot be null");
}
@@ -305,7 +324,7 @@
}
// create the KeySet object
- KeySet ks = new KeySet(new Binder());
+ KeySetHandle ks = new KeySetHandle();
// get the first unoccupied slot in mKeySets
long id = getFreeKeySetIDLPw();
// add the KeySet object to it
@@ -318,7 +337,7 @@
if (p.keySetData != null) {
long pProperSigning = p.keySetData.getProperSigningKeySet();
if (pProperSigning != PackageKeySetData.KEYSET_UNASSIGNED) {
- Set<Long> pSigningKeys = mKeySetMapping.get(pProperSigning);
+ ArraySet<Long> pSigningKeys = mKeySetMapping.get(pProperSigning);
if (pSigningKeys.containsAll(addedKeyIds)) {
p.keySetData.addSigningKeySet(id);
}
@@ -353,7 +372,7 @@
*/
private long getIdFromKeyIdsLPr(Set<Long> publicKeyIds) {
for (int keyMapIndex = 0; keyMapIndex < mKeySetMapping.size(); keyMapIndex++) {
- Set<Long> value = mKeySetMapping.valueAt(keyMapIndex);
+ ArraySet<Long> value = mKeySetMapping.valueAt(keyMapIndex);
if (value.equals(publicKeyIds)) {
return mKeySetMapping.keyAt(keyMapIndex);
}
@@ -582,7 +601,7 @@
serializer.startTag(null, "keysets");
for (int keySetIndex = 0; keySetIndex < mKeySetMapping.size(); keySetIndex++) {
long id = mKeySetMapping.keyAt(keySetIndex);
- Set<Long> keys = mKeySetMapping.valueAt(keySetIndex);
+ ArraySet<Long> keys = mKeySetMapping.valueAt(keySetIndex);
serializer.startTag(null, "keyset");
serializer.attribute(null, "identifier", Long.toString(id));
for (long keyId : keys) {
@@ -662,7 +681,7 @@
final String tagName = parser.getName();
if (tagName.equals("keyset")) {
currentKeySetId = readIdentifierLPw(parser);
- mKeySets.put(currentKeySetId, new KeySet(new Binder()));
+ mKeySets.put(currentKeySetId, new KeySetHandle());
mKeySetMapping.put(currentKeySetId, new ArraySet<Long>());
} else if (tagName.equals("key-id")) {
long id = readIdentifierLPw(parser);
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index c399fa2..41ab66a 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -177,7 +177,8 @@
@Override
public void setClientProgress(int progress) {
mClientProgress = progress;
- mProgress = MathUtils.constrain((mClientProgress * 8 * 100) / (params.progressMax * 10), 0, 80);
+ mProgress = MathUtils.constrain(
+ (int) (((float) mClientProgress) / ((float) params.progressMax)) * 80, 0, 80);
mCallback.onSessionProgress(this, mProgress);
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 101ef92..cfba19c 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -9331,14 +9331,18 @@
return false;
} else {
final File beforeCodeFile = codeFile;
- final File afterCodeFile = new File(mAppInstallDir,
- getNextCodePath(oldCodePath, pkg.packageName, null));
+ final File afterCodeFile = getNextCodePath(pkg.packageName);
Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
- if (!beforeCodeFile.renameTo(afterCodeFile)) {
+ try {
+ Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
+ } catch (ErrnoException e) {
+ Slog.d(TAG, "Failed to rename", e);
return false;
}
+
if (!SELinux.restoreconRecursive(afterCodeFile)) {
+ Slog.d(TAG, "Failed to restorecon");
return false;
}
@@ -9811,6 +9815,16 @@
return prefix + idxStr;
}
+ private File getNextCodePath(String packageName) {
+ int suffix = 1;
+ File result;
+ do {
+ result = new File(mAppInstallDir, packageName + "-" + suffix);
+ suffix++;
+ } while (result.exists());
+ return result;
+ }
+
// Utility method used to ignore ADD/REMOVE events
// by directory observer.
private static boolean ignoreCodePath(String fullPathStr) {
@@ -13255,4 +13269,83 @@
}
return mUserNeedsBadging.valueAt(index);
}
+
+ @Override
+ public KeySetHandle getKeySetByAlias(String packageName, String alias) {
+ if (packageName == null || alias == null) {
+ return null;
+ }
+ synchronized(mPackages) {
+ final PackageParser.Package pkg = mPackages.get(packageName);
+ if (pkg == null) {
+ Slog.w(TAG, "KeySet requested for unknown package:" + packageName);
+ throw new IllegalArgumentException("Unknown package: " + packageName);
+ }
+ if (pkg.applicationInfo.uid != Binder.getCallingUid()
+ && Process.SYSTEM_UID != Binder.getCallingUid()) {
+ throw new SecurityException("May not access KeySets defined by"
+ + " aliases in other applications.");
+ }
+ KeySetManagerService ksms = mSettings.mKeySetManagerService;
+ return ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias);
+ }
+ }
+
+ @Override
+ public KeySetHandle getSigningKeySet(String packageName) {
+ if (packageName == null) {
+ return null;
+ }
+ synchronized(mPackages) {
+ final PackageParser.Package pkg = mPackages.get(packageName);
+ if (pkg == null) {
+ Slog.w(TAG, "KeySet requested for unknown package:" + packageName);
+ throw new IllegalArgumentException("Unknown package: " + packageName);
+ }
+ if (pkg.applicationInfo.uid != Binder.getCallingUid()
+ && Process.SYSTEM_UID != Binder.getCallingUid()) {
+ throw new SecurityException("May not access signing KeySet of other apps.");
+ }
+ KeySetManagerService ksms = mSettings.mKeySetManagerService;
+ return ksms.getSigningKeySetByPackageNameLPr(packageName);
+ }
+ }
+
+ @Override
+ public boolean isPackageSignedByKeySet(String packageName, IBinder ks) {
+ if (packageName == null || ks == null) {
+ return false;
+ }
+ synchronized(mPackages) {
+ final PackageParser.Package pkg = mPackages.get(packageName);
+ if (pkg == null) {
+ Slog.w(TAG, "KeySet requested for unknown package:" + packageName);
+ throw new IllegalArgumentException("Unknown package: " + packageName);
+ }
+ if (ks instanceof KeySetHandle) {
+ KeySetManagerService ksms = mSettings.mKeySetManagerService;
+ return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ks);
+ }
+ return false;
+ }
+ }
+
+ @Override
+ public boolean isPackageSignedByKeySetExactly(String packageName, IBinder ks) {
+ if (packageName == null || ks == null) {
+ return false;
+ }
+ synchronized(mPackages) {
+ final PackageParser.Package pkg = mPackages.get(packageName);
+ if (pkg == null) {
+ Slog.w(TAG, "KeySet requested for unknown package:" + packageName);
+ throw new IllegalArgumentException("Unknown package: " + packageName);
+ }
+ if (ks instanceof KeySetHandle) {
+ KeySetManagerService ksms = mSettings.mKeySetManagerService;
+ return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ks);
+ }
+ return false;
+ }
+ }
}
diff --git a/telecomm/java/android/telecomm/TelecommConstants.java b/telecomm/java/android/telecomm/TelecommConstants.java
index b9fb40c..b21ea60 100644
--- a/telecomm/java/android/telecomm/TelecommConstants.java
+++ b/telecomm/java/android/telecomm/TelecommConstants.java
@@ -51,6 +51,12 @@
public static final String ACTION_CONNECTION_SERVICE = ConnectionService.class.getName();
/**
+ * The {@link Intent} action used to configure a {@link ConnectionService}.
+ */
+ public static final String ACTION_CONNECTION_SERVICE_CONFIGURE =
+ "android.intent.action.CONNECTION_SERVICE_CONFIGURE";
+
+ /**
* Optional extra for {@link Intent#ACTION_CALL} containing a boolean that determines whether
* the speakerphone should be automatically turned on for an outgoing call.
*/
diff --git a/test-runner/src/android/test/mock/MockPackageManager.java b/test-runner/src/android/test/mock/MockPackageManager.java
index a14714a..648c418 100644
--- a/test-runner/src/android/test/mock/MockPackageManager.java
+++ b/test-runner/src/android/test/mock/MockPackageManager.java
@@ -31,6 +31,7 @@
import android.content.pm.IPackageMoveObserver;
import android.content.pm.IPackageStatsObserver;
import android.content.pm.InstrumentationInfo;
+import android.content.pm.KeySet;
import android.content.pm.ManifestDigest;
import android.content.pm.PackageInfo;
import android.content.pm.PackageInstaller;
@@ -616,6 +617,26 @@
throw new UnsupportedOperationException();
}
+ @Override
+ public KeySet getKeySetByAlias(String packageName, String alias) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public KeySet getSigningKeySet(String packageName) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isSignedBy(String packageName, KeySet ks) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isSignedByExactly(String packageName, KeySet ks) {
+ throw new UnsupportedOperationException();
+ }
+
/**
* @hide
*/
diff --git a/tests/OneMedia/src/com/android/onemedia/PlayerController.java b/tests/OneMedia/src/com/android/onemedia/PlayerController.java
index 802f473..9cbb455 100644
--- a/tests/OneMedia/src/com/android/onemedia/PlayerController.java
+++ b/tests/OneMedia/src/com/android/onemedia/PlayerController.java
@@ -18,12 +18,14 @@
import android.media.MediaMetadata;
import android.media.session.MediaController;
+import android.media.session.MediaSession;
import android.media.session.MediaSessionManager;
import android.media.session.PlaybackState;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
+import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -43,7 +45,7 @@
protected MediaController.TransportControls mTransportControls;
private final Intent mServiceIntent;
- private Context mContext;
+ private Activity mContext;
private Listener mListener;
private SessionCallback mControllerCb;
private MediaSessionManager mManager;
@@ -51,7 +53,7 @@
private boolean mResumed;
- public PlayerController(Context context, Intent serviceIntent) {
+ public PlayerController(Activity context, Intent serviceIntent) {
mContext = context;
if (serviceIntent == null) {
mServiceIntent = new Intent(mContext, PlayerService.class);
@@ -140,6 +142,7 @@
mBinder = null;
mController = null;
mTransportControls = null;
+ mContext.setMediaController(null);
Log.d(TAG, "Disconnected from PlayerService");
if (mListener != null) {
@@ -151,12 +154,15 @@
public void onServiceConnected(ComponentName name, IBinder service) {
mBinder = IPlayerService.Stub.asInterface(service);
Log.d(TAG, "service is " + service + " binder is " + mBinder);
+ MediaSession.Token token;
try {
- mController = MediaController.fromToken(mBinder.getSessionToken());
+ token = mBinder.getSessionToken();
} catch (RemoteException e) {
Log.e(TAG, "Error getting session", e);
return;
}
+ mController = MediaController.fromToken(token);
+ mContext.setMediaController(mController);
mController.addCallback(mControllerCb, mHandler);
mTransportControls = mController.getTransportControls();
Log.d(TAG, "Ready to use PlayerService");
diff --git a/tests/OneMedia/src/com/android/onemedia/PlayerSession.java b/tests/OneMedia/src/com/android/onemedia/PlayerSession.java
index 7c0eabe..78353b2 100644
--- a/tests/OneMedia/src/com/android/onemedia/PlayerSession.java
+++ b/tests/OneMedia/src/com/android/onemedia/PlayerSession.java
@@ -28,6 +28,7 @@
import android.os.Bundle;
import android.support.media.protocols.MediaPlayerProtocol;
import android.support.media.protocols.MediaPlayerProtocol.MediaStatus;
+import android.os.SystemClock;
import android.util.Log;
import android.view.KeyEvent;
@@ -59,9 +60,9 @@
mRenderer = new LocalRenderer(context, null);
mCallback = new SessionCb();
mRenderListener = new RenderListener();
- mPlaybackState = new PlaybackState();
- mPlaybackState.setActions(PlaybackState.ACTION_PAUSE
- | PlaybackState.ACTION_PLAY);
+ PlaybackState.Builder psBob = new PlaybackState.Builder();
+ psBob.setActions(PlaybackState.ACTION_PAUSE | PlaybackState.ACTION_PLAY);
+ mPlaybackState = psBob.build();
mRenderer.registerListener(mRenderListener);
}
@@ -131,7 +132,10 @@
private void updateState(int newState) {
float rate = newState == PlaybackState.STATE_PLAYING ? 1 : 0;
long position = mRenderer == null ? -1 : mRenderer.getSeekPosition();
- mPlaybackState.setState(newState, position, rate);
+ PlaybackState.Builder bob = new PlaybackState.Builder(mPlaybackState);
+ bob.setState(newState, position, rate, SystemClock.elapsedRealtime());
+ bob.setErrorMessage(null);
+ mPlaybackState = bob.build();
mSession.setPlaybackState(mPlaybackState);
}
@@ -144,10 +148,12 @@
@Override
public void onError(int type, int extra, Bundle extras, Throwable error) {
Log.d(TAG, "Sending onError with type " + type + " and extra " + extra);
- mPlaybackState.setState(PlaybackState.STATE_ERROR, -1, 0);
+ PlaybackState.Builder bob = new PlaybackState.Builder(mPlaybackState);
+ bob.setState(PlaybackState.STATE_ERROR, -1, 0, 0);
if (error != null) {
- mPlaybackState.setErrorMessage(error.getLocalizedMessage());
+ bob.setErrorMessage(error.getLocalizedMessage());
}
+ mPlaybackState = bob.build();
mSession.setPlaybackState(mPlaybackState);
if (mListener != null) {
mListener.onPlayStateChanged(mPlaybackState);
@@ -156,36 +162,41 @@
@Override
public void onStateChanged(int newState) {
- if (newState != Renderer.STATE_ERROR) {
- mPlaybackState.setErrorMessage(null);
- }
long position = -1;
if (mRenderer != null) {
position = mRenderer.getSeekPosition();
}
+ int pbState;
+ float rate = 0;
+ String errorMsg = null;
switch (newState) {
case Renderer.STATE_ENDED:
case Renderer.STATE_STOPPED:
- mPlaybackState.setState(PlaybackState.STATE_STOPPED, position, 0);
+ pbState = PlaybackState.STATE_STOPPED;
break;
case Renderer.STATE_INIT:
case Renderer.STATE_PREPARING:
- mPlaybackState.setState(PlaybackState.STATE_BUFFERING, position, 0);
+ pbState = PlaybackState.STATE_BUFFERING;
break;
case Renderer.STATE_ERROR:
- mPlaybackState.setState(PlaybackState.STATE_ERROR, position, 0);
+ pbState = PlaybackState.STATE_ERROR;
break;
case Renderer.STATE_PAUSED:
- mPlaybackState.setState(PlaybackState.STATE_PAUSED, position, 0);
+ pbState = PlaybackState.STATE_PAUSED;
break;
case Renderer.STATE_PLAYING:
- mPlaybackState.setState(PlaybackState.STATE_PLAYING, position, 1);
+ pbState = PlaybackState.STATE_PLAYING;
+ rate = 1;
break;
default:
- mPlaybackState.setState(PlaybackState.STATE_ERROR, position, 0);
- mPlaybackState.setErrorMessage("unkown state");
+ pbState = PlaybackState.STATE_ERROR;
+ errorMsg = "unknown state";
break;
}
+ PlaybackState.Builder bob = new PlaybackState.Builder(mPlaybackState);
+ bob.setState(pbState, position, rate, SystemClock.elapsedRealtime());
+ bob.setErrorMessage(errorMsg);
+ mPlaybackState = bob.build();
mSession.setPlaybackState(mPlaybackState);
if (mListener != null) {
mListener.onPlayStateChanged(mPlaybackState);
@@ -200,7 +211,10 @@
public void onFocusLost() {
Log.d(TAG, "Focus lost, changing state to " + Renderer.STATE_PAUSED);
long position = mRenderer == null ? -1 : mRenderer.getSeekPosition();
- mPlaybackState.setState(PlaybackState.STATE_PAUSED, position, 0);
+ PlaybackState.Builder bob = new PlaybackState.Builder(mPlaybackState);
+ bob.setState(PlaybackState.STATE_PAUSED, position, 0, SystemClock.elapsedRealtime());
+ bob.setErrorMessage(null);
+ mPlaybackState = bob.build();
mSession.setPlaybackState(mPlaybackState);
if (mListener != null) {
mListener.onPlayStateChanged(mPlaybackState);
diff --git a/tests/OneMedia/src/com/android/onemedia/provider/OneMediaRouteProvider.java b/tests/OneMedia/src/com/android/onemedia/provider/OneMediaRouteProvider.java
index 2e1478b..5845e48 100644
--- a/tests/OneMedia/src/com/android/onemedia/provider/OneMediaRouteProvider.java
+++ b/tests/OneMedia/src/com/android/onemedia/provider/OneMediaRouteProvider.java
@@ -29,6 +29,9 @@
import android.support.media.protocols.MediaPlayerProtocol;
import android.support.media.protocols.MediaPlayerProtocol.MediaInfo;
import android.support.media.protocols.MediaPlayerProtocol.MediaStatus;
+import android.os.Looper;
+import android.os.ResultReceiver;
+import android.os.SystemClock;
import android.util.Log;
import com.android.onemedia.playback.LocalRenderer;
@@ -60,9 +63,9 @@
mHandler = new Handler();
mRenderer = new LocalRenderer(this, null);
mRenderListener = new RenderListener();
- mPlaybackState = new PlaybackState();
- mPlaybackState.setActions(PlaybackState.ACTION_PAUSE
- | PlaybackState.ACTION_PLAY);
+ PlaybackState.Builder bob = new PlaybackState.Builder();
+ bob.setActions(PlaybackState.ACTION_PAUSE | PlaybackState.ACTION_PLAY);
+ mPlaybackState = bob.build();
mRenderer.registerListener(mRenderListener);
}
@@ -178,36 +181,41 @@
@Override
public void onStateChanged(int newState) {
- if (newState != Renderer.STATE_ERROR) {
- mPlaybackState.setErrorMessage(null);
- }
long position = -1;
if (mRenderer != null) {
position = mRenderer.getSeekPosition();
}
+ int pbState;
+ float rate = 0;
+ String errorMsg = null;
switch (newState) {
case Renderer.STATE_ENDED:
case Renderer.STATE_STOPPED:
- mPlaybackState.setState(PlaybackState.STATE_STOPPED, position, 0);
+ pbState = PlaybackState.STATE_STOPPED;
break;
case Renderer.STATE_INIT:
case Renderer.STATE_PREPARING:
- mPlaybackState.setState(PlaybackState.STATE_BUFFERING, position, 0);
+ pbState = PlaybackState.STATE_BUFFERING;
break;
case Renderer.STATE_ERROR:
- mPlaybackState.setState(PlaybackState.STATE_ERROR, position, 0);
+ pbState = PlaybackState.STATE_ERROR;
break;
case Renderer.STATE_PAUSED:
- mPlaybackState.setState(PlaybackState.STATE_PAUSED, position, 0);
+ pbState = PlaybackState.STATE_PAUSED;
break;
case Renderer.STATE_PLAYING:
- mPlaybackState.setState(PlaybackState.STATE_PLAYING, position, 1);
+ pbState = PlaybackState.STATE_PLAYING;
+ rate = 1;
break;
default:
- mPlaybackState.setState(PlaybackState.STATE_ERROR, position, 0);
- mPlaybackState.setErrorMessage("unkown state");
+ pbState = PlaybackState.STATE_ERROR;
+ errorMsg = "unknown state";
break;
}
+ PlaybackState.Builder bob = new PlaybackState.Builder(mPlaybackState);
+ bob.setState(pbState, position, rate, SystemClock.elapsedRealtime());
+ bob.setErrorMessage(errorMsg);
+ mPlaybackState = bob.build();
sendStatusUpdate(mPlaybackState.getState());
}
@@ -218,8 +226,9 @@
@Override
public void onFocusLost() {
- Log.d(TAG, "Focus lost, changing state to " + Renderer.STATE_PAUSED);
- mPlaybackState.setState(PlaybackState.STATE_PAUSED, mRenderer.getSeekPosition(), 0);
+ Log.d(TAG, "Focus lost, pausing");
+ // Don't update state here, we'll get a separate call to
+ // onStateChanged when it pauses
mRenderer.onPause();
}